From 9f728121a17cbb997c18752d01d7529539966e94 Mon Sep 17 00:00:00 2001 From: Mathias Magnusson Date: Tue, 29 Jul 2025 18:39:46 +0200 Subject: make parameters usable --- src/parse.zig | 52 +++++++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 23 deletions(-) (limited to 'src/parse.zig') diff --git a/src/parse.zig b/src/parse.zig index 451b050..1aa5d07 100644 --- a/src/parse.zig +++ b/src/parse.zig @@ -3,7 +3,8 @@ const Allocator = std.mem.Allocator; const root = @import("root"); const Lexer = root.Lexer; -const Token = root.Lexer.Token; +const Token = Lexer.Token; +const Location = Lexer.Location; fn Fmt(T: type) type { return std.fmt.Formatter(struct { @@ -27,7 +28,7 @@ pub const File = struct { decls: []Decl, const Decl = struct { - loc: Lexer.Location, + loc: Location, inner: Stmt.Type.AssignVar, }; @@ -44,7 +45,7 @@ pub const File = struct { }; pub const Block = struct { - loc: Lexer.Location, + loc: Location, stmts: []Stmt, fn format(self: Block, writer: anytype, source: []const u8, indent: usize) !void { @@ -58,7 +59,7 @@ pub const Block = struct { }; pub const Stmt = struct { - loc: Lexer.Location, + loc: Location, type: Type, pub const Type = union(enum) { @@ -68,7 +69,7 @@ pub const Stmt = struct { @"while": While, pub const AssignVar = struct { - ident: Lexer.Location, + ident: Location, is_decl: bool, value: *const Expr, }; @@ -98,7 +99,7 @@ pub const Stmt = struct { }; pub const Expr = struct { - loc: Lexer.Location, + loc: Location, type: Type, pub const Type = union(enum) { @@ -148,6 +149,7 @@ pub const Expr = struct { pub const Proc = struct { body: Block, + param: ?Location, }; }; @@ -183,7 +185,6 @@ const ParseError = error{ UnexpectedToken, InvalidAssignTarget, ExprStatementMustBeCall, - ExpectedCOmmaOrIdentifier, }; pub fn file(allocator: Allocator, lexer: *Lexer) !File { @@ -274,24 +275,18 @@ fn parseProc(allocator: Allocator, lexer: *Lexer) ParseError!*Expr { if (lexer.peek().type != .proc) return parseComparisons(allocator, lexer); const proc = try mustEat(lexer, .proc); _ = try mustEat(lexer, .left_paren); - var params: std.ArrayList(Lexer.Location) = .init(allocator); - while (true) { - const tok = lexer.next(); - switch (tok.type) { - .right_paren => break, - .identifier => { - try params.append(tok.loc); - if (lexer.peek().type == .right_paren) continue; - _ = try mustEat(lexer, .comma); - }, - else => return error.ExpectedCOmmaOrIdentifier, - } - } + const param_tok = lexer.next(); + const param: ?Location = switch (param_tok.type) { + .identifier => param_tok.loc, + .right_paren => null, + else => |ty| return expected(&.{ .identifier, .right_paren }, ty), + }; + if (param != null) _ = try mustEat(lexer, .right_paren); const body = try parseBlock(allocator, lexer); return allocate(Expr, allocator, .{ .loc = proc.loc.combine(body.loc), - .type = .{ .proc = .{ .body = body } }, + .type = .{ .proc = .{ .body = body, .param = param } }, }); } @@ -390,10 +385,21 @@ fn parsePrimaryExpr(allocator: Allocator, lexer: *Lexer) !*Expr { }); } -fn mustEat(lexer: *Lexer, ty: Lexer.Token.Type) !Lexer.Token { +fn expected(one_of: []const Token.Type, got: Token.Type) error{UnexpectedToken} { + for (one_of) |ty| + std.debug.assert(ty != got); + std.debug.print("Expected ", .{}); + for (0.., one_of) |i, ty| { + std.debug.print("{s}{s}", .{ if (i == 0) "" else " or ", @tagName(ty) }); + } + std.debug.print(". Got {s}.\n", .{@tagName(got)}); + return error.UnexpectedToken; +} + +fn mustEat(lexer: *Lexer, ty: Token.Type) !Token { const token = lexer.next(); if (token.type != ty) { - std.debug.print("Expected {}. Got {}\n", .{ ty, token.type }); + std.debug.print("Expected {s}. Got {s} at {}.\n", .{ @tagName(ty), @tagName(token.type), token.loc }); return error.UnexpectedToken; } return token; -- cgit v1.2.3