diff options
author | Mathias Magnusson <mathias@magnusson.space> | 2025-05-28 23:00:32 +0200 |
---|---|---|
committer | Mathias Magnusson <mathias@magnusson.space> | 2025-05-28 23:00:32 +0200 |
commit | 7b85276fc98643b1138df6f322b8bd657339ea96 (patch) | |
tree | 3d36e1d4961f92caa0fe0e00bb8e27a0fd1242b5 /src/lexer.zig | |
download | huginn-7b85276fc98643b1138df6f322b8bd657339ea96.tar.gz |
initial commit
Diffstat (limited to 'src/lexer.zig')
-rw-r--r-- | src/lexer.zig | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/lexer.zig b/src/lexer.zig new file mode 100644 index 0000000..93ed6cc --- /dev/null +++ b/src/lexer.zig @@ -0,0 +1,66 @@ +pub const Token = struct { + start: usize, + end: usize, + type: Type, + + pub const Type = union(enum) { + LeftParen, + RightParen, + IntegerLiteral: usize, + Plus, + Invalid, + Eof, + }; +}; + +source: []const u8, +last_end: usize = 0, +pos: usize = 0, + +pub fn next(self: *Self) ?Token { + return s: switch (self.eat() orelse return self.create(.Eof)) { + '(' => self.create(.LeftParen), + ')' => self.create(.RightParen), + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' => |d| self.integerLiteral(d), + '+' => self.create(.Plus), + ' ' => { + self.last_end = self.pos; + continue :s (self.eat() orelse return self.create(.Eof)); + }, + else => self.create(.Invalid), + }; +} + +fn integerLiteral(self: *Self, first: u8) Token { + var value: usize = @intCast(digitValue(first).?); + while (digitValue(self.peek())) |d| { + _ = self.eat(); + value = value *| 10 +| d; + } + return self.create(.{ .IntegerLiteral = value }); +} + +fn create(self: *Self, tajp: Token.Type) Token { + const start = self.last_end; + self.last_end = self.pos; + return .{ .start = start, .end = self.pos, .type = tajp }; +} + +fn eat(self: *Self) ?u8 { + const token = self.peek(); + if (token != null) self.pos += 1; + return token; +} + +fn peek(self: *Self) ?u8 { + return if (self.pos < self.source.len) self.source[self.pos] else null; +} + +const Self = @This(); + +fn digitValue(c: ?u8) ?u8 { + return switch (c orelse return null) { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' => c.? - '0', + else => null, + }; +} |