| ... | @@ -100,6 +100,9 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr | ... | @@ -100,6 +100,9 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr |
| 100 | .ArrayCat => return simpleBinOp(mod, scope, rl, node.castTag(.ArrayCat).?, .array_cat), | 100 | .ArrayCat => return simpleBinOp(mod, scope, rl, node.castTag(.ArrayCat).?, .array_cat), |
| 101 | .ArrayMult => return simpleBinOp(mod, scope, rl, node.castTag(.ArrayMult).?, .array_mul), | 101 | .ArrayMult => return simpleBinOp(mod, scope, rl, node.castTag(.ArrayMult).?, .array_mul), |
| 102 | | 102 | |
| | 103 | .BoolAnd => return boolBinOp(mod, scope, rl, node.castTag(.BoolAnd).?), |
| | 104 | .BoolOr => return boolBinOp(mod, scope, rl, node.castTag(.BoolOr).?), |
| | 105 | |
| 103 | .Identifier => return try identifier(mod, scope, rl, node.castTag(.Identifier).?), | 106 | .Identifier => return try identifier(mod, scope, rl, node.castTag(.Identifier).?), |
| 104 | .Asm => return rlWrap(mod, scope, rl, try assembly(mod, scope, node.castTag(.Asm).?)), | 107 | .Asm => return rlWrap(mod, scope, rl, try assembly(mod, scope, node.castTag(.Asm).?)), |
| 105 | .StringLiteral => return rlWrap(mod, scope, rl, try stringLiteral(mod, scope, node.castTag(.StringLiteral).?)), | 108 | .StringLiteral => return rlWrap(mod, scope, rl, try stringLiteral(mod, scope, node.castTag(.StringLiteral).?)), |
| ... | @@ -124,11 +127,10 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr | ... | @@ -124,11 +127,10 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr |
| 124 | .LabeledBlock => return labeledBlockExpr(mod, scope, rl, node.castTag(.LabeledBlock).?), | 127 | .LabeledBlock => return labeledBlockExpr(mod, scope, rl, node.castTag(.LabeledBlock).?), |
| 125 | .Break => return rlWrap(mod, scope, rl, try breakExpr(mod, scope, node.castTag(.Break).?)), | 128 | .Break => return rlWrap(mod, scope, rl, try breakExpr(mod, scope, node.castTag(.Break).?)), |
| 126 | .PtrType => return rlWrap(mod, scope, rl, try ptrType(mod, scope, node.castTag(.PtrType).?)), | 129 | .PtrType => return rlWrap(mod, scope, rl, try ptrType(mod, scope, node.castTag(.PtrType).?)), |
| | 130 | .GroupedExpression => return expr(mod, scope, rl, node.castTag(.GroupedExpression).?.expr), |
| 127 | | 131 | |
| 128 | .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}), | 132 | .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}), |
| 129 | .Catch => return mod.failNode(scope, node, "TODO implement astgen.expr for .Catch", .{}), | 133 | .Catch => return mod.failNode(scope, node, "TODO implement astgen.expr for .Catch", .{}), |
| 130 | .BoolAnd => return mod.failNode(scope, node, "TODO implement astgen.expr for .BoolAnd", .{}), | | |
| 131 | .BoolOr => return mod.failNode(scope, node, "TODO implement astgen.expr for .BoolOr", .{}), | | |
| 132 | .ErrorUnion => return mod.failNode(scope, node, "TODO implement astgen.expr for .ErrorUnion", .{}), | 134 | .ErrorUnion => return mod.failNode(scope, node, "TODO implement astgen.expr for .ErrorUnion", .{}), |
| 133 | .MergeErrorSets => return mod.failNode(scope, node, "TODO implement astgen.expr for .MergeErrorSets", .{}), | 135 | .MergeErrorSets => return mod.failNode(scope, node, "TODO implement astgen.expr for .MergeErrorSets", .{}), |
| 134 | .Range => return mod.failNode(scope, node, "TODO implement astgen.expr for .Range", .{}), | 136 | .Range => return mod.failNode(scope, node, "TODO implement astgen.expr for .Range", .{}), |
| ... | @@ -159,7 +161,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr | ... | @@ -159,7 +161,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr |
| 159 | .EnumLiteral => return mod.failNode(scope, node, "TODO implement astgen.expr for .EnumLiteral", .{}), | 161 | .EnumLiteral => return mod.failNode(scope, node, "TODO implement astgen.expr for .EnumLiteral", .{}), |
| 160 | .MultilineStringLiteral => return mod.failNode(scope, node, "TODO implement astgen.expr for .MultilineStringLiteral", .{}), | 162 | .MultilineStringLiteral => return mod.failNode(scope, node, "TODO implement astgen.expr for .MultilineStringLiteral", .{}), |
| 161 | .CharLiteral => return mod.failNode(scope, node, "TODO implement astgen.expr for .CharLiteral", .{}), | 163 | .CharLiteral => return mod.failNode(scope, node, "TODO implement astgen.expr for .CharLiteral", .{}), |
| 162 | .GroupedExpression => return mod.failNode(scope, node, "TODO implement astgen.expr for .GroupedExpression", .{}), | | |
| 163 | .ErrorSetDecl => return mod.failNode(scope, node, "TODO implement astgen.expr for .ErrorSetDecl", .{}), | 164 | .ErrorSetDecl => return mod.failNode(scope, node, "TODO implement astgen.expr for .ErrorSetDecl", .{}), |
| 164 | .ContainerDecl => return mod.failNode(scope, node, "TODO implement astgen.expr for .ContainerDecl", .{}), | 165 | .ContainerDecl => return mod.failNode(scope, node, "TODO implement astgen.expr for .ContainerDecl", .{}), |
| 165 | .Comptime => return mod.failNode(scope, node, "TODO implement astgen.expr for .Comptime", .{}), | 166 | .Comptime => return mod.failNode(scope, node, "TODO implement astgen.expr for .Comptime", .{}), |
| ... | @@ -568,6 +569,88 @@ fn simpleBinOp( | ... | @@ -568,6 +569,88 @@ fn simpleBinOp( |
| 568 | return rlWrap(mod, scope, rl, result); | 569 | return rlWrap(mod, scope, rl, result); |
| 569 | } | 570 | } |
| 570 | | 571 | |
| | 572 | fn boolBinOp( |
| | 573 | mod: *Module, |
| | 574 | scope: *Scope, |
| | 575 | rl: ResultLoc, |
| | 576 | infix_node: *ast.Node.SimpleInfixOp, |
| | 577 | ) InnerError!*zir.Inst { |
| | 578 | const tree = scope.tree(); |
| | 579 | const src = tree.token_locs[infix_node.op_token].start; |
| | 580 | const bool_type = try addZIRInstConst(mod, scope, src, .{ |
| | 581 | .ty = Type.initTag(.type), |
| | 582 | .val = Value.initTag(.bool_type), |
| | 583 | }); |
| | 584 | |
| | 585 | var block_scope: Scope.GenZIR = .{ |
| | 586 | .parent = scope, |
| | 587 | .decl = scope.decl().?, |
| | 588 | .arena = scope.arena(), |
| | 589 | .instructions = .{}, |
| | 590 | }; |
| | 591 | defer block_scope.instructions.deinit(mod.gpa); |
| | 592 | |
| | 593 | const lhs = try expr(mod, scope, .{ .ty = bool_type }, infix_node.lhs); |
| | 594 | const condbr = try addZIRInstSpecial(mod, &block_scope.base, src, zir.Inst.CondBr, .{ |
| | 595 | .condition = lhs, |
| | 596 | .then_body = undefined, // populated below |
| | 597 | .else_body = undefined, // populated below |
| | 598 | }, .{}); |
| | 599 | |
| | 600 | const block = try addZIRInstBlock(mod, scope, src, .{ |
| | 601 | .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items), |
| | 602 | }); |
| | 603 | |
| | 604 | var rhs_scope: Scope.GenZIR = .{ |
| | 605 | .parent = scope, |
| | 606 | .decl = block_scope.decl, |
| | 607 | .arena = block_scope.arena, |
| | 608 | .instructions = .{}, |
| | 609 | }; |
| | 610 | defer rhs_scope.instructions.deinit(mod.gpa); |
| | 611 | |
| | 612 | const rhs = try expr(mod, &rhs_scope.base, .{ .ty = bool_type }, infix_node.rhs); |
| | 613 | _ = try addZIRInst(mod, &rhs_scope.base, src, zir.Inst.Break, .{ |
| | 614 | .block = block, |
| | 615 | .operand = rhs, |
| | 616 | }, .{}); |
| | 617 | |
| | 618 | var const_scope: Scope.GenZIR = .{ |
| | 619 | .parent = scope, |
| | 620 | .decl = block_scope.decl, |
| | 621 | .arena = block_scope.arena, |
| | 622 | .instructions = .{}, |
| | 623 | }; |
| | 624 | defer const_scope.instructions.deinit(mod.gpa); |
| | 625 | |
| | 626 | const is_bool_and = infix_node.base.tag == .BoolAnd; |
| | 627 | _ = try addZIRInst(mod, &const_scope.base, src, zir.Inst.Break, .{ |
| | 628 | .block = block, |
| | 629 | .operand = try addZIRInstConst(mod, &const_scope.base, src, .{ |
| | 630 | .ty = Type.initTag(.bool), |
| | 631 | .val = if (is_bool_and) Value.initTag(.bool_false) else Value.initTag(.bool_true), |
| | 632 | }), |
| | 633 | }, .{}); |
| | 634 | |
| | 635 | if (is_bool_and) { |
| | 636 | // if lhs // AND |
| | 637 | // break rhs |
| | 638 | // else |
| | 639 | // break false |
| | 640 | condbr.positionals.then_body = .{ .instructions = try rhs_scope.arena.dupe(*zir.Inst, rhs_scope.instructions.items) }; |
| | 641 | condbr.positionals.else_body = .{ .instructions = try const_scope.arena.dupe(*zir.Inst, const_scope.instructions.items) }; |
| | 642 | } else { |
| | 643 | // if lhs // OR |
| | 644 | // break true |
| | 645 | // else |
| | 646 | // break rhs |
| | 647 | condbr.positionals.then_body = .{ .instructions = try const_scope.arena.dupe(*zir.Inst, const_scope.instructions.items) }; |
| | 648 | condbr.positionals.else_body = .{ .instructions = try rhs_scope.arena.dupe(*zir.Inst, rhs_scope.instructions.items) }; |
| | 649 | } |
| | 650 | |
| | 651 | return rlWrap(mod, scope, rl, &block.base); |
| | 652 | } |
| | 653 | |
| 571 | const CondKind = union(enum) { | 654 | const CondKind = union(enum) { |
| 572 | bool, | 655 | bool, |
| 573 | optional: ?*zir.Inst, | 656 | optional: ?*zir.Inst, |