authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-31 02:42:48-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-31 02:42:48-07:00
log7deb1f4f6c038eaef815d5d179633683a9574ff0
treefcfabab97a321af087a1bf03a54db3d4108a8a5a
parenta46d24af1cf2885991c67bf39a2e639891c16121

stage2: type inference for local var


4 files changed, 20 insertions(+), 7 deletions(-)

BRANCH_TODO created+2
...@@ -0,0 +1,2 @@
1 * no need for payload on inferred_alloc for the type
2 * compile error for "variable of type '{}' must be const or comptime" after resolving types
src/astgen.zig+3-3
...@@ -625,9 +625,9 @@ fn varDecl(...@@ -625,9 +625,9 @@ fn varDecl(
625 const alloc = try addZIRUnOp(mod, scope, name_src, .alloc_mut, type_inst);625 const alloc = try addZIRUnOp(mod, scope, name_src, .alloc_mut, type_inst);
626 break :a .{ .alloc = alloc, .result_loc = .{ .ptr = alloc } };626 break :a .{ .alloc = alloc, .result_loc = .{ .ptr = alloc } };
627 } else a: {627 } else a: {
628 const alloc = try addZIRNoOp(mod, scope, name_src, .alloc_inferred_mut);628 const alloc = try addZIRNoOpT(mod, scope, name_src, .alloc_inferred);
629 resolve_inferred_alloc = alloc;629 resolve_inferred_alloc = &alloc.base;
630 break :a .{ .alloc = alloc, .result_loc = .{ .inferred_ptr = alloc.castTag(.alloc_inferred_mut).? } };630 break :a .{ .alloc = &alloc.base, .result_loc = .{ .inferred_ptr = alloc } };
631 };631 };
632 const init_inst = try expr(mod, scope, var_data.result_loc, init_node);632 const init_inst = try expr(mod, scope, var_data.result_loc, init_node);
633 if (resolve_inferred_alloc) |inst| {633 if (resolve_inferred_alloc) |inst| {
src/codegen/c.zig+11-2
...@@ -275,7 +275,6 @@ pub fn generate(file: *C, module: *Module, decl: *Decl) !void {...@@ -275,7 +275,6 @@ pub fn generate(file: *C, module: *Module, decl: *Decl) !void {
275 try writer.writeAll(" {");275 try writer.writeAll(" {");
276276
277 const func: *Module.Fn = func_payload.data;277 const func: *Module.Fn = func_payload.data;
278 //func.dump(module.*);
279 const instructions = func.analysis.success.instructions;278 const instructions = func.analysis.success.instructions;
280 if (instructions.len > 0) {279 if (instructions.len > 0) {
281 try writer.writeAll("\n");280 try writer.writeAll("\n");
...@@ -297,6 +296,7 @@ pub fn generate(file: *C, module: *Module, decl: *Decl) !void {...@@ -297,6 +296,7 @@ pub fn generate(file: *C, module: *Module, decl: *Decl) !void {
297 .cmp_neq => try genBinOp(&ctx, file, inst.castTag(.cmp_neq).?, "!="),296 .cmp_neq => try genBinOp(&ctx, file, inst.castTag(.cmp_neq).?, "!="),
298 .dbg_stmt => try genDbgStmt(&ctx, inst.castTag(.dbg_stmt).?),297 .dbg_stmt => try genDbgStmt(&ctx, inst.castTag(.dbg_stmt).?),
299 .intcast => try genIntCast(&ctx, file, inst.castTag(.intcast).?),298 .intcast => try genIntCast(&ctx, file, inst.castTag(.intcast).?),
299 .load => try genLoad(&ctx, file, inst.castTag(.load).?),
300 .ret => try genRet(&ctx, file, inst.castTag(.ret).?),300 .ret => try genRet(&ctx, file, inst.castTag(.ret).?),
301 .retvoid => try genRetVoid(file),301 .retvoid => try genRetVoid(file),
302 .store => try genStore(&ctx, file, inst.castTag(.store).?),302 .store => try genStore(&ctx, file, inst.castTag(.store).?),
...@@ -431,6 +431,16 @@ fn genRetVoid(file: *C) !?[]u8 {...@@ -431,6 +431,16 @@ fn genRetVoid(file: *C) !?[]u8 {
431 return null;431 return null;
432}432}
433433
434fn genLoad(ctx: *Context, file: *C, inst: *Inst.UnOp) !?[]u8 {
435 const operand = try ctx.resolveInst(inst.operand);
436 const writer = file.main.writer();
437 try indent(file);
438 const local_name = try ctx.name();
439 try renderTypeAndName(ctx, writer, inst.base.ty, local_name, .Const);
440 try writer.print(" = *{s};\n", .{operand});
441 return local_name;
442}
443
434fn genRet(ctx: *Context, file: *C, inst: *Inst.UnOp) !?[]u8 {444fn genRet(ctx: *Context, file: *C, inst: *Inst.UnOp) !?[]u8 {
435 try indent(file);445 try indent(file);
436 const writer = file.main.writer();446 const writer = file.main.writer();
...@@ -442,7 +452,6 @@ fn genIntCast(ctx: *Context, file: *C, inst: *Inst.UnOp) !?[]u8 {...@@ -442,7 +452,6 @@ fn genIntCast(ctx: *Context, file: *C, inst: *Inst.UnOp) !?[]u8 {
442 if (inst.base.isUnused())452 if (inst.base.isUnused())
443 return null;453 return null;
444 try indent(file);454 try indent(file);
445 const op = inst.operand;
446 const writer = file.main.writer();455 const writer = file.main.writer();
447 const name = try ctx.name();456 const name = try ctx.name();
448 const from = try ctx.resolveInst(inst.operand);457 const from = try ctx.resolveInst(inst.operand);
test/stage2/cbe.zig+4-2
...@@ -52,7 +52,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -52,7 +52,7 @@ pub fn addCases(ctx: *TestContext) !void {
52 }52 }
5353
54 {54 {
55 var case = ctx.exeFromCompiledC("inferred local const", .{});55 var case = ctx.exeFromCompiledC("inferred local const and var", .{});
5656
57 case.addCompareOutput(57 case.addCompareOutput(
58 \\fn add(a: i32, b: i32) i32 {58 \\fn add(a: i32, b: i32) i32 {
...@@ -61,7 +61,9 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -61,7 +61,9 @@ pub fn addCases(ctx: *TestContext) !void {
61 \\61 \\
62 \\export fn main() c_int {62 \\export fn main() c_int {
63 \\ const x = add(1, 2);63 \\ const x = add(1, 2);
64 \\ return x - 3;64 \\ var y = add(3, 0);
65 \\ y -= x;
66 \\ return y;
65 \\}67 \\}
66 , "");68 , "");
67 }69 }