aboutsummaryrefslogtreecommitdiff
path: root/src/Lexer.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/Lexer.zig')
-rw-r--r--src/Lexer.zig29
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 };