authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-20 18:50:13+03:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-20 16:42:48-07:00
log6a053ffcc85ce3f2b598be08e5d0587c930b4358
tree6035175440d5fe20f736cb92654d3ebb48d073ce
parentd312d64c9aa058293d69b2bf97c51f4caa7a2d9d

stage2: comptime decl


3 files changed, 60 insertions(+), 32 deletions(-)

src-self-hosted/Module.zig+48-3
...@@ -1485,6 +1485,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {...@@ -1485,6 +1485,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
1485 const type_node = var_decl.getTrailer("type_node") orelse1485 const type_node = var_decl.getTrailer("type_node") orelse
1486 break :blk null;1486 break :blk null;
14871487
1488 // Temporary arena for the zir instructions.
1488 var type_scope_arena = std.heap.ArenaAllocator.init(self.gpa);1489 var type_scope_arena = std.heap.ArenaAllocator.init(self.gpa);
1489 defer type_scope_arena.deinit();1490 defer type_scope_arena.deinit();
1490 var type_scope: Scope.GenZIR = .{1491 var type_scope: Scope.GenZIR = .{
...@@ -1539,7 +1540,8 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {...@@ -1539,7 +1540,8 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
1539 try self.coerce(&inner_block.base, some, ret.operand)1540 try self.coerce(&inner_block.base, some, ret.operand)
1540 else1541 else
1541 ret.operand;1542 ret.operand;
1542 const val = try self.resolveConstValue(&inner_block.base, coerced);1543 const val = coerced.value() orelse
1544 return self.fail(&block_scope.base, inst.src, "unable to resolve comptime value", .{});
15431545
1544 var_type = explicit_type orelse try ret.operand.ty.copy(block_scope.arena);1546 var_type = explicit_type orelse try ret.operand.ty.copy(block_scope.arena);
1545 break :blk try val.copy(block_scope.arena);1547 break :blk try val.copy(block_scope.arena);
...@@ -1603,7 +1605,41 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {...@@ -1603,7 +1605,41 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
1603 }1605 }
1604 return type_changed;1606 return type_changed;
1605 },1607 },
1606 .Comptime => @panic("TODO comptime decl"),1608 .Comptime => {
1609 const comptime_decl = @fieldParentPtr(ast.Node.Comptime, "base", ast_node);
1610
1611 decl.analysis = .in_progress;
1612
1613 // A comptime decl does not store any value so we can just deinit this arena after analysis is done.
1614 var analysis_arena = std.heap.ArenaAllocator.init(self.gpa);
1615 defer analysis_arena.deinit();
1616 var gen_scope: Scope.GenZIR = .{
1617 .decl = decl,
1618 .arena = &analysis_arena.allocator,
1619 .parent = decl.scope,
1620 };
1621 defer gen_scope.instructions.deinit(self.gpa);
1622
1623 // TODO comptime scope here
1624 _ = try astgen.expr(self, &gen_scope.base, .none, comptime_decl.expr);
1625
1626 var block_scope: Scope.Block = .{
1627 .parent = null,
1628 .func = null,
1629 .decl = decl,
1630 .instructions = .{},
1631 .arena = &analysis_arena.allocator,
1632 };
1633 defer block_scope.instructions.deinit(self.gpa);
1634
1635 _ = try zir_sema.analyzeBody(self, &block_scope.base, .{
1636 .instructions = gen_scope.instructions.items,
1637 });
1638
1639 decl.analysis = .complete;
1640 decl.generation = self.generation;
1641 return true;
1642 },
1607 .Use => @panic("TODO usingnamespace decl"),1643 .Use => @panic("TODO usingnamespace decl"),
1608 else => unreachable,1644 else => unreachable,
1609 }1645 }
...@@ -1794,7 +1830,16 @@ fn analyzeRootSrcFile(self: *Module, root_scope: *Scope.File) !void {...@@ -1794,7 +1830,16 @@ fn analyzeRootSrcFile(self: *Module, root_scope: *Scope.File) !void {
1794 }1830 }
1795 }1831 }
1796 } else if (src_decl.castTag(.Comptime)) |comptime_node| {1832 } else if (src_decl.castTag(.Comptime)) |comptime_node| {
1797 log.err("TODO: analyze comptime decl", .{});1833 const name_index = self.getNextAnonNameIndex();
1834 const name = try std.fmt.allocPrint(self.gpa, "__comptime_{}", .{name_index});
1835 defer self.gpa.free(name);
1836
1837 const name_hash = root_scope.fullyQualifiedNameHash(name);
1838 const contents_hash = std.zig.hashSrc(tree.getNodeSource(src_decl));
1839
1840 const new_decl = try self.createNewDecl(&root_scope.base, name, decl_i, name_hash, contents_hash);
1841 root_scope.decls.appendAssumeCapacity(new_decl);
1842 self.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl });
1798 } else if (src_decl.castTag(.ContainerField)) |container_field| {1843 } else if (src_decl.castTag(.ContainerField)) |container_field| {
1799 log.err("TODO: analyze container field", .{});1844 log.err("TODO: analyze container field", .{});
1800 } else if (src_decl.castTag(.TestDecl)) |test_decl| {1845 } else if (src_decl.castTag(.TestDecl)) |test_decl| {
test/stage2/compare_output.zig-5
...@@ -23,11 +23,6 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -23,11 +23,6 @@ pub fn addCases(ctx: *TestContext) !void {
2323
24 case.addError("", &[_][]const u8{":1:1: error: no entry point found"});24 case.addError("", &[_][]const u8{":1:1: error: no entry point found"});
2525
26 case.addError(
27 \\export fn _start() noreturn {
28 \\}
29 , &[_][]const u8{":2:1: error: expected noreturn, found void"});
30
31 // Regular old hello world26 // Regular old hello world
32 case.addCompareOutput(27 case.addCompareOutput(
33 \\export fn _start() noreturn {28 \\export fn _start() noreturn {
test/stage2/compile_errors.zig+12-24
...@@ -67,6 +67,18 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -67,6 +67,18 @@ pub fn addCases(ctx: *TestContext) !void {
67 \\fn entry() void {}67 \\fn entry() void {}
68 , &[_][]const u8{":2:4: error: redefinition of 'entry'"});68 , &[_][]const u8{":2:4: error: redefinition of 'entry'"});
6969
70 ctx.compileError("incorrect return type", linux_x64,
71 \\export fn _start() noreturn {
72 \\}
73 , &[_][]const u8{":2:1: error: expected noreturn, found void"});
74
75 ctx.compileError("extern variable has no type", linux_x64,
76 \\comptime {
77 \\ _ = foo;
78 \\}
79 \\extern var foo;
80 , &[_][]const u8{":4:1: error: unable to infer variable type"});
81
70 //ctx.incrementalFailure("function redefinition", linux_x64,82 //ctx.incrementalFailure("function redefinition", linux_x64,
71 // \\fn entry() void {}83 // \\fn entry() void {}
72 // \\fn entry() void {}84 // \\fn entry() void {}
...@@ -108,28 +120,4 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -108,28 +120,4 @@ pub fn addCases(ctx: *TestContext) !void {
108 // \\ return 36893488147419103232;120 // \\ return 36893488147419103232;
109 // \\}121 // \\}
110 //, "1.zig", 2, 12, "integer value '36893488147419103232' cannot be stored in type 'c_int'");122 //, "1.zig", 2, 12, "integer value '36893488147419103232' cannot be stored in type 'c_int'");
111
112 //ctx.testCompileError(
113 // \\comptime {
114 // \\ var a: *align(4) align(4) i32 = 0;
115 // \\}
116 //, "1.zig", 2, 22, "Extra align qualifier");
117
118 //ctx.testCompileError(
119 // \\comptime {
120 // \\ var b: *const const i32 = 0;
121 // \\}
122 //, "1.zig", 2, 19, "Extra align qualifier");
123
124 //ctx.testCompileError(
125 // \\comptime {
126 // \\ var c: *volatile volatile i32 = 0;
127 // \\}
128 //, "1.zig", 2, 22, "Extra align qualifier");
129
130 //ctx.testCompileError(
131 // \\comptime {
132 // \\ var d: *allowzero allowzero i32 = 0;
133 // \\}
134 //, "1.zig", 2, 23, "Extra align qualifier");
135}123}