| ... | @@ -8,16 +8,6 @@ const assert = std.debug.assert; | ... | @@ -8,16 +8,6 @@ const assert = std.debug.assert; |
| 8 | pub const Inst = struct { | 8 | pub const Inst = struct { |
| 9 | tag: Tag, | 9 | tag: Tag, |
| 10 | | 10 | |
| 11 | pub const all_types = .{ | | |
| 12 | Constant, | | |
| 13 | PtrToInt, | | |
| 14 | FieldPtr, | | |
| 15 | Deref, | | |
| 16 | Assembly, | | |
| 17 | Unreach, | | |
| 18 | Fn, | | |
| 19 | }; | | |
| 20 | | | |
| 21 | /// These names are used for the IR text format. | 11 | /// These names are used for the IR text format. |
| 22 | pub const Tag = enum { | 12 | pub const Tag = enum { |
| 23 | constant, | 13 | constant, |
| ... | @@ -29,6 +19,23 @@ pub const Inst = struct { | ... | @@ -29,6 +19,23 @@ pub const Inst = struct { |
| 29 | @"fn", | 19 | @"fn", |
| 30 | }; | 20 | }; |
| 31 | | 21 | |
| | 22 | pub fn TagToType(tag: Tag) type { |
| | 23 | return switch (tag) { |
| | 24 | .constant => Constant, |
| | 25 | .ptrtoint => PtrToInt, |
| | 26 | .fieldptr => FieldPtr, |
| | 27 | .deref => Deref, |
| | 28 | .@"asm" => Assembly, |
| | 29 | .unreach => Unreach, |
| | 30 | .@"fn" => Fn, |
| | 31 | }; |
| | 32 | } |
| | 33 | |
| | 34 | /// Represents a reference to another instruction. |
| | 35 | pub const OtherInst = struct { |
| | 36 | index: usize, |
| | 37 | }; |
| | 38 | |
| 32 | /// This struct owns the `Value` memory. When the struct is deallocated, | 39 | /// This struct owns the `Value` memory. When the struct is deallocated, |
| 33 | /// so is the `Value`. The value of a constant must be copied into | 40 | /// so is the `Value`. The value of a constant must be copied into |
| 34 | /// a memory location for the value to survive after a const instruction. | 41 | /// a memory location for the value to survive after a const instruction. |
| ... | @@ -45,7 +52,9 @@ pub const Inst = struct { | ... | @@ -45,7 +52,9 @@ pub const Inst = struct { |
| 45 | pub const PtrToInt = struct { | 52 | pub const PtrToInt = struct { |
| 46 | base: Inst = Inst{ .tag = .ptrtoint }, | 53 | base: Inst = Inst{ .tag = .ptrtoint }, |
| 47 | | 54 | |
| 48 | positionals: struct {}, | 55 | positionals: struct { |
| | 56 | ptr: OtherInst, |
| | 57 | }, |
| 49 | kw_args: struct {}, | 58 | kw_args: struct {}, |
| 50 | }; | 59 | }; |
| 51 | | 60 | |
| ... | @@ -224,10 +233,10 @@ fn parseInstruction(ctx: *ParseContext, opt_type: ?Type) error{ OutOfMemory, Par | ... | @@ -224,10 +233,10 @@ fn parseInstruction(ctx: *ParseContext, opt_type: ?Type) error{ OutOfMemory, Par |
| 224 | else => {}, | 233 | else => {}, |
| 225 | } | 234 | } |
| 226 | const fn_name = try skipToAndOver(ctx, '('); | 235 | const fn_name = try skipToAndOver(ctx, '('); |
| 227 | inline for (Inst.all_types) |InstType| { | 236 | inline for (@typeInfo(Inst.Tag).Enum.fields) |field| { |
| 228 | const this_name = @tagName(std.meta.fieldInfo(InstType, "base").default_value.?.tag); | 237 | if (mem.eql(u8, field.name, fn_name)) { |
| 229 | if (mem.eql(u8, this_name, fn_name)) { | 238 | const tag = @field(Inst.Tag, field.name); |
| 230 | return parseInstructionGeneric(ctx, this_name, InstType, opt_type); | 239 | return parseInstructionGeneric(ctx, field.name, Inst.TagToType(tag), opt_type); |
| 231 | } | 240 | } |
| 232 | } | 241 | } |
| 233 | return parseError(ctx, "unknown instruction '{}'", .{fn_name}); | 242 | return parseError(ctx, "unknown instruction '{}'", .{fn_name}); |
| ... | @@ -288,6 +297,9 @@ fn parseParameterGeneric(ctx: *ParseContext, comptime T: type) !T { | ... | @@ -288,6 +297,9 @@ fn parseParameterGeneric(ctx: *ParseContext, comptime T: type) !T { |
| 288 | } | 297 | } |
| 289 | switch (T) { | 298 | switch (T) { |
| 290 | Inst.Fn.Body => return parseBody(ctx), | 299 | Inst.Fn.Body => return parseBody(ctx), |
| | 300 | Inst.OtherInst => { |
| | 301 | return parseError(ctx, "TODO implement parseParameterGeneric for OtherInst", .{}); |
| | 302 | }, |
| 291 | Value => return parseError(ctx, "TODO implement parseParameterGeneric for type Value", .{}), | 303 | Value => return parseError(ctx, "TODO implement parseParameterGeneric for type Value", .{}), |
| 292 | else => @compileError("Unimplemented: ir parseParameterGeneric for type " ++ @typeName(T)), | 304 | else => @compileError("Unimplemented: ir parseParameterGeneric for type " ++ @typeName(T)), |
| 293 | } | 305 | } |