refactor: expression parser returns position of next token

This commit is contained in:
Fernando Araoz 2025-01-27 19:45:48 -05:00
parent 5f75392d6b
commit 9374caa7ed
2 changed files with 11 additions and 10 deletions

View File

@ -10,8 +10,9 @@ pub const Expression = union(enum) {
/// Attempts to parse an expression from a token stream. /// Attempts to parse an expression from a token stream.
/// ///
/// Receives a pointer to the memory for initialization /// Receives a pointer to the memory for initialization,
pub fn init(self: *@This(), tokens: *const std.ArrayList(Token), pos: usize) ?void { /// returns the position of the next token
pub fn init(self: *@This(), tokens: *const std.ArrayList(Token), pos: usize) ?usize {
std.debug.assert(pos < tokens.items.len); std.debug.assert(pos < tokens.items.len);
const t = tokens.items[pos]; const t = tokens.items[pos];
@ -22,6 +23,7 @@ pub const Expression = union(enum) {
self.* = .{ self.* = .{
.number = &t, .number = &t,
}; };
return pos + 1;
} }
}; };

View File

@ -33,11 +33,13 @@ pub const VariableBinding = struct {
// check there is still input // check there is still input
if (pos + 1 >= tokens.items.len) { if (pos + 1 >= tokens.items.len) {
// return error // return error
// TODO: populate error information
return ParseError.Error; return ParseError.Error;
} }
// try to parse an identifier // try to parse an identifier
const identifier = if (utils.expect_token_type(lexic.TokenType.Identifier, &tokens.items[pos + 1])) |i| i else { const identifier = if (utils.expect_token_type(lexic.TokenType.Identifier, &tokens.items[pos + 1])) |i| i else {
// TODO: populate error information
return ParseError.Error; return ParseError.Error;
}; };
@ -51,14 +53,12 @@ pub const VariableBinding = struct {
// parse expression // parse expression
if (pos + 3 >= tokens.items.len) return ParseError.Error; if (pos + 3 >= tokens.items.len) return ParseError.Error;
const exp = allocator.create(expression.Expression) catch { const exp = try allocator.create(expression.Expression);
return ParseError.OutOfMemory;
};
errdefer allocator.destroy(exp); errdefer allocator.destroy(exp);
const res = exp.init(tokens, pos + 3); const next_pos = if (exp.init(tokens, pos + 3)) |x| x else {
if (res == null) { // TODO: populate error information
return ParseError.Error; return ParseError.Error;
} };
// return // return
target.* = .{ target.* = .{
@ -68,8 +68,7 @@ pub const VariableBinding = struct {
.expression = exp, .expression = exp,
.alloc = allocator, .alloc = allocator,
}; };
// TODO: when expression parses more than one token this will break. return next_pos;
return pos + 4;
} }
pub fn deinit(self: @This()) void { pub fn deinit(self: @This()) void {