fix precedence
This commit is contained in:
parent
b193b80e40
commit
3ad4054176
|
|
@ -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 };
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue