| author | |
| committer | |
| log | 715abe8ebeebb6d49db1e265748554404c3aab98 |
| tree | 19c0fc7880bb3d9205877b31043a757de61f9cda |
| parent | 2d290d6f82b780fc5c1448bcc41fec602359dfec |
also get rid of the `optional_type_from_ptr_elem` instruction.4 files changed, 95 insertions(+), 66 deletions(-)
src/AstGen.zig+32-14| ... | @@ -1735,6 +1735,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner | ... | @@ -1735,6 +1735,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner |
| 1735 | .func, | 1735 | .func, |
| 1736 | .func_inferred, | 1736 | .func_inferred, |
| 1737 | .int, | 1737 | .int, |
| 1738 | .int_big, | ||
| 1738 | .float, | 1739 | .float, |
| 1739 | .float128, | 1740 | .float128, |
| 1740 | .intcast, | 1741 | .intcast, |
| ... | @@ -1762,7 +1763,6 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner | ... | @@ -1762,7 +1763,6 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner |
| 1762 | .typeof_elem, | 1763 | .typeof_elem, |
| 1763 | .xor, | 1764 | .xor, |
| 1764 | .optional_type, | 1765 | .optional_type, |
| 1765 | .optional_type_from_ptr_elem, | ||
| 1766 | .optional_payload_safe, | 1766 | .optional_payload_safe, |
| 1767 | .optional_payload_unsafe, | 1767 | .optional_payload_unsafe, |
| 1768 | .optional_payload_safe_ptr, | 1768 | .optional_payload_safe_ptr, |
| ... | @@ -3874,18 +3874,9 @@ fn orelseCatchExpr( | ... | @@ -3874,18 +3874,9 @@ fn orelseCatchExpr( |
| 3874 | block_scope.setBreakResultLoc(rl); | 3874 | block_scope.setBreakResultLoc(rl); |
| 3875 | defer block_scope.instructions.deinit(astgen.gpa); | 3875 | defer block_scope.instructions.deinit(astgen.gpa); |
| 3876 | 3876 | ||
| 3877 | // TODO get rid of optional_type_from_ptr_elem | ||
| 3878 | const operand_rl: ResultLoc = switch (block_scope.break_result_loc) { | 3877 | const operand_rl: ResultLoc = switch (block_scope.break_result_loc) { |
| 3879 | .ref => .ref, | 3878 | .ref => .ref, |
| 3880 | .discard, .none, .none_or_ref, .block_ptr, .inferred_ptr => .none, | 3879 | else => .none, |
| 3881 | .ty => |elem_ty| blk: { | ||
| 3882 | const wrapped_ty = try block_scope.addUnNode(.optional_type, elem_ty, node); | ||
| 3883 | break :blk .{ .ty = wrapped_ty }; | ||
| 3884 | }, | ||
| 3885 | .ptr => |ptr_ty| blk: { | ||
| 3886 | const wrapped_ty = try block_scope.addUnNode(.optional_type_from_ptr_elem, ptr_ty, node); | ||
| 3887 | break :blk .{ .ty = wrapped_ty }; | ||
| 3888 | }, | ||
| 3889 | }; | 3880 | }; |
| 3890 | block_scope.break_count += 1; | 3881 | block_scope.break_count += 1; |
| 3891 | // This could be a pointer or value depending on the `operand_rl` parameter. | 3882 | // This could be a pointer or value depending on the `operand_rl` parameter. |
| ... | @@ -5755,10 +5746,37 @@ fn integerLiteral( | ... | @@ -5755,10 +5746,37 @@ fn integerLiteral( |
| 5755 | else => try gz.addInt(small_int), | 5746 | else => try gz.addInt(small_int), |
| 5756 | }; | 5747 | }; |
| 5757 | return rvalue(gz, scope, rl, result, node); | 5748 | return rvalue(gz, scope, rl, result, node); |
| 5758 | } else |err| { | 5749 | } else |err| switch (err) { |
| 5759 | assert(err != error.InvalidCharacter); | 5750 | error.InvalidCharacter => unreachable, // Caught by the parser. |
| 5760 | return gz.astgen.failNode(node, "TODO implement int literals that don't fit in a u64", .{}); | 5751 | error.Overflow => {}, |
| 5752 | } | ||
| 5753 | |||
| 5754 | var base: u8 = 10; | ||
| 5755 | var non_prefixed: []const u8 = prefixed_bytes; | ||
| 5756 | if (mem.startsWith(u8, prefixed_bytes, "0x")) { | ||
| 5757 | base = 16; | ||
| 5758 | non_prefixed = prefixed_bytes[2..]; | ||
| 5759 | } else if (mem.startsWith(u8, prefixed_bytes, "0o")) { | ||
| 5760 | base = 8; | ||
| 5761 | non_prefixed = prefixed_bytes[2..]; | ||
| 5762 | } else if (mem.startsWith(u8, prefixed_bytes, "0b")) { | ||
| 5763 | base = 2; | ||
| 5764 | non_prefixed = prefixed_bytes[2..]; | ||
| 5761 | } | 5765 | } |
| 5766 | |||
| 5767 | const gpa = astgen.gpa; | ||
| 5768 | var big_int = try std.math.big.int.Managed.init(gpa); | ||
| 5769 | defer big_int.deinit(); | ||
| 5770 | big_int.setString(base, non_prefixed) catch |err| switch (err) { | ||
| 5771 | error.InvalidCharacter => unreachable, // caught by parser | ||
| 5772 | error.InvalidBase => unreachable, // we only pass 16, 8, 2, see above | ||
| 5773 | error.OutOfMemory => return error.OutOfMemory, | ||
| 5774 | }; | ||
| 5775 | |||
| 5776 | const limbs = big_int.limbs[0..big_int.len()]; | ||
| 5777 | assert(big_int.isPositive()); | ||
| 5778 | const result = try gz.addIntBig(limbs); | ||
| 5779 | return rvalue(gz, scope, rl, result, node); | ||
| 5762 | } | 5780 | } |
| 5763 | 5781 | ||
| 5764 | fn floatLiteral( | 5782 | fn floatLiteral( |
src/Module.zig+20-16| ... | @@ -1423,6 +1423,26 @@ pub const Scope = struct { | ... | @@ -1423,6 +1423,26 @@ pub const Scope = struct { |
| 1423 | }); | 1423 | }); |
| 1424 | } | 1424 | } |
| 1425 | 1425 | ||
| 1426 | pub fn addIntBig(gz: *GenZir, limbs: []const std.math.big.Limb) !Zir.Inst.Ref { | ||
| 1427 | const astgen = gz.astgen; | ||
| 1428 | const gpa = astgen.gpa; | ||
| 1429 | try gz.instructions.ensureUnusedCapacity(gpa, 1); | ||
| 1430 | try astgen.instructions.ensureUnusedCapacity(gpa, 1); | ||
| 1431 | try astgen.string_bytes.ensureUnusedCapacity(gpa, @sizeOf(std.math.big.Limb) * limbs.len); | ||
| 1432 | |||
| 1433 | const new_index = @intCast(Zir.Inst.Index, astgen.instructions.len); | ||
| 1434 | astgen.instructions.appendAssumeCapacity(.{ | ||
| 1435 | .tag = .int_big, | ||
| 1436 | .data = .{ .str = .{ | ||
| 1437 | .start = @intCast(u32, astgen.string_bytes.items.len), | ||
| 1438 | .len = @intCast(u32, limbs.len), | ||
| 1439 | } }, | ||
| 1440 | }); | ||
| 1441 | gz.instructions.appendAssumeCapacity(new_index); | ||
| 1442 | astgen.string_bytes.appendSliceAssumeCapacity(mem.sliceAsBytes(limbs)); | ||
| 1443 | return gz.indexToRef(new_index); | ||
| 1444 | } | ||
| 1445 | |||
| 1426 | pub fn addFloat(gz: *GenZir, number: f32, src_node: ast.Node.Index) !Zir.Inst.Ref { | 1446 | pub fn addFloat(gz: *GenZir, number: f32, src_node: ast.Node.Index) !Zir.Inst.Ref { |
| 1427 | return gz.add(.{ | 1447 | return gz.add(.{ |
| 1428 | .tag = .float, | 1448 | .tag = .float, |
| ... | @@ -1683,22 +1703,6 @@ pub const Scope = struct { | ... | @@ -1683,22 +1703,6 @@ pub const Scope = struct { |
| 1683 | return gz.indexToRef(new_index); | 1703 | return gz.indexToRef(new_index); |
| 1684 | } | 1704 | } |
| 1685 | 1705 | ||
| 1686 | /// Asserts that `str` is 8 or fewer bytes. | ||
| 1687 | pub fn addSmallStr( | ||
| 1688 | gz: *GenZir, | ||
| 1689 | tag: Zir.Inst.Tag, | ||
| 1690 | str: []const u8, | ||
| 1691 | ) !Zir.Inst.Ref { | ||
| 1692 | var buf: [9]u8 = undefined; | ||
| 1693 | mem.copy(u8, &buf, str); | ||
| 1694 | buf[str.len] = 0; | ||
| 1695 | |||
| 1696 | return gz.add(.{ | ||
| 1697 | .tag = tag, | ||
| 1698 | .data = .{ .small_str = .{ .bytes = buf[0..8].* } }, | ||
| 1699 | }); | ||
| 1700 | } | ||
| 1701 | |||
| 1702 | /// Note that this returns a `Zir.Inst.Index` not a ref. | 1706 | /// Note that this returns a `Zir.Inst.Index` not a ref. |
| 1703 | /// Does *not* append the block instruction to the scope. | 1707 | /// Does *not* append the block instruction to the scope. |
| 1704 | /// Leaves the `payload_index` field undefined. | 1708 | /// Leaves the `payload_index` field undefined. |
src/Sema.zig+18-13| ... | @@ -200,6 +200,7 @@ pub fn analyzeBody( | ... | @@ -200,6 +200,7 @@ pub fn analyzeBody( |
| 200 | .import => try sema.zirImport(block, inst), | 200 | .import => try sema.zirImport(block, inst), |
| 201 | .indexable_ptr_len => try sema.zirIndexablePtrLen(block, inst), | 201 | .indexable_ptr_len => try sema.zirIndexablePtrLen(block, inst), |
| 202 | .int => try sema.zirInt(block, inst), | 202 | .int => try sema.zirInt(block, inst), |
| 203 | .int_big => try sema.zirIntBig(block, inst), | ||
| 203 | .float => try sema.zirFloat(block, inst), | 204 | .float => try sema.zirFloat(block, inst), |
| 204 | .float128 => try sema.zirFloat128(block, inst), | 205 | .float128 => try sema.zirFloat128(block, inst), |
| 205 | .int_type => try sema.zirIntType(block, inst), | 206 | .int_type => try sema.zirIntType(block, inst), |
| ... | @@ -219,7 +220,6 @@ pub fn analyzeBody( | ... | @@ -219,7 +220,6 @@ pub fn analyzeBody( |
| 219 | .optional_payload_unsafe => try sema.zirOptionalPayload(block, inst, false), | 220 | .optional_payload_unsafe => try sema.zirOptionalPayload(block, inst, false), |
| 220 | .optional_payload_unsafe_ptr => try sema.zirOptionalPayloadPtr(block, inst, false), | 221 | .optional_payload_unsafe_ptr => try sema.zirOptionalPayloadPtr(block, inst, false), |
| 221 | .optional_type => try sema.zirOptionalType(block, inst), | 222 | .optional_type => try sema.zirOptionalType(block, inst), |
| 222 | .optional_type_from_ptr_elem => try sema.zirOptionalTypeFromPtrElem(block, inst), | ||
| 223 | .param_type => try sema.zirParamType(block, inst), | 223 | .param_type => try sema.zirParamType(block, inst), |
| 224 | .ptr_type => try sema.zirPtrType(block, inst), | 224 | .ptr_type => try sema.zirPtrType(block, inst), |
| 225 | .ptr_type_simple => try sema.zirPtrTypeSimple(block, inst), | 225 | .ptr_type_simple => try sema.zirPtrTypeSimple(block, inst), |
| ... | @@ -1479,6 +1479,23 @@ fn zirInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*In | ... | @@ -1479,6 +1479,23 @@ fn zirInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*In |
| 1479 | return sema.mod.constIntUnsigned(sema.arena, .unneeded, Type.initTag(.comptime_int), int); | 1479 | return sema.mod.constIntUnsigned(sema.arena, .unneeded, Type.initTag(.comptime_int), int); |
| 1480 | } | 1480 | } |
| 1481 | 1481 | ||
| 1482 | fn zirIntBig(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { | ||
| 1483 | const tracy = trace(@src()); | ||
| 1484 | defer tracy.end(); | ||
| 1485 | |||
| 1486 | const arena = sema.arena; | ||
| 1487 | const int = sema.code.instructions.items(.data)[inst].str; | ||
| 1488 | const byte_count = int.len * @sizeOf(std.math.big.Limb); | ||
| 1489 | const limb_bytes = sema.code.string_bytes[int.start..][0..byte_count]; | ||
| 1490 | const limbs = try arena.alloc(std.math.big.Limb, int.len); | ||
| 1491 | mem.copy(u8, mem.sliceAsBytes(limbs), limb_bytes); | ||
| 1492 | |||
| 1493 | return sema.mod.constInst(arena, .unneeded, .{ | ||
| 1494 | .ty = Type.initTag(.comptime_int), | ||
| 1495 | .val = try Value.Tag.int_big_positive.create(arena, limbs), | ||
| 1496 | }); | ||
| 1497 | } | ||
| 1498 | |||
| 1482 | fn zirFloat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { | 1499 | fn zirFloat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { |
| 1483 | const arena = sema.arena; | 1500 | const arena = sema.arena; |
| 1484 | const inst_data = sema.code.instructions.items(.data)[inst].float; | 1501 | const inst_data = sema.code.instructions.items(.data)[inst].float; |
| ... | @@ -2120,18 +2137,6 @@ fn zirOptionalType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inner | ... | @@ -2120,18 +2137,6 @@ fn zirOptionalType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inner |
| 2120 | return sema.mod.constType(sema.arena, src, opt_type); | 2137 | return sema.mod.constType(sema.arena, src, opt_type); |
| 2121 | } | 2138 | } |
| 2122 | 2139 | ||
| 2123 | fn zirOptionalTypeFromPtrElem(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { | ||
| 2124 | const tracy = trace(@src()); | ||
| 2125 | defer tracy.end(); | ||
| 2126 | |||
| 2127 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | ||
| 2128 | const ptr = try sema.resolveInst(inst_data.operand); | ||
| 2129 | const elem_ty = ptr.ty.elemType(); | ||
| 2130 | const opt_ty = try sema.mod.optionalType(sema.arena, elem_ty); | ||
| 2131 | |||
| 2132 | return sema.mod.constType(sema.arena, inst_data.src(), opt_ty); | ||
| 2133 | } | ||
| 2134 | |||
| 2135 | fn zirElemType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { | 2140 | fn zirElemType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { |
| 2136 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | 2141 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 2137 | const src = inst_data.src(); | 2142 | const src = inst_data.src(); |
src/Zir.zig+25-23| ... | @@ -374,8 +374,10 @@ pub const Inst = struct { | ... | @@ -374,8 +374,10 @@ pub const Inst = struct { |
| 374 | /// Implements the `@import` builtin. | 374 | /// Implements the `@import` builtin. |
| 375 | /// Uses the `str_tok` field. | 375 | /// Uses the `str_tok` field. |
| 376 | import, | 376 | import, |
| 377 | /// Integer literal that fits in a u64. Uses the int union value. | 377 | /// Integer literal that fits in a u64. Uses the `int` union field. |
| 378 | int, | 378 | int, |
| 379 | /// Arbitrary sized integer literal. Uses the `str` union field. | ||
| 380 | int_big, | ||
| 379 | /// A float literal that fits in a f32. Uses the float union value. | 381 | /// A float literal that fits in a f32. Uses the float union value. |
| 380 | float, | 382 | float, |
| 381 | /// A float literal that fits in a f128. Uses the `pl_node` union value. | 383 | /// A float literal that fits in a f128. Uses the `pl_node` union value. |
| ... | @@ -540,10 +542,6 @@ pub const Inst = struct { | ... | @@ -540,10 +542,6 @@ pub const Inst = struct { |
| 540 | /// Create an optional type '?T' | 542 | /// Create an optional type '?T' |
| 541 | /// Uses the `un_node` field. | 543 | /// Uses the `un_node` field. |
| 542 | optional_type, | 544 | optional_type, |
| 543 | /// Create an optional type '?T'. The operand is a pointer value. The optional type will | ||
| 544 | /// be the type of the pointer element, wrapped in an optional. | ||
| 545 | /// Uses the `un_node` field. | ||
| 546 | optional_type_from_ptr_elem, | ||
| 547 | /// ?T => T with safety. | 545 | /// ?T => T with safety. |
| 548 | /// Given an optional value, returns the payload value, with a safety check that | 546 | /// Given an optional value, returns the payload value, with a safety check that |
| 549 | /// the value is non-null. Used for `orelse`, `if` and `while`. | 547 | /// the value is non-null. Used for `orelse`, `if` and `while`. |
| ... | @@ -1030,6 +1028,7 @@ pub const Inst = struct { | ... | @@ -1030,6 +1028,7 @@ pub const Inst = struct { |
| 1030 | .func_inferred, | 1028 | .func_inferred, |
| 1031 | .has_decl, | 1029 | .has_decl, |
| 1032 | .int, | 1030 | .int, |
| 1031 | .int_big, | ||
| 1033 | .float, | 1032 | .float, |
| 1034 | .float128, | 1033 | .float128, |
| 1035 | .intcast, | 1034 | .intcast, |
| ... | @@ -1061,7 +1060,6 @@ pub const Inst = struct { | ... | @@ -1061,7 +1060,6 @@ pub const Inst = struct { |
| 1061 | .typeof_elem, | 1060 | .typeof_elem, |
| 1062 | .xor, | 1061 | .xor, |
| 1063 | .optional_type, | 1062 | .optional_type, |
| 1064 | .optional_type_from_ptr_elem, | ||
| 1065 | .optional_payload_safe, | 1063 | .optional_payload_safe, |
| 1066 | .optional_payload_unsafe, | 1064 | .optional_payload_unsafe, |
| 1067 | .optional_payload_safe_ptr, | 1065 | .optional_payload_safe_ptr, |
| ... | @@ -1700,17 +1698,6 @@ pub const Inst = struct { | ... | @@ -1700,17 +1698,6 @@ pub const Inst = struct { |
| 1700 | return code.string_bytes[self.start..][0..self.len]; | 1698 | return code.string_bytes[self.start..][0..self.len]; |
| 1701 | } | 1699 | } |
| 1702 | }, | 1700 | }, |
| 1703 | /// Strings 8 or fewer bytes which may not contain null bytes. | ||
| 1704 | small_str: struct { | ||
| 1705 | bytes: [8]u8, | ||
| 1706 | |||
| 1707 | pub fn get(self: @This()) []const u8 { | ||
| 1708 | const end = for (self.bytes) |byte, i| { | ||
| 1709 | if (byte == 0) break i; | ||
| 1710 | } else self.bytes.len; | ||
| 1711 | return self.bytes[0..end]; | ||
| 1712 | } | ||
| 1713 | }, | ||
| 1714 | str_tok: struct { | 1701 | str_tok: struct { |
| 1715 | /// Offset into `string_bytes`. Null-terminated. | 1702 | /// Offset into `string_bytes`. Null-terminated. |
| 1716 | start: u32, | 1703 | start: u32, |
| ... | @@ -2324,7 +2311,6 @@ const Writer = struct { | ... | @@ -2324,7 +2311,6 @@ const Writer = struct { |
| 2324 | .ret_node, | 2311 | .ret_node, |
| 2325 | .resolve_inferred_alloc, | 2312 | .resolve_inferred_alloc, |
| 2326 | .optional_type, | 2313 | .optional_type, |
| 2327 | .optional_type_from_ptr_elem, | ||
| 2328 | .optional_payload_safe, | 2314 | .optional_payload_safe, |
| 2329 | .optional_payload_unsafe, | 2315 | .optional_payload_unsafe, |
| 2330 | .optional_payload_safe_ptr, | 2316 | .optional_payload_safe_ptr, |
| ... | @@ -2405,6 +2391,7 @@ const Writer = struct { | ... | @@ -2405,6 +2391,7 @@ const Writer = struct { |
| 2405 | .ptr_type_simple => try self.writePtrTypeSimple(stream, inst), | 2391 | .ptr_type_simple => try self.writePtrTypeSimple(stream, inst), |
| 2406 | .ptr_type => try self.writePtrType(stream, inst), | 2392 | .ptr_type => try self.writePtrType(stream, inst), |
| 2407 | .int => try self.writeInt(stream, inst), | 2393 | .int => try self.writeInt(stream, inst), |
| 2394 | .int_big => try self.writeIntBig(stream, inst), | ||
| 2408 | .float => try self.writeFloat(stream, inst), | 2395 | .float => try self.writeFloat(stream, inst), |
| 2409 | .float128 => try self.writeFloat128(stream, inst), | 2396 | .float128 => try self.writeFloat128(stream, inst), |
| 2410 | .str => try self.writeStr(stream, inst), | 2397 | .str => try self.writeStr(stream, inst), |
| ... | @@ -2710,15 +2697,30 @@ const Writer = struct { | ... | @@ -2710,15 +2697,30 @@ const Writer = struct { |
| 2710 | try stream.writeAll("TODO)"); | 2697 | try stream.writeAll("TODO)"); |
| 2711 | } | 2698 | } |
| 2712 | 2699 | ||
| 2713 | fn writeInt( | 2700 | fn writeInt(self: *Writer, stream: anytype, inst: Inst.Index) !void { |
| 2714 | self: *Writer, | ||
| 2715 | stream: anytype, | ||
| 2716 | inst: Inst.Index, | ||
| 2717 | ) (@TypeOf(stream).Error || error{OutOfMemory})!void { | ||
| 2718 | const inst_data = self.code.instructions.items(.data)[inst].int; | 2701 | const inst_data = self.code.instructions.items(.data)[inst].int; |
| 2719 | try stream.print("{d})", .{inst_data}); | 2702 | try stream.print("{d})", .{inst_data}); |
| 2720 | } | 2703 | } |
| 2721 | 2704 | ||
| 2705 | fn writeIntBig(self: *Writer, stream: anytype, inst: Inst.Index) !void { | ||
| 2706 | const inst_data = self.code.instructions.items(.data)[inst].str; | ||
| 2707 | const byte_count = inst_data.len * @sizeOf(std.math.big.Limb); | ||
| 2708 | const limb_bytes = self.code.string_bytes[inst_data.start..][0..byte_count]; | ||
| 2709 | // limb_bytes is not aligned properly; we must allocate and copy the bytes | ||
| 2710 | // in order to accomplish this. | ||
| 2711 | const limbs = try self.gpa.alloc(std.math.big.Limb, inst_data.len); | ||
| 2712 | defer self.gpa.free(limbs); | ||
| 2713 | |||
| 2714 | mem.copy(u8, mem.sliceAsBytes(limbs), limb_bytes); | ||
| 2715 | const big_int: std.math.big.int.Const = .{ | ||
| 2716 | .limbs = limbs, | ||
| 2717 | .positive = true, | ||
| 2718 | }; | ||
| 2719 | const as_string = try big_int.toStringAlloc(self.gpa, 10, false); | ||
| 2720 | defer self.gpa.free(as_string); | ||
| 2721 | try stream.print("{s})", .{as_string}); | ||
| 2722 | } | ||
| 2723 | |||
| 2722 | fn writeFloat(self: *Writer, stream: anytype, inst: Inst.Index) !void { | 2724 | fn writeFloat(self: *Writer, stream: anytype, inst: Inst.Index) !void { |
| 2723 | const inst_data = self.code.instructions.items(.data)[inst].float; | 2725 | const inst_data = self.code.instructions.items(.data)[inst].float; |
| 2724 | const src = inst_data.src(); | 2726 | const src = inst_data.src(); |