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