diff --git a/src-self-hosted/Module.zig b/src-self-hosted/Module.zig index 0c80803fc7..f4d65ab7c0 100644 --- a/src-self-hosted/Module.zig +++ b/src-self-hosted/Module.zig @@ -1297,10 +1297,28 @@ fn astGenExpr(self: *Module, scope: *Scope, ast_node: *ast.Node) InnerError!*zir .Unreachable => return self.astGenUnreachable(scope, @fieldParentPtr(ast.Node.Unreachable, "base", ast_node)), .ControlFlowExpression => return self.astGenControlFlowExpression(scope, @fieldParentPtr(ast.Node.ControlFlowExpression, "base", ast_node)), .If => return self.astGenIf(scope, @fieldParentPtr(ast.Node.If, "base", ast_node)), + .InfixOp => return self.astGenInfixOp(scope, @fieldParentPtr(ast.Node.InfixOp, "base", ast_node)), else => return self.failNode(scope, ast_node, "TODO implement astGenExpr for {}", .{@tagName(ast_node.id)}), } } +fn astGenInfixOp(self: *Module, scope: *Scope, infix_node: *ast.Node.InfixOp) InnerError!*zir.Inst { + switch (infix_node.op) { + .Add => { + const lhs = try self.astGenExpr(scope, infix_node.lhs); + const rhs = try self.astGenExpr(scope, infix_node.rhs); + + const tree = scope.tree(); + const src = tree.token_locs[infix_node.op_token].start; + + return self.addZIRInst(scope, src, zir.Inst.Add, .{ .lhs = lhs, .rhs = rhs }, .{}); + }, + else => |op| { + return self.failNode(scope, &infix_node.base, "TODO implement infix operator {}", .{op}); + }, + } +} + fn astGenIf(self: *Module, scope: *Scope, if_node: *ast.Node.If) InnerError!*zir.Inst { if (if_node.payload) |payload| { return self.failNode(scope, payload, "TODO implement astGenIf for optionals", .{}); @@ -1496,7 +1514,12 @@ fn astGenBuiltinCall(self: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) const arg_count: ?usize = if (positionals.fields[0].field_type == []*zir.Inst) null else positionals.fields.len; if (arg_count) |some| { if (call.params_len != some) { - return self.failTok(scope, call.builtin_token, "expected {} parameter, found {}", .{ some, call.params_len }); + return self.failTok( + scope, + call.builtin_token, + "expected {} parameter{}, found {}", + .{ some, if (some == 1) "" else "s", call.params_len }, + ); } const params = call.params(); inline for (positionals.fields) |p, i| { @@ -2902,7 +2925,9 @@ fn analyzeInstAdd(self: *Module, scope: *Scope, inst: *zir.Inst.Add) InnerError! const lhs = try self.resolveInst(scope, inst.positionals.lhs); const rhs = try self.resolveInst(scope, inst.positionals.rhs); - if (lhs.ty.zigTypeTag() == .Int and rhs.ty.zigTypeTag() == .Int) { + if ((lhs.ty.zigTypeTag() == .Int or lhs.ty.zigTypeTag() == .ComptimeInt) and + (rhs.ty.zigTypeTag() == .Int or rhs.ty.zigTypeTag() == .ComptimeInt)) + { if (!lhs.ty.eql(rhs.ty)) { return self.fail(scope, inst.base.src, "TODO implement peer type resolution", .{}); } @@ -2946,8 +2971,7 @@ fn analyzeInstAdd(self: *Module, scope: *Scope, inst: *zir.Inst.Add) InnerError! .rhs = rhs, }); } - - return self.fail(scope, inst.base.src, "TODO implement more analyze add", .{}); + return self.fail(scope, inst.base.src, "TODO analyze add for {} + {}", .{ lhs.ty.zigTypeTag(), rhs.ty.zigTypeTag() }); } fn analyzeInstDeref(self: *Module, scope: *Scope, deref: *zir.Inst.Deref) InnerError!*Inst { diff --git a/src-self-hosted/zir.zig b/src-self-hosted/zir.zig index 7dceaaea1b..95548657a9 100644 --- a/src-self-hosted/zir.zig +++ b/src-self-hosted/zir.zig @@ -290,6 +290,7 @@ pub const Inst = struct { pub const As = struct { pub const base_tag = Tag.as; + pub const builtin_name = "@as"; base: Inst, positionals: struct { diff --git a/test/stage2/compare_output.zig b/test/stage2/compare_output.zig index d49f16876e..1f2853707a 100644 --- a/test/stage2/compare_output.zig +++ b/test/stage2/compare_output.zig @@ -118,4 +118,29 @@ pub fn addCases(ctx: *TestContext) !void { \\ ); } + + { + var case = ctx.exe("adding numbers", linux_x64); + case.addCompareOutput( + \\export fn _start() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (1), + \\ [arg1] "{rdi}" (1), + \\ [arg2] "{rsi}" (@ptrToInt("Hello, World!\n")), + \\ [arg3] "{rdx}" (10 + 4) + \\ : "rcx", "r11", "memory" + \\ ); + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (@as(usize, 230) + @as(usize, 1)), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "Hello, World!\n", + ); + } }