diff options
Diffstat (limited to 'src/Lexer.zig')
-rw-r--r-- | src/Lexer.zig | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/src/Lexer.zig b/src/Lexer.zig index 3621a1c..62b2352 100644 --- a/src/Lexer.zig +++ b/src/Lexer.zig @@ -12,6 +12,10 @@ pub const Token = struct { minus, invalid, eof, + identifier, + + // Keywords + @"if", }; }; @@ -33,6 +37,11 @@ pub const Location = struct { } return value; } + + /// Assumes that the location comes directly from an `identifier` token. + pub fn getIdent(self: Location, file_source: []const u8) []const u8 { + return file_source[self.start..self.end]; + } }; source: []const u8, @@ -51,7 +60,10 @@ pub fn next(self: *Self) ?Token { self.start = self.pos; continue :s (self.eat() orelse return self.create(.eof)); }, - else => self.create(.invalid), + else => |c| if ('a' <= c and c <= 'z' or 'A' <= c and c <= 'Z') + self.identifierOrKeyword() + else + self.create(.invalid), }; } @@ -74,6 +86,21 @@ fn integerLiteral(self: *Self) Token { self.create(.invalid); } +fn identifierOrKeyword(self: *Self) Token { + while (true) { + const c = self.peek() orelse 0; + if ('a' <= c and c <= 'z' or 'A' <= c and c <= 'Z' or c == '_') { + _ = self.eat(); + continue; + } + const value = self.source[self.start..self.pos]; + return self.create(switch (std.meta.stringToEnum(Token.Type, value) orelse .invalid) { + .@"if" => .@"if", + else => .identifier, + }); + } +} + fn create(self: *Self, tajp: Token.Type) Token { const start = self.start; return .{ .loc = .{ .start = start, .end = self.pos }, .type = tajp }; |