From 3ad4054176409337d22b34c18ea7ed8387e939ea Mon Sep 17 00:00:00 2001 From: caandt Date: Sun, 8 Jun 2025 11:59:07 -0500 Subject: [PATCH] fix precedence --- src/frontend/parse.zig | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/frontend/parse.zig b/src/frontend/parse.zig index a3cf53b..1524b42 100644 --- a/src/frontend/parse.zig +++ b/src/frontend/parse.zig @@ -45,7 +45,8 @@ fn no_infix(_: *Parser, _: u32, _: *const Expr, _: Token) Error!*const Expr { return Error.InvalidOp; } pub const Operator = struct { - precedence: u32 = 0, + prefix_precedence: u32 = 0, + infix_precedence: u32 = 0, parse_prefix: *const fn (*Parser, u32, Token) Error!*const Expr = no_prefix, parse_infix: *const fn (*Parser, u32, *const Expr, Token) Error!*const Expr = no_infix, }; @@ -80,13 +81,13 @@ pub const Parser = struct { fn parse_expr(self: *Parser, precedence: u32) Error!*const Expr { const tok = self.tokenizer.next(); const prefix = self.ops.get(tok.kind) orelse return Error.InvalidOp; - var left = try prefix.parse_prefix(self, prefix.precedence, tok); + var left = try prefix.parse_prefix(self, prefix.prefix_precedence, tok); var infix: Operator = undefined; while (w: { infix = self.ops.get(self.tokenizer.peek().kind) orelse break :w false; - break :w infix.precedence > precedence; + break :w infix.infix_precedence > precedence; }) { - left = try infix.parse_infix(self, infix.precedence, left, self.tokenizer.next()); + left = try infix.parse_infix(self, infix.infix_precedence, left, self.tokenizer.next()); } return left; } @@ -95,15 +96,17 @@ pub const Parser = struct { ptr.* = try expr; return ptr; } - fn register_unop(self: *Parser, op: []const u8, precedence: u32) !void { - const op_p = try self.ops.getOrPutValue(op_kind(op), .{ .precedence = precedence }); + fn register_unop(self: *Parser, op: []const u8, precedence: u32) Error!void { + const op_p = try self.ops.getOrPutValue(op_kind(op), .{}); op_p.value_ptr.parse_prefix = prefix_unop; + op_p.value_ptr.prefix_precedence = precedence; } - fn register_binop(self: *Parser, op: []const u8, precedence: u32) !void { - const op_p = try self.ops.getOrPutValue(op_kind(op), .{ .precedence = precedence }); + fn register_binop(self: *Parser, op: []const u8, precedence: u32) Error!void { + const op_p = try self.ops.getOrPutValue(op_kind(op), .{}); op_p.value_ptr.parse_infix = infix_binop; + op_p.value_ptr.infix_precedence = precedence; } - pub fn init(allocator: std.mem.Allocator) !Parser { + pub fn init(allocator: std.mem.Allocator) Error!Parser { const ops = std.AutoHashMap(TokenKind, Operator).init(allocator); var p = Parser{ .tokenizer = undefined, .allocator = allocator, .ops = ops };