]> Repositories - zlox.git/blobdiff - src/Scanner.zig
Implement parser
[zlox.git] / src / Scanner.zig
index c542e45ba058f167dc1f1f6a82af45bff8f4ad40..98fc69e1a5c6626a42e3a726b8fb29e6c3bc1d89 100644 (file)
@@ -9,6 +9,7 @@ const Scanner = @This();
 const TokenType = @import("token_type.zig").TokenType;
 const lox = @import("main.zig");
 
 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,
 source: []const u8,
 tokens: std.ArrayList(Token) = .empty,
 start: u32 = 0,
@@ -34,70 +35,71 @@ const keyword: std.StaticStringMap(TokenType) = .initComptime(.{
     .{ "while", .@"while" },
 });
 
     .{ "while", .@"while" },
 });
 
-pub fn init(source: []const u8) Scanner {
+pub fn init(allocator: Allocator, source: []const u8) Scanner {
     return .{
     return .{
+        .allocator = allocator,
         .source = source,
     };
 }
 
         .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;
     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) {
     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 {
 
         '/' => 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,
         },
 
         ' ', '\r', '\t' => {},
         '\n' => self.line += 1,
-        '"' => try self.string(allocator),
+        '"' => try self.string(),
 
         else => if (isDigit(c)) {
 
         else => if (isDigit(c)) {
-            try self.number(allocator);
+            try self.number();
         } else if (isAlpha(c)) {
         } else if (isAlpha(c)) {
-            try self.identifier(allocator);
+            try self.identifier();
         } else {
             try lox.@"error"(self.line, "Unexpected character.");
         },
     }
 }
 
         } 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;
     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();
 
     // Look for a fractional part.
@@ -108,10 +110,10 @@ fn number(self: *Scanner, allocator: Allocator) !void {
         while (isDigit(self.peek())) _ = self.advance();
     }
 
         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();
     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];
     _ = 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 {
 }
 
 fn match(self: *Scanner, expected: u8) bool {
@@ -163,7 +165,7 @@ fn advance(self: *Scanner) u8 {
     return self.source[self.current];
 }
 
     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];
     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));
 }
 }