ir: parse string literals as parameters

master
Andrew Kelley 2020-04-19 01:06:15 -04:00
parent bd37c8d8ed
commit 730dd887e4
1 changed files with 18 additions and 12 deletions

View File

@ -31,11 +31,6 @@ pub const Inst = struct {
}; };
} }
/// 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.
@ -53,7 +48,7 @@ pub const Inst = struct {
base: Inst = Inst{ .tag = .ptrtoint }, base: Inst = Inst{ .tag = .ptrtoint },
positionals: struct { positionals: struct {
ptr: OtherInst, ptr: *Inst,
}, },
kw_args: struct {}, kw_args: struct {},
}; };
@ -61,7 +56,10 @@ pub const Inst = struct {
pub const FieldPtr = struct { pub const FieldPtr = struct {
base: Inst = Inst{ .tag = .fieldptr }, base: Inst = Inst{ .tag = .fieldptr },
positionals: struct {}, positionals: struct {
object_ptr: *Inst,
field_name: *Inst,
},
kw_args: struct {}, kw_args: struct {},
}; };
@ -257,8 +255,15 @@ fn parseInstructionGeneric(
} }
const Positionals = @TypeOf(inst_specific.positionals); const Positionals = @TypeOf(inst_specific.positionals);
inline for (@typeInfo(Positionals).Struct.fields) |arg_field| { inline for (@typeInfo(Positionals).Struct.fields) |arg_field, i| {
if (ctx.source[ctx.i] == ',') {
ctx.i += 1;
skipSpace(ctx);
} else if (ctx.source[ctx.i] == ')') {
return parseError(ctx, "expected positional parameter '{}'", .{arg_field.name});
}
@field(inst_specific.positionals, arg_field.name) = try parseParameterGeneric(ctx, arg_field.field_type); @field(inst_specific.positionals, arg_field.name) = try parseParameterGeneric(ctx, arg_field.field_type);
skipSpace(ctx);
} }
const KW_Args = @TypeOf(inst_specific.kw_args); const KW_Args = @TypeOf(inst_specific.kw_args);
@ -297,16 +302,17 @@ 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 => { *Inst => {
const map = switch (ctx.source[ctx.i]) { const map = switch (ctx.source[ctx.i]) {
'@' => ctx.global_name_map, '@' => ctx.global_name_map,
'%' => return parseError(ctx, "TODO implement OtherInst for %", .{}), '%' => return parseError(ctx, "TODO implement parsing % parameter", .{}),
'"' => return parseStringLiteralConst(ctx, null),
else => |byte| return parseError(ctx, "unexpected byte: '{c}'", .{byte}), else => |byte| return parseError(ctx, "unexpected byte: '{c}'", .{byte}),
}; };
ctx.i += 1; ctx.i += 1;
const name_start = ctx.i; const name_start = ctx.i;
while (ctx.i < ctx.source.len) : (ctx.i += 1) switch (ctx.source[ctx.i]) { while (ctx.i < ctx.source.len) : (ctx.i += 1) switch (ctx.source[ctx.i]) {
';', ' ', '\n', ',', ')' => break, ' ', '\n', ',', ')' => break,
else => continue, else => continue,
}; };
const ident = ctx.source[name_start..ctx.i]; const ident = ctx.source[name_start..ctx.i];
@ -315,7 +321,7 @@ fn parseParameterGeneric(ctx: *ParseContext, comptime T: type) !T {
ctx.i = name_start - 1; ctx.i = name_start - 1;
return parseError(ctx, "unrecognized identifier: {}", .{bad_name}); return parseError(ctx, "unrecognized identifier: {}", .{bad_name});
}; };
return Inst.OtherInst{ .index = kv.value }; return ctx.decls.items[kv.value];
}, },
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)),