commit 7c7ee7b8161cddf83572f27b757f33dcf541a3af
parent 2de0bcd3e29b8ea0281bfae961c0aa46b5838046
Author: Szymon Mikulicz <szymon.mikulicz@posteo.net>
Date: Wed, 21 Feb 2024 18:24:20 +0100
Start on trie
Diffstat:
4 files changed, 49 insertions(+), 19 deletions(-)
diff --git a/zlox/build.zig.zon b/zlox/build.zig.zon
@@ -1,10 +1,13 @@
.{
.name = "zlox",
.version = "0.1.0",
+ .paths = .{
+ "./src",
+ },
.dependencies = .{
.linenoize = .{
- .url = "https://github.com/joachimschmidt557/linenoize/archive/180e8d1d8df4811d20ab7e216da9a6e2c35eb3a5.tar.gz",
- .hash = "1220aa9878b4bfa6a70a10793ae8ad42ea7cb1bbd1394c78613c3a9480aae0694d79",
+ .url = "https://github.com/joachimschmidt557/linenoize/archive/refs/heads/master.tar.gz",
+ .hash = "122095273d370fe3a29c2cd98027bae899065db6d759f3eacf049c4941af113b099c",
},
},
}
diff --git a/zlox/src/array.zig b/zlox/src/array.zig
@@ -7,11 +7,7 @@ pub fn Array(comptime T: type, comptime S: type, comptime size: S) type {
allocator: std.mem.Allocator,
pub fn init(allocator: std.mem.Allocator) !@This() {
- return @This() {
- .len = 0,
- .data = try allocator.alloc(T, size),
- .allocator = allocator
- };
+ return @This(){ .len = 0, .data = try allocator.alloc(T, size), .allocator = allocator };
}
pub fn add(self: *@This(), val: T) !void {
@@ -23,7 +19,7 @@ pub fn Array(comptime T: type, comptime S: type, comptime size: S) type {
}
pub fn get(self: *const @This(), idx: S) !T {
- if (idx >= self.len)
+ if (idx >= self.len)
return error.IndexOutOfBounds;
return self.data[idx];
}
@@ -44,34 +40,33 @@ pub fn RLEArray(comptime T: type, comptime size: usize) type {
return struct {
array: Array(element, usize, size),
- const element = struct {val: T, run: usize};
+ const element = struct { val: T, run: usize };
pub fn init(allocator: std.mem.Allocator) !@This() {
- return @This() {
+ return @This(){
.array = try Array(element, usize, size).init(allocator),
};
}
pub fn add(self: *@This(), val: T) !void {
const last = self.array.last() catch {
- try self.array.add(.{.val = val, .run = 1});
+ try self.array.add(.{ .val = val, .run = 1 });
return;
};
if (val == last.val) {
- self.array.data[self.array.len-1].run += 1;
+ self.array.data[self.array.len - 1].run += 1;
} else {
- try self.array.add(.{.val = val, .run = 1});
+ try self.array.add(.{ .val = val, .run = 1 });
}
}
pub fn get(self: *const @This(), idx: usize) !T {
var i: usize = 0;
var sum: usize = 0;
- while(idx >= sum) : (i += 1) {
+ while (idx >= sum) : (i += 1) {
sum += (try self.array.get(i)).run;
}
- if (i > 0) return self.array.data[i-1].val
- else return (try self.array.get(i)).val;
+ if (i > 0) return self.array.data[i - 1].val else return (try self.array.get(i)).val;
}
pub fn deinit(self: *@This()) void {
diff --git a/zlox/src/scanner.zig b/zlox/src/scanner.zig
@@ -46,7 +46,7 @@ pub const TokenType = enum {
EOF,
};
-pub const ScannerError = error{ UnexpectedCharacter, UnknownCharacter };
+pub const ScannerError = error{ UnexpectedCharacter, UnknownCharacter, UnterminatedString };
pub const Token = struct {
type: TokenType,
@@ -54,6 +54,8 @@ pub const Token = struct {
line: i32,
};
+const keywords: [][]const u8 = [_][]const u8{"while"};
+
pub const Scanner = struct {
pub fn init(source: []const u8) @This() {
return @This(){ .start = source.ptr, .current = source.ptr, .end = source.ptr + source.len, .line = 0 };
@@ -82,6 +84,7 @@ pub const Scanner = struct {
'=' => return self.makeToken(if (self.match('=')) TokenType.EQUAL_EQUAL else TokenType.EQUAL),
'<' => return self.makeToken(if (self.match('=')) TokenType.LESS_EQUAL else TokenType.LESS),
'>' => return self.makeToken(if (self.match('=')) TokenType.GREATER_EQUAL else TokenType.GREATER),
+ '"' => return self.string(),
'0'...'9' => return self.number(),
'a'...'z', 'A'...'Z', '_' => return self.identifier(),
else => return ScannerError.UnknownCharacter,
@@ -90,6 +93,19 @@ pub const Scanner = struct {
return ScannerError.UnexpectedCharacter;
}
+ fn string(self: *@This()) ScannerError!Token {
+ while (self.peek() != '"' and !self.isAtEnd()) {
+ if (self.peek() == '\n') self.line += 1;
+ _ = self.advance();
+ }
+
+ if (self.isAtEnd()) return ScannerError.UnterminatedString;
+
+ _ = self.advance();
+
+ return self.makeToken(TokenType.STRING);
+ }
+
fn skipWhitespace(self: *@This()) void {
while (true) {
switch (self.peek()) {
@@ -124,8 +140,19 @@ pub const Scanner = struct {
return self.makeToken(self.identifierType());
}
- fn identifierType(_: *const @This()) TokenType {
- return TokenType.IDENTIFIER;
+ fn identifierType(self: *const @This()) TokenType {
+ return switch (self.start[0]) {
+ 'a' => self.checkKeyword(1, "nd", TokenType.AND),
+ else => TokenType.IDENTIFIER,
+ };
+ }
+
+ fn checkKeyword(self: *const @This(), start: u8, rest: []const u8, token: TokenType) TokenType {
+ return if (@intFromPtr(self.current) - @intFromPtr(self.start) == start + rest.len and
+ std.mem.eql(u8, self.start[start .. start + rest.len], rest))
+ token
+ else
+ TokenType.IDENTIFIER;
}
fn advance(self: *@This()) u8 {
diff --git a/zlox/src/trie.zig b/zlox/src/trie.zig
@@ -0,0 +1,5 @@
+pub fn Trie(comptime T: type) type {
+ return struct {
+ len: S,
+ data: []T,
+ allocator: std.mem.Allocator,