| ... | ... | @@ -31,11 +31,6 @@ pub const Inst = struct { |
| 31 | 31 | }; |
| 32 | 32 | } |
| 33 | 33 | |
| 34 | | /// Represents a reference to another instruction. |
| 35 | | pub const OtherInst = struct { |
| 36 | | index: usize, |
| 37 | | }; |
| 38 | | |
| 39 | 34 | /// This struct owns the `Value` memory. When the struct is deallocated, |
| 40 | 35 | /// so is the `Value`. The value of a constant must be copied into |
| 41 | 36 | /// a memory location for the value to survive after a const instruction. |
| ... | ... | @@ -53,7 +48,7 @@ pub const Inst = struct { |
| 53 | 48 | base: Inst = Inst{ .tag = .ptrtoint }, |
| 54 | 49 | |
| 55 | 50 | positionals: struct { |
| 56 | | ptr: OtherInst, |
| 51 | ptr: *Inst, |
| 57 | 52 | }, |
| 58 | 53 | kw_args: struct {}, |
| 59 | 54 | }; |
| ... | ... | @@ -61,7 +56,10 @@ pub const Inst = struct { |
| 61 | 56 | pub const FieldPtr = struct { |
| 62 | 57 | base: Inst = Inst{ .tag = .fieldptr }, |
| 63 | 58 | |
| 64 | | positionals: struct {}, |
| 59 | positionals: struct { |
| 60 | object_ptr: *Inst, |
| 61 | field_name: *Inst, |
| 62 | }, |
| 65 | 63 | kw_args: struct {}, |
| 66 | 64 | }; |
| 67 | 65 | |
| ... | ... | @@ -257,8 +255,15 @@ fn parseInstructionGeneric( |
| 257 | 255 | } |
| 258 | 256 | |
| 259 | 257 | const Positionals = @TypeOf(inst_specific.positionals); |
| 260 | | inline for (@typeInfo(Positionals).Struct.fields) |arg_field| { |
| 258 | inline for (@typeInfo(Positionals).Struct.fields) |arg_field, i| { |
| 259 | if (ctx.source[ctx.i] == ',') { |
| 260 | ctx.i += 1; |
| 261 | skipSpace(ctx); |
| 262 | } else if (ctx.source[ctx.i] == ')') { |
| 263 | return parseError(ctx, "expected positional parameter '{}'", .{arg_field.name}); |
| 264 | } |
| 261 | 265 | @field(inst_specific.positionals, arg_field.name) = try parseParameterGeneric(ctx, arg_field.field_type); |
| 266 | skipSpace(ctx); |
| 262 | 267 | } |
| 263 | 268 | |
| 264 | 269 | const KW_Args = @TypeOf(inst_specific.kw_args); |
| ... | ... | @@ -297,16 +302,17 @@ fn parseParameterGeneric(ctx: *ParseContext, comptime T: type) !T { |
| 297 | 302 | } |
| 298 | 303 | switch (T) { |
| 299 | 304 | Inst.Fn.Body => return parseBody(ctx), |
| 300 | | Inst.OtherInst => { |
| 305 | *Inst => { |
| 301 | 306 | const map = switch (ctx.source[ctx.i]) { |
| 302 | 307 | '@' => ctx.global_name_map, |
| 303 | | '%' => return parseError(ctx, "TODO implement OtherInst for %", .{}), |
| 308 | '%' => return parseError(ctx, "TODO implement parsing % parameter", .{}), |
| 309 | '"' => return parseStringLiteralConst(ctx, null), |
| 304 | 310 | else => |byte| return parseError(ctx, "unexpected byte: '{c}'", .{byte}), |
| 305 | 311 | }; |
| 306 | 312 | ctx.i += 1; |
| 307 | 313 | const name_start = ctx.i; |
| 308 | 314 | while (ctx.i < ctx.source.len) : (ctx.i += 1) switch (ctx.source[ctx.i]) { |
| 309 | | ';', ' ', '\n', ',', ')' => break, |
| 315 | ' ', '\n', ',', ')' => break, |
| 310 | 316 | else => continue, |
| 311 | 317 | }; |
| 312 | 318 | const ident = ctx.source[name_start..ctx.i]; |
| ... | ... | @@ -315,7 +321,7 @@ fn parseParameterGeneric(ctx: *ParseContext, comptime T: type) !T { |
| 315 | 321 | ctx.i = name_start - 1; |
| 316 | 322 | return parseError(ctx, "unrecognized identifier: {}", .{bad_name}); |
| 317 | 323 | }; |
| 318 | | return Inst.OtherInst{ .index = kv.value }; |
| 324 | return ctx.decls.items[kv.value]; |
| 319 | 325 | }, |
| 320 | 326 | Value => return parseError(ctx, "TODO implement parseParameterGeneric for type Value", .{}), |
| 321 | 327 | else => @compileError("Unimplemented: ir parseParameterGeneric for type " ++ @typeName(T)), |