ir: more foolproof way to organize instruction parsing
parent
4cb203db92
commit
49e2f3ca36
|
@ -8,16 +8,6 @@ const assert = std.debug.assert;
|
||||||
pub const Inst = struct {
|
pub const Inst = struct {
|
||||||
tag: Tag,
|
tag: Tag,
|
||||||
|
|
||||||
pub const all_types = .{
|
|
||||||
Constant,
|
|
||||||
PtrToInt,
|
|
||||||
FieldPtr,
|
|
||||||
Deref,
|
|
||||||
Assembly,
|
|
||||||
Unreach,
|
|
||||||
Fn,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// These names are used for the IR text format.
|
/// These names are used for the IR text format.
|
||||||
pub const Tag = enum {
|
pub const Tag = enum {
|
||||||
constant,
|
constant,
|
||||||
|
@ -29,6 +19,23 @@ pub const Inst = struct {
|
||||||
@"fn",
|
@"fn",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub fn TagToType(tag: Tag) type {
|
||||||
|
return switch (tag) {
|
||||||
|
.constant => Constant,
|
||||||
|
.ptrtoint => PtrToInt,
|
||||||
|
.fieldptr => FieldPtr,
|
||||||
|
.deref => Deref,
|
||||||
|
.@"asm" => Assembly,
|
||||||
|
.unreach => Unreach,
|
||||||
|
.@"fn" => Fn,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents a reference to another instruction.
|
||||||
|
pub const OtherInst = struct {
|
||||||
|
index: usize,
|
||||||
|
};
|
||||||
|
|
||||||
/// This struct owns the `Value` memory. When the struct is deallocated,
|
/// This struct owns the `Value` memory. When the struct is deallocated,
|
||||||
/// so is the `Value`. The value of a constant must be copied into
|
/// so is the `Value`. The value of a constant must be copied into
|
||||||
/// a memory location for the value to survive after a const instruction.
|
/// a memory location for the value to survive after a const instruction.
|
||||||
|
@ -45,7 +52,9 @@ pub const Inst = struct {
|
||||||
pub const PtrToInt = struct {
|
pub const PtrToInt = struct {
|
||||||
base: Inst = Inst{ .tag = .ptrtoint },
|
base: Inst = Inst{ .tag = .ptrtoint },
|
||||||
|
|
||||||
positionals: struct {},
|
positionals: struct {
|
||||||
|
ptr: OtherInst,
|
||||||
|
},
|
||||||
kw_args: struct {},
|
kw_args: struct {},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -224,10 +233,10 @@ fn parseInstruction(ctx: *ParseContext, opt_type: ?Type) error{ OutOfMemory, Par
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
const fn_name = try skipToAndOver(ctx, '(');
|
const fn_name = try skipToAndOver(ctx, '(');
|
||||||
inline for (Inst.all_types) |InstType| {
|
inline for (@typeInfo(Inst.Tag).Enum.fields) |field| {
|
||||||
const this_name = @tagName(std.meta.fieldInfo(InstType, "base").default_value.?.tag);
|
if (mem.eql(u8, field.name, fn_name)) {
|
||||||
if (mem.eql(u8, this_name, fn_name)) {
|
const tag = @field(Inst.Tag, field.name);
|
||||||
return parseInstructionGeneric(ctx, this_name, InstType, opt_type);
|
return parseInstructionGeneric(ctx, field.name, Inst.TagToType(tag), opt_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return parseError(ctx, "unknown instruction '{}'", .{fn_name});
|
return parseError(ctx, "unknown instruction '{}'", .{fn_name});
|
||||||
|
@ -288,6 +297,9 @@ fn parseParameterGeneric(ctx: *ParseContext, comptime T: type) !T {
|
||||||
}
|
}
|
||||||
switch (T) {
|
switch (T) {
|
||||||
Inst.Fn.Body => return parseBody(ctx),
|
Inst.Fn.Body => return parseBody(ctx),
|
||||||
|
Inst.OtherInst => {
|
||||||
|
return parseError(ctx, "TODO implement parseParameterGeneric for OtherInst", .{});
|
||||||
|
},
|
||||||
Value => return parseError(ctx, "TODO implement parseParameterGeneric for type Value", .{}),
|
Value => return parseError(ctx, "TODO implement parseParameterGeneric for type Value", .{}),
|
||||||
else => @compileError("Unimplemented: ir parseParameterGeneric for type " ++ @typeName(T)),
|
else => @compileError("Unimplemented: ir parseParameterGeneric for type " ++ @typeName(T)),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue