diff options
| author | Nic Gaffney <gaffney_nic@protonmail.com> | 2024-08-06 02:24:04 -0500 |
|---|---|---|
| committer | Nic Gaffney <gaffney_nic@protonmail.com> | 2024-08-06 02:24:04 -0500 |
| commit | 6a7467264b506e5812b2d9a8cd55fa307f2b5a10 (patch) | |
| tree | 97c136f9f65a575d940f647b7c2130b3454fa88d /src/tokenize.zig | |
| parent | f8542ab4c65d64e7713063460d750901e7b0362d (diff) | |
| download | calico-6a7467264b506e5812b2d9a8cd55fa307f2b5a10.tar.gz | |
ok so i messed up
Diffstat (limited to 'src/tokenize.zig')
| -rw-r--r-- | src/tokenize.zig | 84 |
1 files changed, 80 insertions, 4 deletions
diff --git a/src/tokenize.zig b/src/tokenize.zig index ad263c2..770f483 100644 --- a/src/tokenize.zig +++ b/src/tokenize.zig @@ -1,36 +1,57 @@ const std = @import("std"); -const TokenizeError = error{ +pub const TokenizeError = error{ UnknownToken, UnexpectedEOF, + ExpectedToken, }; pub const TokenType = enum { + // Runtime Values ident, intLit, + // Keywords constant, variable, exit, + fun, + // Operators plus, minus, star, slash, semiCol, equal, + // Symbols + openBrace, + closeBrace, + openParen, + closeParen, + arrow, }; pub const Token = union(TokenType) { + //RuntimeVar ident: []const u8, intLit: i32, + // Keywords constant, variable, exit, + fun, + // Operators plus, minus, star, slash, semiCol, equal, + // Symbols + openBrace, + closeBrace, + openParen, + closeParen, + arrow, pub fn fromChar(char: u8) !Token { return switch (char) { @@ -40,15 +61,20 @@ pub const Token = union(TokenType) { '/' => .slash, ';' => .semiCol, '=' => .equal, + '{' => .openBrace, + '}' => .closeBrace, + '(' => .openParen, + ')' => .closeParen, else => TokenizeError.UnknownToken, }; } pub fn fromStr(str: []const u8) Token { const eql = std.mem.eql; - if (eql(u8, str, "exit")) return .exit; + if (eql(u8, str, "return")) return .exit; if (eql(u8, str, "const")) return .constant; if (eql(u8, str, "var")) return .variable; + if (eql(u8, str, "fn")) return .fun; return Token{ .ident = str }; } }; @@ -91,7 +117,7 @@ pub fn Iterator(comptime typ: type) type { pub fn consume(self: *Iterator(typ), comptime expected: TokenType) !?typ { if (typ != Token) return error.TokenIteratorOnly; if (!checkType(self.peek().?, expected)) - return error.ExpectedToken; + return TokenizeError.ExpectedToken; return self.next(); } @@ -134,6 +160,15 @@ pub const Tokenizer = struct { while (self.src.peek()) |char| { try switch (char) { + '-' => { + self.src.skip(); + if (self.src.peek().? != '>') { + try self.toks.append(.minus); + continue; + } + self.src.skip(); + try self.toks.append(.arrow); + }, ' ', '\n', '\t' => self.src.skip(), '0'...'9' => { while (std.ascii.isDigit(self.src.peek().?)) @@ -161,7 +196,7 @@ pub const Tokenizer = struct { test "Tokenize Expression" { const expect = std.testing.expect; - const testSource: []const u8 = "exit 120 + 150 - 260 * 12 / 5 + variable;"; + const testSource: []const u8 = "return 120 + 150 - 260 * 12 / 5 + variable;"; var tokenizer = Tokenizer.init(std.testing.allocator, testSource); defer tokenizer.deinit(); const tokens = try tokenizer.tokenize(); @@ -219,6 +254,7 @@ test "Tokenize variable" { } } } + test "Tokenize constant" { const expect = std.testing.expect; const testSource: []const u8 = "const five = 5;"; @@ -243,3 +279,43 @@ test "Tokenize constant" { } } } + +test "Tokenize Function" { + const expect = std.testing.expect; + const testSource: []const u8 = + \\fn main() -> i32 { + \\ return 7; + \\} + ; + var tokenizer = Tokenizer.init(std.testing.allocator, testSource); + defer tokenizer.deinit(); + const tokens = try tokenizer.tokenize(); + const expected = &[_]Token{ + .fun, + .{ .ident = "main" }, + .openParen, + .closeParen, + .arrow, + .{ .ident = "i32" }, + .openBrace, + .exit, + .{ .intLit = 7 }, + .semiCol, + .closeBrace, + }; + for (tokens, expected) |act, exp| { + switch (act) { + .ident => |v| try expect(std.mem.eql(u8, exp.ident, v)), + .fun => |v| try expect(v == exp.fun), + .arrow => |v| try expect(v == exp.arrow), + .intLit => |v| try expect(v == exp.intLit), + .exit => |v| try expect(v == exp.exit), + .closeParen => |v| try expect(v == exp.closeParen), + .openParen => |v| try expect(v == exp.openParen), + .openBrace => |v| try expect(v == exp.openBrace), + .closeBrace => |v| try expect(v == exp.closeBrace), + .semiCol => |v| try expect(v == exp.semiCol), + else => try expect(1 == 0), + } + } +} |
