stage2: comptime decl

This commit is contained in:
Vexu 2020-08-20 18:50:13 +03:00 committed by Andrew Kelley
parent d312d64c9a
commit 6a053ffcc8
3 changed files with 60 additions and 32 deletions

View File

@ -1485,6 +1485,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
const type_node = var_decl.getTrailer("type_node") orelse
break :blk null;
// Temporary arena for the zir instructions.
var type_scope_arena = std.heap.ArenaAllocator.init(self.gpa);
defer type_scope_arena.deinit();
var type_scope: Scope.GenZIR = .{
@ -1539,7 +1540,8 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
try self.coerce(&inner_block.base, some, ret.operand)
else
ret.operand;
const val = try self.resolveConstValue(&inner_block.base, coerced);
const val = coerced.value() orelse
return self.fail(&block_scope.base, inst.src, "unable to resolve comptime value", .{});
var_type = explicit_type orelse try ret.operand.ty.copy(block_scope.arena);
break :blk try val.copy(block_scope.arena);
@ -1603,7 +1605,41 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
}
return type_changed;
},
.Comptime => @panic("TODO comptime decl"),
.Comptime => {
const comptime_decl = @fieldParentPtr(ast.Node.Comptime, "base", ast_node);
decl.analysis = .in_progress;
// A comptime decl does not store any value so we can just deinit this arena after analysis is done.
var analysis_arena = std.heap.ArenaAllocator.init(self.gpa);
defer analysis_arena.deinit();
var gen_scope: Scope.GenZIR = .{
.decl = decl,
.arena = &analysis_arena.allocator,
.parent = decl.scope,
};
defer gen_scope.instructions.deinit(self.gpa);
// TODO comptime scope here
_ = try astgen.expr(self, &gen_scope.base, .none, comptime_decl.expr);
var block_scope: Scope.Block = .{
.parent = null,
.func = null,
.decl = decl,
.instructions = .{},
.arena = &analysis_arena.allocator,
};
defer block_scope.instructions.deinit(self.gpa);
_ = try zir_sema.analyzeBody(self, &block_scope.base, .{
.instructions = gen_scope.instructions.items,
});
decl.analysis = .complete;
decl.generation = self.generation;
return true;
},
.Use => @panic("TODO usingnamespace decl"),
else => unreachable,
}
@ -1794,7 +1830,16 @@ fn analyzeRootSrcFile(self: *Module, root_scope: *Scope.File) !void {
}
}
} else if (src_decl.castTag(.Comptime)) |comptime_node| {
log.err("TODO: analyze comptime decl", .{});
const name_index = self.getNextAnonNameIndex();
const name = try std.fmt.allocPrint(self.gpa, "__comptime_{}", .{name_index});
defer self.gpa.free(name);
const name_hash = root_scope.fullyQualifiedNameHash(name);
const contents_hash = std.zig.hashSrc(tree.getNodeSource(src_decl));
const new_decl = try self.createNewDecl(&root_scope.base, name, decl_i, name_hash, contents_hash);
root_scope.decls.appendAssumeCapacity(new_decl);
self.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl });
} else if (src_decl.castTag(.ContainerField)) |container_field| {
log.err("TODO: analyze container field", .{});
} else if (src_decl.castTag(.TestDecl)) |test_decl| {

View File

@ -23,11 +23,6 @@ pub fn addCases(ctx: *TestContext) !void {
case.addError("", &[_][]const u8{":1:1: error: no entry point found"});
case.addError(
\\export fn _start() noreturn {
\\}
, &[_][]const u8{":2:1: error: expected noreturn, found void"});
// Regular old hello world
case.addCompareOutput(
\\export fn _start() noreturn {

View File

@ -67,6 +67,18 @@ pub fn addCases(ctx: *TestContext) !void {
\\fn entry() void {}
, &[_][]const u8{":2:4: error: redefinition of 'entry'"});
ctx.compileError("incorrect return type", linux_x64,
\\export fn _start() noreturn {
\\}
, &[_][]const u8{":2:1: error: expected noreturn, found void"});
ctx.compileError("extern variable has no type", linux_x64,
\\comptime {
\\ _ = foo;
\\}
\\extern var foo;
, &[_][]const u8{":4:1: error: unable to infer variable type"});
//ctx.incrementalFailure("function redefinition", linux_x64,
// \\fn entry() void {}
// \\fn entry() void {}
@ -108,28 +120,4 @@ pub fn addCases(ctx: *TestContext) !void {
// \\ return 36893488147419103232;
// \\}
//, "1.zig", 2, 12, "integer value '36893488147419103232' cannot be stored in type 'c_int'");
//ctx.testCompileError(
// \\comptime {
// \\ var a: *align(4) align(4) i32 = 0;
// \\}
//, "1.zig", 2, 22, "Extra align qualifier");
//ctx.testCompileError(
// \\comptime {
// \\ var b: *const const i32 = 0;
// \\}
//, "1.zig", 2, 19, "Extra align qualifier");
//ctx.testCompileError(
// \\comptime {
// \\ var c: *volatile volatile i32 = 0;
// \\}
//, "1.zig", 2, 22, "Extra align qualifier");
//ctx.testCompileError(
// \\comptime {
// \\ var d: *allowzero allowzero i32 = 0;
// \\}
//, "1.zig", 2, 23, "Extra align qualifier");
}