aboutsummaryrefslogtreecommitdiff
path: root/src/parse.zig
diff options
context:
space:
mode:
authorMathias Magnusson <mathias@magnusson.space>2025-07-29 18:39:46 +0200
committerMathias Magnusson <mathias@magnusson.space>2025-07-29 18:39:46 +0200
commit9f728121a17cbb997c18752d01d7529539966e94 (patch)
treec557e4fccf50832fc30a5eab190e36678e22222d /src/parse.zig
parent15984567e8187f529fbe649109ef83bba309a2d8 (diff)
downloadhuginn-9f728121a17cbb997c18752d01d7529539966e94.tar.gz
make parameters usable
Diffstat (limited to 'src/parse.zig')
-rw-r--r--src/parse.zig52
1 files changed, 29 insertions, 23 deletions
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;