authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-19 00:15:52-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-19 19:31:50-04:00
log49e2f3ca36edddc16d13959bc4b16745a04c6383
treeb90d5003e854860dbc14916043a8e076c3d947d7
parent4cb203db9242cb477027b92d866c4dccece64d38

ir: more foolproof way to organize instruction parsing


1 files changed, 27 insertions(+), 15 deletions(-)

src-self-hosted/ir.zig+27-15
...@@ -8,16 +8,6 @@ const assert = std.debug.assert;...@@ -8,16 +8,6 @@ const assert = std.debug.assert;
8pub const Inst = struct {8pub const Inst = struct {
9 tag: Tag,9 tag: Tag,
1010
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 };
3121
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 into40 /// 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 },
4754
48 positionals: struct {},55 positionals: struct {
56 ptr: OtherInst,
57 },
49 kw_args: struct {},58 kw_args: struct {},
50 };59 };
5160
...@@ -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 }