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;
88pub const Inst = struct {
99 tag: Tag,
1010
11 pub const all_types = .{
12 Constant,
13 PtrToInt,
14 FieldPtr,
15 Deref,
16 Assembly,
17 Unreach,
18 Fn,
19 };
20
2111 /// These names are used for the IR text format.
2212 pub const Tag = enum {
2313 constant,
......@@ -29,6 +19,23 @@ pub const Inst = struct {
2919 @"fn",
3020 };
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
3239 /// This struct owns the `Value` memory. When the struct is deallocated,
3340 /// so is the `Value`. The value of a constant must be copied into
3441 /// a memory location for the value to survive after a const instruction.
......@@ -45,7 +52,9 @@ pub const Inst = struct {
4552 pub const PtrToInt = struct {
4653 base: Inst = Inst{ .tag = .ptrtoint },
4754
48 positionals: struct {},
55 positionals: struct {
56 ptr: OtherInst,
57 },
4958 kw_args: struct {},
5059 };
5160
......@@ -224,10 +233,10 @@ fn parseInstruction(ctx: *ParseContext, opt_type: ?Type) error{ OutOfMemory, Par
224233 else => {},
225234 }
226235 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);
231240 }
232241 }
233242 return parseError(ctx, "unknown instruction '{}'", .{fn_name});
......@@ -288,6 +297,9 @@ fn parseParameterGeneric(ctx: *ParseContext, comptime T: type) !T {
288297 }
289298 switch (T) {
290299 Inst.Fn.Body => return parseBody(ctx),
300 Inst.OtherInst => {
301 return parseError(ctx, "TODO implement parseParameterGeneric for OtherInst", .{});
302 },
291303 Value => return parseError(ctx, "TODO implement parseParameterGeneric for type Value", .{}),
292304 else => @compileError("Unimplemented: ir parseParameterGeneric for type " ++ @typeName(T)),
293305 }