aboutsummaryrefslogtreecommitdiff
path: root/src/parse.zig
diff options
context:
space:
mode:
authorMathias Magnusson <mathias@magnusson.space>2025-06-01 02:32:13 +0200
committerMathias Magnusson <mathias@magnusson.space>2025-06-01 02:32:13 +0200
commit546bb5cb935832791a280d1561620cf7a7a64842 (patch)
tree8c9439fdc4728a93380f93914605b890b8e4806a /src/parse.zig
parenta49805b7a8a9fc05df34f14cb8b6892c723e2a61 (diff)
downloadhuginn-546bb5cb935832791a280d1561620cf7a7a64842.tar.gz
add identifiers, procedure calls and a built in print procedure
Diffstat (limited to 'src/parse.zig')
-rw-r--r--src/parse.zig30
1 files changed, 28 insertions, 2 deletions
diff --git a/src/parse.zig b/src/parse.zig
index 7daa3f8..d5d3e9b 100644
--- a/src/parse.zig
+++ b/src/parse.zig
@@ -15,6 +15,8 @@ pub const Expr = struct {
integer_literal,
bin_op: BinOp,
invalid: Token,
+ call: Call,
+ identifier,
pub const BinOp = struct {
lhs: *const Expr,
@@ -35,6 +37,11 @@ pub const Expr = struct {
}
};
};
+
+ pub const Call = struct {
+ proc: *const Expr,
+ arg: *const Expr,
+ };
};
pub fn format(self: Expr, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
@@ -44,6 +51,8 @@ pub const Expr = struct {
.integer_literal => try writer.print("<int>", .{}),
.bin_op => |bin_op| try writer.print("({} {} {})", .{ bin_op.lhs, bin_op.op, bin_op.rhs }),
.invalid => try writer.print("<invalid>", .{}),
+ .call => |call| try writer.print("({} {})", .{ call.proc, call.arg }),
+ .identifier => try writer.print("<identifier>", .{}),
}
}
};
@@ -53,7 +62,7 @@ pub fn expression(allocator: Allocator, lexer: *Peekable(Lexer)) error{OutOfMemo
}
pub fn addExpr(allocator: Allocator, lexer: *Peekable(Lexer)) !*Expr {
- var lhs = try primaryExpr(allocator, lexer);
+ var lhs = try callExpr(allocator, lexer);
while (true) {
const token: Lexer.Token = if (lexer.peek()) |t| t else break;
const op: Expr.Type.BinOp.Op = switch (token.type) {
@@ -64,7 +73,7 @@ pub fn addExpr(allocator: Allocator, lexer: *Peekable(Lexer)) !*Expr {
_ = lexer.next();
- const rhs = try primaryExpr(allocator, lexer);
+ const rhs = try callExpr(allocator, lexer);
lhs = try allocate(allocator, .{
.loc = lhs.loc.combine(rhs.loc),
.type = .{ .bin_op = .{ .lhs = lhs, .op = op, .rhs = rhs } },
@@ -73,6 +82,22 @@ pub fn addExpr(allocator: Allocator, lexer: *Peekable(Lexer)) !*Expr {
return lhs;
}
+pub fn callExpr(allocator: Allocator, lexer: *Peekable(Lexer)) !*Expr {
+ var proc = try primaryExpr(allocator, lexer);
+ while (true) {
+ switch (lexer.peek().?.type) {
+ .left_paren, .integer_literal => {},
+ else => break,
+ }
+ const arg = try primaryExpr(allocator, lexer);
+ proc = try allocate(allocator, .{
+ .loc = proc.loc.combine(arg.loc),
+ .type = .{ .call = .{ .proc = proc, .arg = arg } },
+ });
+ }
+ return proc;
+}
+
pub fn primaryExpr(allocator: Allocator, lexer: *Peekable(Lexer)) !*Expr {
const token = lexer.next().?;
// std.debug.print("term {}\n", .{token});
@@ -88,6 +113,7 @@ pub fn primaryExpr(allocator: Allocator, lexer: *Peekable(Lexer)) !*Expr {
return res;
},
.integer_literal => .{ .loc = token.loc, .type = .integer_literal },
+ .identifier => .{ .loc = token.loc, .type = .identifier },
else => .{ .loc = token.loc, .type = .{ .invalid = token } },
});
}