| ... | ... | @@ -150,7 +150,7 @@ pub fn parseRoot(ctx: *ParseContext) !void { |
| 150 | 150 | while (ctx.i < ctx.source.len) : (ctx.i += 1) switch (ctx.source[ctx.i]) { |
| 151 | 151 | ';' => _ = try skipToAndOver(ctx, '\n'), |
| 152 | 152 | '@' => { |
| 153 | | const at_start = ctx.i; |
| 153 | ctx.i += 1; |
| 154 | 154 | const ident = try skipToAndOver(ctx, ' '); |
| 155 | 155 | const opt_type = try parseOptionalType(ctx); |
| 156 | 156 | const inst = try parseInstruction(ctx, opt_type); |
| ... | ... | @@ -298,7 +298,24 @@ fn parseParameterGeneric(ctx: *ParseContext, comptime T: type) !T { |
| 298 | 298 | switch (T) { |
| 299 | 299 | Inst.Fn.Body => return parseBody(ctx), |
| 300 | 300 | Inst.OtherInst => { |
| 301 | | return parseError(ctx, "TODO implement parseParameterGeneric for OtherInst", .{}); |
| 301 | const map = switch (ctx.source[ctx.i]) { |
| 302 | '@' => ctx.global_name_map, |
| 303 | '%' => return parseError(ctx, "TODO implement OtherInst for %", .{}), |
| 304 | else => |byte| return parseError(ctx, "unexpected byte: '{c}'", .{byte}), |
| 305 | }; |
| 306 | ctx.i += 1; |
| 307 | const name_start = ctx.i; |
| 308 | while (ctx.i < ctx.source.len) : (ctx.i += 1) switch (ctx.source[ctx.i]) { |
| 309 | ';', ' ', '\n', ',', ')' => break, |
| 310 | else => continue, |
| 311 | }; |
| 312 | const ident = ctx.source[name_start..ctx.i]; |
| 313 | const kv = map.get(ident) orelse { |
| 314 | const bad_name = ctx.source[name_start - 1 .. ctx.i]; |
| 315 | ctx.i = name_start - 1; |
| 316 | return parseError(ctx, "unrecognized identifier: {}", .{bad_name}); |
| 317 | }; |
| 318 | return Inst.OtherInst{ .index = kv.value }; |
| 302 | 319 | }, |
| 303 | 320 | Value => return parseError(ctx, "TODO implement parseParameterGeneric for type Value", .{}), |
| 304 | 321 | else => @compileError("Unimplemented: ir parseParameterGeneric for type " ++ @typeName(T)), |
| ... | ... | @@ -319,7 +336,7 @@ fn parseBody(ctx: *ParseContext) !Inst.Fn.Body { |
| 319 | 336 | while (ctx.i < ctx.source.len) : (ctx.i += 1) switch (ctx.source[ctx.i]) { |
| 320 | 337 | ';' => _ = try skipToAndOver(ctx, '\n'), |
| 321 | 338 | '%' => { |
| 322 | | const at_start = ctx.i; |
| 339 | ctx.i += 1; |
| 323 | 340 | const ident = try skipToAndOver(ctx, ' '); |
| 324 | 341 | const opt_type = try parseOptionalType(ctx); |
| 325 | 342 | const inst = try parseInstruction(ctx, opt_type); |
| ... | ... | @@ -452,3 +469,6 @@ fn findLineColumn(source: []const u8, byte_offset: usize) struct { line: usize, |
| 452 | 469 | } |
| 453 | 470 | return .{ .line = line, .column = column }; |
| 454 | 471 | } |
| 472 | |
| 473 | // Performance optimization ideas: |
| 474 | // * make the source code sentinel-terminated, so that all the checks against the length can be skipped |