| ... | @@ -219,8 +219,8 @@ fn parseOptionalType(ctx: *ParseContext) !?Type { | ... | @@ -219,8 +219,8 @@ fn parseOptionalType(ctx: *ParseContext) !?Type { |
| 219 | | 219 | |
| 220 | fn parseInstruction(ctx: *ParseContext, opt_type: ?Type) error{ OutOfMemory, ParseFailure }!*Inst { | 220 | fn parseInstruction(ctx: *ParseContext, opt_type: ?Type) error{ OutOfMemory, ParseFailure }!*Inst { |
| 221 | switch (ctx.source[ctx.i]) { | 221 | switch (ctx.source[ctx.i]) { |
| 222 | '"' => return parseStringLiteralConst(ctx), | 222 | '"' => return parseStringLiteralConst(ctx, opt_type), |
| 223 | '0'...'9' => return parseIntegerLiteralConst(ctx), | 223 | '0'...'9' => return parseIntegerLiteralConst(ctx, opt_type), |
| 224 | else => {}, | 224 | else => {}, |
| 225 | } | 225 | } |
| 226 | const fn_name = try skipToAndOver(ctx, '('); | 226 | const fn_name = try skipToAndOver(ctx, '('); |
| ... | @@ -327,7 +327,7 @@ fn parseBody(ctx: *ParseContext) !Inst.Fn.Body { | ... | @@ -327,7 +327,7 @@ fn parseBody(ctx: *ParseContext) !Inst.Fn.Body { |
| 327 | }; | 327 | }; |
| 328 | } | 328 | } |
| 329 | | 329 | |
| 330 | fn parseStringLiteralConst(ctx: *ParseContext) !*Inst { | 330 | fn parseStringLiteralConst(ctx: *ParseContext, opt_type: ?Type) !*Inst { |
| 331 | const start = ctx.i; | 331 | const start = ctx.i; |
| 332 | ctx.i += 1; // skip over '"' | 332 | ctx.i += 1; // skip over '"' |
| 333 | | 333 | |
| ... | @@ -344,17 +344,21 @@ fn parseStringLiteralConst(ctx: *ParseContext) !*Inst { | ... | @@ -344,17 +344,21 @@ fn parseStringLiteralConst(ctx: *ParseContext) !*Inst { |
| 344 | }, | 344 | }, |
| 345 | else => |e| return e, | 345 | else => |e| return e, |
| 346 | }; | 346 | }; |
| | 347 | const const_inst = try ctx.allocator.create(Inst.Constant); |
| | 348 | errdefer ctx.allocator.destroy(const_inst); |
| | 349 | |
| 347 | const bytes_payload = try ctx.allocator.create(Value.Payload.Bytes); | 350 | const bytes_payload = try ctx.allocator.create(Value.Payload.Bytes); |
| 348 | errdefer ctx.allocator.destroy(bytes_payload); | 351 | errdefer ctx.allocator.destroy(bytes_payload); |
| 349 | bytes_payload.* = .{ .data = parsed }; | 352 | bytes_payload.* = .{ .data = parsed }; |
| 350 | | 353 | |
| 351 | const ty_payload = try ctx.allocator.create(Type.Payload.Array_u8_Sentinel0); | 354 | const ty = opt_type orelse blk: { |
| 352 | errdefer ctx.allocator.destroy(ty_payload); | 355 | const ty_payload = try ctx.allocator.create(Type.Payload.Array_u8_Sentinel0); |
| 353 | ty_payload.* = .{ .len = parsed.len }; | 356 | ty_payload.* = .{ .len = parsed.len }; |
| | 357 | break :blk Type.initPayload(&ty_payload.base); |
| | 358 | }; |
| 354 | | 359 | |
| 355 | const const_inst = try ctx.allocator.create(Inst.Constant); | | |
| 356 | const_inst.* = .{ | 360 | const_inst.* = .{ |
| 357 | .ty = Type.initPayload(&ty_payload.base), | 361 | .ty = ty, |
| 358 | .positionals = .{ .value = Value.initPayload(&bytes_payload.base) }, | 362 | .positionals = .{ .value = Value.initPayload(&bytes_payload.base) }, |
| 359 | .kw_args = .{}, | 363 | .kw_args = .{}, |
| 360 | }; | 364 | }; |
| ... | @@ -370,8 +374,31 @@ fn parseStringLiteralConst(ctx: *ParseContext) !*Inst { | ... | @@ -370,8 +374,31 @@ fn parseStringLiteralConst(ctx: *ParseContext) !*Inst { |
| 370 | return parseError(ctx, "unexpected EOF in string literal", .{}); | 374 | return parseError(ctx, "unexpected EOF in string literal", .{}); |
| 371 | } | 375 | } |
| 372 | | 376 | |
| 373 | fn parseIntegerLiteralConst(ctx: *ParseContext) !*Inst { | 377 | fn parseIntegerLiteralConst(ctx: *ParseContext, opt_type: ?Type) !*Inst { |
| 374 | return parseError(ctx, "TODO parse integer literal", .{}); | 378 | const start = ctx.i; |
| | 379 | while (ctx.i < ctx.source.len) : (ctx.i += 1) switch (ctx.source[ctx.i]) { |
| | 380 | '0'...'9' => continue, |
| | 381 | else => break, |
| | 382 | }; |
| | 383 | const number_text = ctx.source[start..ctx.i]; |
| | 384 | const number = std.fmt.parseInt(u64, number_text, 10) catch |err| switch (err) { |
| | 385 | error.Overflow => return parseError(ctx, "TODO handle big integers", .{}), |
| | 386 | error.InvalidCharacter => return parseError(ctx, "invalid integer literal", .{}), |
| | 387 | }; |
| | 388 | |
| | 389 | const int_payload = try ctx.allocator.create(Value.Payload.Int_u64); |
| | 390 | errdefer ctx.allocator.destroy(int_payload); |
| | 391 | int_payload.* = .{ .int = number }; |
| | 392 | |
| | 393 | const const_inst = try ctx.allocator.create(Inst.Constant); |
| | 394 | errdefer ctx.allocator.destroy(const_inst); |
| | 395 | |
| | 396 | const_inst.* = .{ |
| | 397 | .ty = opt_type orelse Type.initTag(.int_comptime), |
| | 398 | .positionals = .{ .value = Value.initPayload(&int_payload.base) }, |
| | 399 | .kw_args = .{}, |
| | 400 | }; |
| | 401 | return &const_inst.base; |
| 375 | } | 402 | } |
| 376 | | 403 | |
| 377 | pub fn main() anyerror!void { | 404 | pub fn main() anyerror!void { |