authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-18 11:38:56+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-18 11:38:56+03:00
log3eb8f7be1018cef3043bfb56a0e2c3ff323e91d5
tree9d50691512e07de488c0d8d20e24df4ca07c2b32
parent0977e4140768447e57474792ff42d056a8f2e0ed
signature Commit is signed but in an unrecognized format.

stage2: astgen bool and/or


2 files changed, 90 insertions(+), 3 deletions(-)

src-self-hosted/astgen.zig+86-3
...@@ -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),
102102
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),
127131
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}
570571
572fn 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
571const CondKind = union(enum) {654const CondKind = union(enum) {
572 bool,655 bool,
573 optional: ?*zir.Inst,656 optional: ?*zir.Inst,
src-self-hosted/zir.zig+4
...@@ -1924,6 +1924,10 @@ const EmitZIR = struct {...@@ -1924,6 +1924,10 @@ const EmitZIR = struct {
1924 return self.emitUnnamedDecl(&str_inst.base);1924 return self.emitUnnamedDecl(&str_inst.base);
1925 },1925 },
1926 .Void => return self.emitPrimitive(src, .void_value),1926 .Void => return self.emitPrimitive(src, .void_value),
1927 .Bool => if (typed_value.val.toBool())
1928 return self.emitPrimitive(src, .@"true")
1929 else
1930 return self.emitPrimitive(src, .@"false"),
1927 else => |t| std.debug.panic("TODO implement emitTypedValue for {}", .{@tagName(t)}),1931 else => |t| std.debug.panic("TODO implement emitTypedValue for {}", .{@tagName(t)}),
1928 }1932 }
1929 }1933 }