aboutsummaryrefslogtreecommitdiff
path: root/src/Lexer.zig
diff options
context:
space:
mode:
authorMathias Magnusson <mathias@magnusson.space>2025-06-02 15:01:58 +0200
committerMathias Magnusson <mathias@magnusson.space>2025-06-02 15:16:20 +0200
commit939ee7606fbfe3afa6b6a008fb617120a6dd8114 (patch)
tree2bd55979cd3f4531ef83090b99ba296ec7db82c8 /src/Lexer.zig
parentef18ba588a4b1531c8b42cbfc996ef6f60de1d97 (diff)
downloadhuginn-939ee7606fbfe3afa6b6a008fb617120a6dd8114.tar.gz
make Lexer peekable without a wrapper
Diffstat (limited to 'src/Lexer.zig')
-rw-r--r--src/Lexer.zig38
1 files changed, 26 insertions, 12 deletions
diff --git a/src/Lexer.zig b/src/Lexer.zig
index 62b2352..8c23b26 100644
--- a/src/Lexer.zig
+++ b/src/Lexer.zig
@@ -44,13 +44,27 @@ pub const Location = struct {
}
};
+pub fn peek(self: *Self) Token {
+ if (self.peeked == null) {
+ self.peeked = self.getNext();
+ }
+ return self.peeked.?;
+}
+
+pub fn next(self: *Self) Token {
+ const token = self.peek();
+ self.peeked = null;
+ return token;
+}
+
source: []const u8,
start: usize = 0,
pos: usize = 0,
+peeked: ?Token = null,
-pub fn next(self: *Self) ?Token {
+fn getNext(self: *Self) Token {
self.start = self.pos;
- return s: switch (self.eat() orelse return self.create(.eof)) {
+ return s: switch (self.eatChar() orelse return self.create(.eof)) {
'(' => self.create(.left_paren),
')' => self.create(.right_paren),
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9' => self.integerLiteral(),
@@ -58,7 +72,7 @@ pub fn next(self: *Self) ?Token {
'-' => self.create(.minus),
' ' => {
self.start = self.pos;
- continue :s (self.eat() orelse return self.create(.eof));
+ continue :s (self.eatChar() orelse return self.create(.eof));
},
else => |c| if ('a' <= c and c <= 'z' or 'A' <= c and c <= 'Z')
self.identifierOrKeyword()
@@ -69,7 +83,7 @@ pub fn next(self: *Self) ?Token {
fn integerLiteral(self: *Self) Token {
var value: ?u64 = self.source[self.start] - '0';
- while (digitValue(self.peek())) |v| {
+ while (digitValue(self.peekChar())) |v| {
var nxt: ?u64 = null;
if (value) |val|
if (std.math.mul(u64, val, 10) catch null) |p|
@@ -78,7 +92,7 @@ fn integerLiteral(self: *Self) Token {
};
value = nxt;
- _ = self.eat();
+ _ = self.eatChar();
}
return if (value != null)
self.create(.integer_literal)
@@ -88,9 +102,9 @@ fn integerLiteral(self: *Self) Token {
fn identifierOrKeyword(self: *Self) Token {
while (true) {
- const c = self.peek() orelse 0;
+ const c = self.peekChar() orelse 0;
if ('a' <= c and c <= 'z' or 'A' <= c and c <= 'Z' or c == '_') {
- _ = self.eat();
+ _ = self.eatChar();
continue;
}
const value = self.source[self.start..self.pos];
@@ -101,18 +115,18 @@ fn identifierOrKeyword(self: *Self) Token {
}
}
-fn create(self: *Self, tajp: Token.Type) Token {
+fn create(self: *Self, ty: Token.Type) Token {
const start = self.start;
- return .{ .loc = .{ .start = start, .end = self.pos }, .type = tajp };
+ return .{ .loc = .{ .start = start, .end = self.pos }, .type = ty };
}
-fn eat(self: *Self) ?u8 {
- const token = self.peek();
+fn eatChar(self: *Self) ?u8 {
+ const token = self.peekChar();
if (token != null) self.pos += 1;
return token;
}
-fn peek(self: *Self) ?u8 {
+fn peekChar(self: *Self) ?u8 {
return if (self.pos < self.source.len) self.source[self.pos] else null;
}