diff options
Diffstat (limited to 'src/parse.zig')
-rw-r--r-- | src/parse.zig | 30 |
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 } }, }); } |