authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2021-03-22 00:51:25+01:00
committergravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2021-03-22 00:51:25+01:00
log72bcdb639f24ae08022935453ea2aec95a2113ca
tree4c329fca390853f7f017ee74eed2a98de7ca1faf
parent4cfd5f6a300a97778ec515319656c6f1c0ca6ec5
signature Commit is signed but in an unrecognized format.

astgen: implement bool_and/bool_or


2 files changed, 87 insertions(+), 63 deletions(-)

src/Module.zig+46-6
...@@ -1045,10 +1045,10 @@ pub const Scope = struct {...@@ -1045,10 +1045,10 @@ pub const Scope = struct {
1045 try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.items.len +1045 try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.items.len +
1046 @typeInfo(zir.Inst.FnTypeCc).Struct.fields.len + args.param_types.len);1046 @typeInfo(zir.Inst.FnTypeCc).Struct.fields.len + args.param_types.len);
10471047
1048 const payload_index = gz.zir_code.addExtra(zir.Inst.FnTypeCc{1048 const payload_index = gz.zir_code.addExtraAssumeCapacity(zir.Inst.FnTypeCc{
1049 .cc = args.cc,1049 .cc = args.cc,
1050 .param_types_len = @intCast(u32, args.param_types.len),1050 .param_types_len = @intCast(u32, args.param_types.len),
1051 }) catch unreachable; // Capacity is ensured above.1051 });
1052 gz.zir_code.extra.appendSliceAssumeCapacity(args.param_types);1052 gz.zir_code.extra.appendSliceAssumeCapacity(args.param_types);
10531053
1054 const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len);1054 const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len);
...@@ -1076,9 +1076,9 @@ pub const Scope = struct {...@@ -1076,9 +1076,9 @@ pub const Scope = struct {
1076 try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.items.len +1076 try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.items.len +
1077 @typeInfo(zir.Inst.FnType).Struct.fields.len + param_types.len);1077 @typeInfo(zir.Inst.FnType).Struct.fields.len + param_types.len);
10781078
1079 const payload_index = gz.zir_code.addExtra(zir.Inst.FnType{1079 const payload_index = gz.zir_code.addExtraAssumeCapacity(zir.Inst.FnType{
1080 .param_types_len = @intCast(u32, param_types.len),1080 .param_types_len = @intCast(u32, param_types.len),
1081 }) catch unreachable; // Capacity is ensured above.1081 });
1082 gz.zir_code.extra.appendSliceAssumeCapacity(param_types);1082 gz.zir_code.extra.appendSliceAssumeCapacity(param_types);
10831083
1084 const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len);1084 const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len);
...@@ -1093,6 +1093,41 @@ pub const Scope = struct {...@@ -1093,6 +1093,41 @@ pub const Scope = struct {
1093 return new_index + gz.zir_code.ref_start_index;1093 return new_index + gz.zir_code.ref_start_index;
1094 }1094 }
10951095
1096 pub fn addCondBr(
1097 gz: *GenZir,
1098 condition: zir.Inst.Ref,
1099 then_body: []const zir.Inst.Ref,
1100 else_body: []const zir.Inst.Ref,
1101 /// Absolute node index. This function does the conversion to offset from Decl.
1102 abs_node_index: ast.Node.Index,
1103 ) !zir.Inst.Ref {
1104 const gpa = gz.zir_code.gpa;
1105 try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1);
1106 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);
1107 try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.items.len +
1108 @typeInfo(zir.Inst.CondBr).Struct.fields.len + then_body.len + else_body.len);
1109
1110 const payload_index = gz.zir_code.addExtraAssumeCapacity(zir.Inst.CondBr{
1111 .condition = condition,
1112 .then_body_len = @intCast(u32, then_body.len),
1113 .else_body_len = @intCast(u32, else_body.len),
1114 });
1115 gz.zir_code.extra.appendSliceAssumeCapacity(then_body);
1116 gz.zir_code.extra.appendSliceAssumeCapacity(else_body);
1117
1118 const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len);
1119 gz.zir_code.instructions.appendAssumeCapacity(.{
1120 .tag = .condbr,
1121 .data = .{ .pl_node = .{
1122 .src_node = gz.zir_code.decl.nodeIndexToRelative(abs_node_index),
1123 .payload_index = payload_index,
1124 } },
1125 });
1126 gz.instructions.appendAssumeCapacity(new_index);
1127
1128 return new_index + gz.zir_code.ref_start_index;
1129 }
1130
1096 pub fn addCall(1131 pub fn addCall(
1097 gz: *GenZir,1132 gz: *GenZir,
1098 tag: zir.Inst.Tag,1133 tag: zir.Inst.Tag,
...@@ -1109,10 +1144,10 @@ pub const Scope = struct {...@@ -1109,10 +1144,10 @@ pub const Scope = struct {
1109 try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.items.len +1144 try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.items.len +
1110 @typeInfo(zir.Inst.Call).Struct.fields.len + args.len);1145 @typeInfo(zir.Inst.Call).Struct.fields.len + args.len);
11111146
1112 const payload_index = gz.zir_code.addExtra(zir.Inst.Call{1147 const payload_index = gz.zir_code.addExtraAssumeCapacity(zir.Inst.Call{
1113 .callee = callee,1148 .callee = callee,
1114 .args_len = @intCast(u32, args.len),1149 .args_len = @intCast(u32, args.len),
1115 }) catch unreachable; // Capacity is ensured above.1150 });
1116 gz.zir_code.extra.appendSliceAssumeCapacity(args);1151 gz.zir_code.extra.appendSliceAssumeCapacity(args);
11171152
1118 const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len);1153 const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len);
...@@ -1356,6 +1391,11 @@ pub const WipZirCode = struct {...@@ -1356,6 +1391,11 @@ pub const WipZirCode = struct {
1356 pub fn addExtra(wzc: *WipZirCode, extra: anytype) Allocator.Error!u32 {1391 pub fn addExtra(wzc: *WipZirCode, extra: anytype) Allocator.Error!u32 {
1357 const fields = std.meta.fields(@TypeOf(extra));1392 const fields = std.meta.fields(@TypeOf(extra));
1358 try wzc.extra.ensureCapacity(wzc.gpa, wzc.extra.items.len + fields.len);1393 try wzc.extra.ensureCapacity(wzc.gpa, wzc.extra.items.len + fields.len);
1394 return addExtraAssumeCapacity(wzc, extra);
1395 }
1396
1397 pub fn addExtraAssumeCapacity(wzc: *WipZirCode, extra: anytype) u32 {
1398 const fields = std.meta.fields(@TypeOf(extra));
1359 const result = @intCast(u32, wzc.extra.items.len);1399 const result = @intCast(u32, wzc.extra.items.len);
1360 inline for (fields) |field| {1400 inline for (fields) |field| {
1361 comptime assert(field.field_type == u32);1401 comptime assert(field.field_type == u32);
src/astgen.zig+41-57
...@@ -370,8 +370,8 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In...@@ -370,8 +370,8 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
370 .array_cat => return simpleBinOp(mod, scope, rl, node, .array_cat),370 .array_cat => return simpleBinOp(mod, scope, rl, node, .array_cat),
371 .array_mult => return simpleBinOp(mod, scope, rl, node, .array_mul),371 .array_mult => return simpleBinOp(mod, scope, rl, node, .array_mul),
372372
373 .bool_and => return boolBinOp(mod, scope, rl, node, true),373 .bool_and => return boolBinOp(mod, scope, rl, node, .bool_and),
374 .bool_or => return boolBinOp(mod, scope, rl, node, false),374 .bool_or => return boolBinOp(mod, scope, rl, node, .bool_or),
375375
376 .bool_not => return boolNot(mod, scope, rl, node),376 .bool_not => return boolNot(mod, scope, rl, node),
377 .bit_not => return bitNot(mod, scope, rl, node),377 .bit_not => return bitNot(mod, scope, rl, node),
...@@ -1805,87 +1805,71 @@ fn boolBinOp(...@@ -1805,87 +1805,71 @@ fn boolBinOp(
1805 scope: *Scope,1805 scope: *Scope,
1806 rl: ResultLoc,1806 rl: ResultLoc,
1807 infix_node: ast.Node.Index,1807 infix_node: ast.Node.Index,
1808 is_bool_and: bool,1808 kind: enum { bool_and, bool_or },
1809) InnerError!zir.Inst.Ref {1809) InnerError!zir.Inst.Ref {
1810 if (true) @panic("TODO update for zir-memory-layout");
1811 const tree = scope.tree();1810 const tree = scope.tree();
1812 const node_datas = tree.nodes.items(.data);1811 const node_datas = tree.nodes.items(.data);
1813 const main_tokens = tree.nodes.items(.main_token);1812 const bool_type = @enumToInt(zir.Const.bool_type);
1813 const gz = scope.getGenZir();
18141814
1815 const bool_type = try addZIRInstConst(mod, scope, src, .{1815 const lhs = try expr(mod, scope, .{ .ty = bool_type }, node_datas[infix_node].lhs);
1816 .ty = Type.initTag(.type),
1817 .val = Value.initTag(.bool_type),
1818 });
18191816
1817 const block_inst = try gz.addBlock(.block, infix_node);
1818 const block_ref = gz.zir_code.ref_start_index + block_inst;
1820 var block_scope: Scope.GenZir = .{1819 var block_scope: Scope.GenZir = .{
1821 .parent = scope,1820 .parent = scope,
1822 .decl = scope.ownerDecl().?,1821 .zir_code = gz.zir_code,
1823 .arena = scope.arena(),1822 .force_comptime = gz.force_comptime,
1824 .force_comptime = scope.isComptime(),
1825 .instructions = .{},
1826 };1823 };
1827 defer block_scope.instructions.deinit(mod.gpa);1824 defer block_scope.instructions.deinit(mod.gpa);
18281825
1829 const lhs = try expr(mod, scope, .{ .ty = bool_type }, node_datas[infix_node].lhs);
1830 const condbr = try addZIRInstSpecial(mod, &block_scope.base, src, zir.Inst.CondBr, .{
1831 .condition = lhs,
1832 .then_body = undefined, // populated below
1833 .else_body = undefined, // populated below
1834 }, .{});
1835
1836 const block = try addZIRInstBlock(mod, scope, src, .block, .{
1837 .instructions = try block_scope.arena.dupe(zir.Inst.Ref, block_scope.instructions.items),
1838 });
1839
1840 var rhs_scope: Scope.GenZir = .{1826 var rhs_scope: Scope.GenZir = .{
1841 .parent = scope,1827 .parent = &block_scope.base,
1842 .decl = block_scope.decl,1828 .zir_code = gz.zir_code,
1843 .arena = block_scope.arena,1829 .force_comptime = gz.force_comptime,
1844 .force_comptime = block_scope.force_comptime,
1845 .instructions = .{},
1846 };1830 };
1847 defer rhs_scope.instructions.deinit(mod.gpa);1831 defer rhs_scope.instructions.deinit(mod.gpa);
1848
1849 const rhs = try expr(mod, &rhs_scope.base, .{ .ty = bool_type }, node_datas[infix_node].rhs);1832 const rhs = try expr(mod, &rhs_scope.base, .{ .ty = bool_type }, node_datas[infix_node].rhs);
1850 _ = try addZIRInst(mod, &rhs_scope.base, src, zir.Inst.Break, .{1833 _ = try rhs_scope.addBin(.@"break", block_inst, rhs);
1851 .block = block,
1852 .operand = rhs,
1853 }, .{});
18541834
1855 var const_scope: Scope.GenZir = .{1835 // TODO: should we have zir.Const instructions for `break true` and `break false`?
1856 .parent = scope,1836 const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len);
1857 .decl = block_scope.decl,1837 const break_true_false_ref = new_index + gz.zir_code.ref_start_index;
1858 .arena = block_scope.arena,1838 try gz.zir_code.instructions.append(gz.zir_code.gpa, .{ .tag = .@"break", .data = .{ .bin = .{
1859 .force_comptime = block_scope.force_comptime,1839 .lhs = block_inst,
1860 .instructions = .{},1840 .rhs = switch (kind) {
1861 };1841 .bool_and => @enumToInt(zir.Const.bool_false),
1862 defer const_scope.instructions.deinit(mod.gpa);1842 .bool_or => @enumToInt(zir.Const.bool_true),
18631843 },
1864 _ = try addZIRInst(mod, &const_scope.base, src, zir.Inst.Break, .{1844 } } });
1865 .block = block,
1866 .operand = try addZIRInstConst(mod, &const_scope.base, src, .{
1867 .ty = Type.initTag(.bool),
1868 .val = if (is_bool_and) Value.initTag(.bool_false) else Value.initTag(.bool_true),
1869 }),
1870 }, .{});
18711845
1872 if (is_bool_and) {1846 switch (kind) {
1873 // if lhs // AND1847 // if lhs // AND
1874 // break rhs1848 // break rhs
1875 // else1849 // else
1876 // break false1850 // break false
1877 condbr.positionals.then_body = .{ .instructions = try rhs_scope.arena.dupe(zir.Inst.Ref, rhs_scope.instructions.items) };1851 .bool_and => _ = try block_scope.addCondBr(
1878 condbr.positionals.else_body = .{ .instructions = try const_scope.arena.dupe(zir.Inst.Ref, const_scope.instructions.items) };1852 lhs,
1879 } else {1853 rhs_scope.instructions.items,
1854 &[_]zir.Inst.Ref{break_true_false_ref},
1855 infix_node,
1856 ),
1880 // if lhs // OR1857 // if lhs // OR
1881 // break true1858 // break true
1882 // else1859 // else
1883 // break rhs1860 // break rhs
1884 condbr.positionals.then_body = .{ .instructions = try const_scope.arena.dupe(zir.Inst.Ref, const_scope.instructions.items) };1861 .bool_or => _ = try block_scope.addCondBr(
1885 condbr.positionals.else_body = .{ .instructions = try rhs_scope.arena.dupe(zir.Inst.Ref, rhs_scope.instructions.items) };1862 lhs,
1863 &[_]zir.Inst.Ref{break_true_false_ref},
1864 rhs_scope.instructions.items,
1865 infix_node,
1866 ),
1886 }1867 }
18871868
1888 return rvalue(mod, scope, rl, &block.base);1869 try gz.instructions.append(mod.gpa, block_inst);
1870 try copyBodyNoEliding(block_inst, block_scope);
1871
1872 return rvalue(mod, scope, rl, block_ref, infix_node);
1889}1873}
18901874
1891fn ifExpr(1875fn ifExpr(