aboutsummaryrefslogtreecommitdiff
path: root/src/parse.zig
diff options
context:
space:
mode:
authorMathias Magnusson <mathias@magnusson.space>2025-06-02 19:55:33 +0200
committerMathias Magnusson <mathias@magnusson.space>2025-06-02 19:55:33 +0200
commite06dd22930472b688d533ec7d4635f7657574ece (patch)
tree6376c4bdbda157674483ad32089b1c6162735564 /src/parse.zig
parentbb66477d1423f16c77986b48acd6156222d7d195 (diff)
downloadhuginn-e06dd22930472b688d533ec7d4635f7657574ece.tar.gz
force parenthesis around arguments
would've been cool to not force that imo, but otherwise it seems like there can be absolutely no places where two expression-like things could be next to each other, which is a kinda meh
Diffstat (limited to 'src/parse.zig')
-rw-r--r--src/parse.zig25
1 files changed, 12 insertions, 13 deletions
diff --git a/src/parse.zig b/src/parse.zig
index e240ce3..08dcc81 100644
--- a/src/parse.zig
+++ b/src/parse.zig
@@ -80,7 +80,7 @@ pub const Expr = struct {
switch (self.type) {
.integer_literal => try writer.print("{}", .{self.loc.getInt(file_source)}),
.bin_op => |bin_op| try writer.print("({} {} {})", .{ bin_op.lhs.fmt(file_source), bin_op.op, bin_op.rhs.fmt(file_source) }),
- .call => |call| try writer.print("({} {})", .{ call.proc.fmt(file_source), call.arg.fmt(file_source) }),
+ .call => |call| try writer.print("{}({})", .{ call.proc.fmt(file_source), call.arg.fmt(file_source) }),
.identifier => try writer.print("{s}", .{self.loc.getIdent(file_source)}),
}
}
@@ -121,11 +121,11 @@ pub fn statement(allocator: Allocator, lexer: *Lexer) !Stmt {
}
pub fn expression(allocator: Allocator, lexer: *Lexer) error{ OutOfMemory, ExpectedRightParen, UnexpectedToken }!*Expr {
- return addExpr(allocator, lexer);
+ return parseTerms(allocator, lexer);
}
-pub fn addExpr(allocator: Allocator, lexer: *Lexer) !*Expr {
- var lhs = try callExpr(allocator, lexer);
+pub fn parseTerms(allocator: Allocator, lexer: *Lexer) !*Expr {
+ var lhs = try parseInvocations(allocator, lexer);
while (true) {
const op: Expr.Type.BinOp.Op = switch (lexer.peek().type) {
.plus => .plus,
@@ -134,7 +134,7 @@ pub fn addExpr(allocator: Allocator, lexer: *Lexer) !*Expr {
};
_ = lexer.next();
- const rhs = try callExpr(allocator, lexer);
+ const rhs = try parseInvocations(allocator, lexer);
lhs = try allocate(Expr, allocator, .{
.loc = lhs.loc.combine(rhs.loc),
.type = .{ .bin_op = .{ .lhs = lhs, .op = op, .rhs = rhs } },
@@ -143,14 +143,13 @@ pub fn addExpr(allocator: Allocator, lexer: *Lexer) !*Expr {
return lhs;
}
-pub fn callExpr(allocator: Allocator, lexer: *Lexer) !*Expr {
- var proc = try primaryExpr(allocator, lexer);
+pub fn parseInvocations(allocator: Allocator, lexer: *Lexer) !*Expr {
+ var proc = try parsePrimaryExpr(allocator, lexer);
while (true) {
- switch (lexer.peek().type) {
- .left_paren, .integer_literal, .identifier => {},
- else => break,
- }
- const arg = try primaryExpr(allocator, lexer);
+ if (lexer.peek().type != .left_paren) break;
+ _ = lexer.next();
+ const arg = try expression(allocator, lexer);
+ _ = try mustEat(lexer, .right_paren);
proc = try allocate(Expr, allocator, .{
.loc = proc.loc.combine(arg.loc),
.type = .{ .call = .{ .proc = proc, .arg = arg } },
@@ -159,7 +158,7 @@ pub fn callExpr(allocator: Allocator, lexer: *Lexer) !*Expr {
return proc;
}
-pub fn primaryExpr(allocator: Allocator, lexer: *Lexer) !*Expr {
+pub fn parsePrimaryExpr(allocator: Allocator, lexer: *Lexer) !*Expr {
const token = lexer.next();
return allocate(Expr, allocator, switch (token.type) {
.left_paren => {