X-Git-Url: https://git.ayoreis.com/zlox.git/blobdiff_plain/29d59fd1346c54a1bc6163fb860783eed7888d45..6d286699938880d7a1482be65e5e4771788c6b6f:/src/Scanner.zig?ds=sidebyside diff --git a/src/Scanner.zig b/src/Scanner.zig index c542e45..98fc69e 100644 --- a/src/Scanner.zig +++ b/src/Scanner.zig @@ -9,6 +9,7 @@ const Scanner = @This(); 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, @@ -34,70 +35,71 @@ const keyword: std.StaticStringMap(TokenType) = .initComptime(.{ .{ "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. @@ -108,10 +110,10 @@ fn number(self: *Scanner, allocator: Allocator) !void { 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(); @@ -126,7 +128,7 @@ fn string(self: *Scanner, allocator: Allocator) !void { _ = 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 { @@ -163,7 +165,7 @@ fn advance(self: *Scanner) u8 { 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)); }