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