Commit 6ece36a051

Noam Preil <pleasantatk@gmail.com>
2020-07-07 23:51:59
Working translation of empty function
1 parent 2f28ecf
Changed files (3)
src-self-hosted
test
stage2
src-self-hosted/cgen.zig
@@ -1,11 +1,50 @@
 const link = @import("link.zig");
 const Module = @import("Module.zig");
+const std = @import("std");
+const Value = @import("value.zig").Value;
 
 const C = link.File.C;
 const Decl = Module.Decl;
 const CStandard = Module.CStandard;
+const mem = std.mem;
+
+/// Maps a name from Zig source to C. This will always give the same output for
+/// any given input.
+fn map(name: []const u8) ![]const u8 {
+    return name;
+}
 
 pub fn generate(file: *C, decl: *Decl, standard: CStandard) !void {
     const writer = file.file.?.writer();
-    try writer.print("Generating decl '{}', targeting {}", .{ decl.name, @tagName(standard) });
+    const tv = decl.typed_value.most_recent.typed_value;
+    switch (tv.ty.zigTypeTag()) {
+        .Fn => {
+            const return_type = tv.ty.fnReturnType();
+            switch (return_type.zigTypeTag()) {
+                .NoReturn => try writer.writeAll("_Noreturn void "),
+                else => return error.Unimplemented,
+            }
+
+            const name = try map(mem.spanZ(decl.name));
+            try writer.print("{} (", .{name});
+            if (tv.ty.fnParamLen() == 0) {
+                try writer.writeAll("void){");
+            } else {
+                return error.Unimplemented;
+            }
+
+            const func: *Module.Fn = tv.val.cast(Value.Payload.Function).?.func;
+            const instructions = func.analysis.success.instructions;
+            if (instructions.len > 0) {
+                try writer.writeAll("\n\t");
+                for (instructions) |inst| {
+                    std.debug.warn("\nTranslating {}\n", .{inst.*});
+                }
+                try writer.writeAll("\n");
+            }
+
+            try writer.writeAll("}\n");
+        },
+        else => return error.Unimplemented,
+    }
 }
src-self-hosted/test.zig
@@ -482,6 +482,7 @@ pub const TestContext = struct {
                         label = @tagName(cstd);
                         var c: *link.File.C = module.bin_file.cast(link.File.C).?;
                         c.file.?.close();
+                        c.file = null;
                         var file = try tmp.dir.openFile(bin_name, .{ .read = true });
                         defer file.close();
                         var out = file.reader().readAllAlloc(allocator, 1024 * 1024) catch @panic("Unable to read C output!");
test/stage2/cbe.zig
@@ -11,8 +11,11 @@ const linux_x64 = std.zig.CrossTarget{
 pub fn addCases(ctx: *TestContext) !void {
     // These tests should work on every platform
     ctx.c11("empty start function", linux_x64,
-        \\export fn start() void {}
+        \\export fn _start() noreturn {}
     ,
-        \\void start(void) {}
+    // A newline is always generated after every function; this ensures, among
+    // other things, that there is always a newline at the end of the file
+    \\_Noreturn void _start(void) {}
+        \\
     );
 }