const TokenType = @import("token_type.zig").TokenType;
const lox = @import("main.zig");
+allocator: Allocator,
source: []const u8,
tokens: std.ArrayList(Token) = .empty,
start: u32 = 0,
.{ "while", .@"while" },
});
-pub fn init(source: []const u8) Scanner {
+pub fn init(allocator: Allocator, source: []const u8) Scanner {
return .{
+ .allocator = allocator,
.source = source,
};
}
-pub fn scanTokens(self: *Scanner, allocator: Allocator) ![]Token {
+pub fn scanTokens(self: *Scanner) ![]Token {
while (!isAtEnd(self)) {
// We are at the beginning of the next lexeme.
self.start = self.current;
- try self.scanToken(allocator);
+ try self.scanToken();
}
- try self.tokens.append(allocator, .init(.eof, "", null, self.line));
- return try self.tokens.toOwnedSlice(allocator);
+ try self.tokens.append(self.allocator, .init(.eof, "", null, self.line));
+ return try self.tokens.toOwnedSlice(self.allocator);
}
-fn scanToken(self: *Scanner, allocator: Allocator) !void {
+fn scanToken(self: *Scanner) !void {
const c = self.advance();
switch (c) {
- '(' => try self.addToken(allocator, .left_paren, null),
- ')' => try self.addToken(allocator, .right_paren, null),
- '{' => try self.addToken(allocator, .left_brace, null),
- '}' => try self.addToken(allocator, .right_brace, null),
- ',' => try self.addToken(allocator, .comma, null),
- '.' => try self.addToken(allocator, .dot, null),
- '-' => try self.addToken(allocator, .minus, null),
- '+' => try self.addToken(allocator, .plus, null),
- ';' => try self.addToken(allocator, .semicolon, null),
- '*' => try self.addToken(allocator, .star, null),
- '!' => try self.addToken(allocator, if (self.match('=')) .bang_equal else .bang, null),
- '=' => try self.addToken(allocator, if (self.match('=')) .equal_equal else .equal, null),
- '<' => try self.addToken(allocator, if (self.match('=')) .less_equal else .less, null),
- '>' => try self.addToken(allocator, if (self.match('=')) .greater_equal else .greater, null),
+ '(' => try self.addToken(.left_paren, null),
+ ')' => try self.addToken(.right_paren, null),
+ '{' => try self.addToken(.left_brace, null),
+ '}' => try self.addToken(.right_brace, null),
+ ',' => try self.addToken(.comma, null),
+ '.' => try self.addToken(.dot, null),
+ '-' => try self.addToken(.minus, null),
+ '+' => try self.addToken(.plus, null),
+ ';' => try self.addToken(.semicolon, null),
+ '*' => try self.addToken(.star, null),
+ '!' => try self.addToken(if (self.match('=')) .bang_equal else .bang, null),
+ '=' => try self.addToken(if (self.match('=')) .equal_equal else .equal, null),
+ '<' => try self.addToken(if (self.match('=')) .less_equal else .less, null),
+ '>' => try self.addToken(if (self.match('=')) .greater_equal else .greater, null),
'/' => if (self.match('/')) {
while (self.peek() != '\n' and !self.isAtEnd()) _ = self.advance();
} else {
- try self.addToken(allocator, .slash, null);
+ try self.addToken(.slash, null);
},
' ', '\r', '\t' => {},
'\n' => self.line += 1,
- '"' => try self.string(allocator),
+ '"' => try self.string(),
else => if (isDigit(c)) {
- try self.number(allocator);
+ try self.number();
} else if (isAlpha(c)) {
- try self.identifier(allocator);
+ try self.identifier();
} else {
try lox.@"error"(self.line, "Unexpected character.");
},
}
}
-fn identifier(self: *Scanner, allocator: Allocator) !void {
+fn identifier(self: *Scanner) !void {
while (isAlphanumeric(self.peek())) _ = self.advance();
const text = self.source[self.start..self.current];
const @"type" = keyword.get(text) orelse .identifier;
- try self.addToken(allocator, @"type", null);
+ try self.addToken(@"type", null);
}
-fn number(self: *Scanner, allocator: Allocator) !void {
+fn number(self: *Scanner) !void {
while (isDigit(self.peek())) _ = self.advance();
// Look for a fractional part.
while (isDigit(self.peek())) _ = self.advance();
}
- try self.addToken(allocator, .number, .{ .number = std.fmt.parseFloat(f64, self.source[self.start..self.current]) catch unreachable });
+ try self.addToken(.number, .{ .number = std.fmt.parseFloat(f64, self.source[self.start..self.current]) catch unreachable });
}
-fn string(self: *Scanner, allocator: Allocator) !void {
+fn string(self: *Scanner) !void {
while (self.peek() != '"' and !self.isAtEnd()) {
if (self.peek() == '\n') self.line += 1;
_ = self.advance();
_ = self.advance();
const value = self.source[self.start + 1 .. self.current - 1];
- try self.addToken(allocator, .string, .{ .string = value });
+ try self.addToken(.string, .{ .string = value });
}
fn match(self: *Scanner, expected: u8) bool {
return self.source[self.current];
}
-fn addToken(self: *Scanner, allocator: Allocator, @"type": TokenType, literal: ?Literal) !void {
+fn addToken(self: *Scanner, @"type": TokenType, literal: ?Literal) !void {
const text = self.source[self.start..self.current];
- try self.tokens.append(allocator, .init(@"type", text, literal, self.line));
+ try self.tokens.append(self.allocator, .init(@"type", text, literal, self.line));
}