Commit be673e6793

Andrew Kelley <andrew@ziglang.org>
2021-03-24 00:12:26
stage2: implement inttype ZIR
also add i128 and u128 to const inst list
1 parent aa46a70
src/astgen.zig
@@ -2888,7 +2888,10 @@ fn identifier(
     if (ident_name.len >= 2) integer: {
         const first_c = ident_name[0];
         if (first_c == 'i' or first_c == 'u') {
-            const is_signed = first_c == 'i';
+            const signedness: std.builtin.Signedness = switch (first_c == 'i') {
+                true => .signed,
+                false => .unsigned,
+            };
             const bit_count = std.fmt.parseInt(u16, ident_name[1..], 10) catch |err| switch (err) {
                 error.Overflow => return mod.failNode(
                     scope,
@@ -2898,7 +2901,15 @@ fn identifier(
                 ),
                 error.InvalidCharacter => break :integer,
             };
-            return rvalue(mod, scope, rl, try gz.addBin(.int_type, @boolToInt(is_signed), bit_count), ident);
+            const result = try gz.add(.{
+                .tag = .int_type,
+                .data = .{ .int_type = .{
+                    .src_node = gz.zir_code.decl.nodeIndexToRelative(ident),
+                    .signedness = signedness,
+                    .bit_count = bit_count,
+                } },
+            });
+            return rvalue(mod, scope, rl, result, ident);
         }
     }
 
src/Module.zig
@@ -3599,11 +3599,14 @@ pub fn lookupDeclName(mod: *Module, scope: *Scope, ident_name: []const u8) ?*Dec
     return mod.decl_table.get(name_hash);
 }
 
-pub fn makeIntType(arena: *Allocator, signed: bool, bits: u16) !Type {
+pub fn makeIntType(arena: *Allocator, signedness: std.builtin.Signedness, bits: u16) !Type {
     const int_payload = try arena.create(Type.Payload.Bits);
     int_payload.* = .{
         .base = .{
-            .tag = if (signed) .int_signed else .int_unsigned,
+            .tag = switch (signedness) {
+                .signed => .int_signed,
+                .unsigned => .int_unsigned,
+            },
         },
         .data = bits,
     };
src/Sema.zig
@@ -1226,7 +1226,11 @@ fn zirIntType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
     const tracy = trace(@src());
     defer tracy.end();
 
-    return sema.mod.fail(&block.base, sema.src, "TODO implement inttype", .{});
+    const int_type = sema.code.instructions.items(.data)[inst].int_type;
+    const src = int_type.src();
+    const ty = try Module.makeIntType(sema.arena, int_type.signedness, int_type.bit_count);
+
+    return sema.mod.constType(sema.arena, src, ty);
 }
 
 fn zirOptionalType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
@@ -3967,7 +3971,8 @@ fn cmpNumeric(
         const casted_bits = std.math.cast(u16, max_bits) catch |err| switch (err) {
             error.Overflow => return sema.mod.fail(&block.base, src, "{d} exceeds maximum integer bit count", .{max_bits}),
         };
-        break :blk try Module.makeIntType(sema.arena, dest_int_is_signed, casted_bits);
+        const signedness: std.builtin.Signedness = if (dest_int_is_signed) .signed else .unsigned;
+        break :blk try Module.makeIntType(sema.arena, signedness, casted_bits);
     };
     const casted_lhs = try sema.coerce(block, dest_type, lhs, lhs.src);
     const casted_rhs = try sema.coerce(block, dest_type, rhs, rhs.src);
src/value.zig
@@ -30,6 +30,8 @@ pub const Value = extern union {
         i32_type,
         u64_type,
         i64_type,
+        u128_type,
+        i128_type,
         usize_type,
         isize_type,
         c_short_type,
@@ -120,6 +122,8 @@ pub const Value = extern union {
                 .i32_type,
                 .u64_type,
                 .i64_type,
+                .u128_type,
+                .i128_type,
                 .usize_type,
                 .isize_type,
                 .c_short_type,
@@ -274,6 +278,8 @@ pub const Value = extern union {
             .i32_type,
             .u64_type,
             .i64_type,
+            .u128_type,
+            .i128_type,
             .usize_type,
             .isize_type,
             .c_short_type,
@@ -427,6 +433,8 @@ pub const Value = extern union {
             .i32_type => return out_stream.writeAll("i32"),
             .u64_type => return out_stream.writeAll("u64"),
             .i64_type => return out_stream.writeAll("i64"),
+            .u128_type => return out_stream.writeAll("u128"),
+            .i128_type => return out_stream.writeAll("i128"),
             .isize_type => return out_stream.writeAll("isize"),
             .usize_type => return out_stream.writeAll("usize"),
             .c_short_type => return out_stream.writeAll("c_short"),
@@ -554,6 +562,8 @@ pub const Value = extern union {
             .i32_type => Type.initTag(.i32),
             .u64_type => Type.initTag(.u64),
             .i64_type => Type.initTag(.i64),
+            .u128_type => Type.initTag(.u128),
+            .i128_type => Type.initTag(.i128),
             .usize_type => Type.initTag(.usize),
             .isize_type => Type.initTag(.isize),
             .c_short_type => Type.initTag(.c_short),
@@ -650,6 +660,8 @@ pub const Value = extern union {
             .i32_type,
             .u64_type,
             .i64_type,
+            .u128_type,
+            .i128_type,
             .usize_type,
             .isize_type,
             .c_short_type,
@@ -736,6 +748,8 @@ pub const Value = extern union {
             .i32_type,
             .u64_type,
             .i64_type,
+            .u128_type,
+            .i128_type,
             .usize_type,
             .isize_type,
             .c_short_type,
@@ -822,6 +836,8 @@ pub const Value = extern union {
             .i32_type,
             .u64_type,
             .i64_type,
+            .u128_type,
+            .i128_type,
             .usize_type,
             .isize_type,
             .c_short_type,
@@ -935,6 +951,8 @@ pub const Value = extern union {
             .i32_type,
             .u64_type,
             .i64_type,
+            .u128_type,
+            .i128_type,
             .usize_type,
             .isize_type,
             .c_short_type,
@@ -1026,6 +1044,8 @@ pub const Value = extern union {
             .i32_type,
             .u64_type,
             .i64_type,
+            .u128_type,
+            .i128_type,
             .usize_type,
             .isize_type,
             .c_short_type,
@@ -1182,6 +1202,8 @@ pub const Value = extern union {
             .i32_type,
             .u64_type,
             .i64_type,
+            .u128_type,
+            .i128_type,
             .usize_type,
             .isize_type,
             .c_short_type,
@@ -1265,6 +1287,8 @@ pub const Value = extern union {
             .i32_type,
             .u64_type,
             .i64_type,
+            .u128_type,
+            .i128_type,
             .usize_type,
             .isize_type,
             .c_short_type,
@@ -1416,6 +1440,8 @@ pub const Value = extern union {
             .i32_type,
             .u64_type,
             .i64_type,
+            .u128_type,
+            .i128_type,
             .usize_type,
             .isize_type,
             .c_short_type,
@@ -1573,6 +1599,8 @@ pub const Value = extern union {
             .i32_type,
             .u64_type,
             .i64_type,
+            .u128_type,
+            .i128_type,
             .usize_type,
             .isize_type,
             .c_short_type,
@@ -1659,6 +1687,8 @@ pub const Value = extern union {
             .i32_type,
             .u64_type,
             .i64_type,
+            .u128_type,
+            .i128_type,
             .usize_type,
             .isize_type,
             .c_short_type,
@@ -1762,6 +1792,8 @@ pub const Value = extern union {
             .i32_type,
             .u64_type,
             .i64_type,
+            .u128_type,
+            .i128_type,
             .usize_type,
             .isize_type,
             .c_short_type,
@@ -1843,6 +1875,8 @@ pub const Value = extern union {
             .i32_type,
             .u64_type,
             .i64_type,
+            .u128_type,
+            .i128_type,
             .usize_type,
             .isize_type,
             .c_short_type,
@@ -1944,6 +1978,8 @@ pub const Value = extern union {
             .i32_type,
             .u64_type,
             .i64_type,
+            .u128_type,
+            .i128_type,
             .usize_type,
             .isize_type,
             .c_short_type,
src/zir.zig
@@ -125,6 +125,8 @@ pub const Const = enum {
     i32_type,
     u64_type,
     i64_type,
+    u128_type,
+    i128_type,
     usize_type,
     isize_type,
     c_short_type,
@@ -210,6 +212,14 @@ pub const const_inst_list = std.enums.directEnumArray(Const, TypedValue, 0, .{
         .ty = Type.initTag(.type),
         .val = Value.initTag(.i64_type),
     },
+    .u128_type = .{
+        .ty = Type.initTag(.type),
+        .val = Value.initTag(.u128_type),
+    },
+    .i128_type = .{
+        .ty = Type.initTag(.type),
+        .val = Value.initTag(.i128_type),
+    },
     .usize_type = .{
         .ty = Type.initTag(.type),
         .val = Value.initTag(.usize_type),
@@ -619,8 +629,7 @@ pub const Inst = struct {
         /// Payload is `Bin` with lhs as the dest type, rhs the operand.
         intcast,
         /// Make an integer type out of signedness and bit count.
-        /// lhs is signedness, rhs is bit count.
-        /// Payload is `Bin`
+        /// Payload is `int_type`
         int_type,
         /// Return a boolean false if an optional is null. `x != null`
         /// Uses the `un_tok` field.
@@ -1135,6 +1144,17 @@ pub const Inst = struct {
             /// For `fn_type_cc` this points to `FnTypeCc` in `extra`.
             payload_index: u32,
         },
+        int_type: struct {
+            /// Offset from Decl AST node index.
+            /// `Tag` determines which kind of AST node this points to.
+            src_node: i32,
+            signedness: std.builtin.Signedness,
+            bit_count: u16,
+
+            pub fn src(self: @This()) LazySrcLoc {
+                return .{ .node_offset = self.src_node };
+            }
+        },
         bool_br: struct {
             lhs: Ref,
             /// Points to a `Block`.
@@ -1340,7 +1360,6 @@ const Writer = struct {
             .elem_ptr,
             .elem_val,
             .intcast,
-            .int_type,
             .merge_error_sets,
             => try self.writeBin(stream, inst),
 
@@ -1405,6 +1424,7 @@ const Writer = struct {
             .str => try self.writeStr(stream, inst),
             .elided => try stream.writeAll(")"),
             .break_void_node => try self.writeBreakVoidNode(stream, inst),
+            .int_type => try self.writeIntType(stream, inst),
 
             .@"asm",
             .asm_volatile,
@@ -1742,6 +1762,16 @@ const Writer = struct {
         try self.writeSrc(stream, inst_data.src());
     }
 
+    fn writeIntType(self: *Writer, stream: anytype, inst: Inst.Index) !void {
+        const int_type = self.code.instructions.items(.data)[inst].int_type;
+        const prefix: u8 = switch (int_type.signedness) {
+            .signed => 'i',
+            .unsigned => 'u',
+        };
+        try stream.print("{c}{d}) ", .{ prefix, int_type.bit_count });
+        try self.writeSrc(stream, int_type.src());
+    }
+
     fn writeUnreachable(self: *Writer, stream: anytype, inst: Inst.Index) !void {
         const inst_data = self.code.instructions.items(.data)[inst].@"unreachable";
         const safety_str = if (inst_data.safety) "safe" else "unsafe";