From 18cc7a9ff7e83f47e9289d2adbd15663833fefef Mon Sep 17 00:00:00 2001 From: Mathias Magnusson Date: Sun, 1 Jun 2025 01:09:37 +0200 Subject: capitalize Lexer.zig correctly --- src/Lexer.zig | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lexer.zig | 99 ----------------------------------------------------------- src/main.zig | 2 +- 3 files changed, 100 insertions(+), 100 deletions(-) create mode 100644 src/Lexer.zig delete mode 100644 src/lexer.zig (limited to 'src') diff --git a/src/Lexer.zig b/src/Lexer.zig new file mode 100644 index 0000000..3621a1c --- /dev/null +++ b/src/Lexer.zig @@ -0,0 +1,99 @@ +const std = @import("std"); + +pub const Token = struct { + loc: Location, + type: Type, + + pub const Type = enum { + left_paren, + right_paren, + integer_literal, + plus, + minus, + invalid, + eof, + }; +}; + +pub const Location = struct { + start: usize, + end: usize, + + pub fn combine(a: Location, b: Location) Location { + std.debug.assert(a.end <= b.start); + return .{ .start = @min(a.start, b.start), .end = @max(a.end, b.end) }; + } + + /// Assumes that the location comes directly from an `integer_literal` token. + pub fn getInt(self: Location, file_source: []const u8) u64 { + var value: u64 = 0; + for (file_source[self.start..self.end]) |c| { + std.debug.assert('0' <= c and c <= '9'); + value = value * 10 + (c - '0'); + } + return value; + } +}; + +source: []const u8, +start: usize = 0, +pos: usize = 0, + +pub fn next(self: *Self) ?Token { + self.start = self.pos; + return s: switch (self.eat() orelse return self.create(.eof)) { + '(' => self.create(.left_paren), + ')' => self.create(.right_paren), + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' => self.integerLiteral(), + '+' => self.create(.plus), + '-' => self.create(.minus), + ' ' => { + self.start = self.pos; + continue :s (self.eat() orelse return self.create(.eof)); + }, + else => self.create(.invalid), + }; +} + +fn integerLiteral(self: *Self) Token { + var value: ?u64 = self.source[self.start] - '0'; + while (digitValue(self.peek())) |v| { + var nxt: ?u64 = null; + if (value) |val| + if (std.math.mul(u64, val, 10) catch null) |p| + if (std.math.add(u64, p, v) catch null) |s| { + nxt = s; + }; + + value = nxt; + _ = self.eat(); + } + return if (value != null) + self.create(.integer_literal) + else + self.create(.invalid); +} + +fn create(self: *Self, tajp: Token.Type) Token { + const start = self.start; + return .{ .loc = .{ .start = start, .end = self.pos }, .type = tajp }; +} + +fn eat(self: *Self) ?u8 { + const token = self.peek(); + if (token != null) self.pos += 1; + return token; +} + +fn peek(self: *Self) ?u8 { + return if (self.pos < self.source.len) self.source[self.pos] else null; +} + +const Self = @This(); + +fn digitValue(c: ?u8) ?u8 { + return switch (c orelse return null) { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' => c.? - '0', + else => null, + }; +} diff --git a/src/lexer.zig b/src/lexer.zig deleted file mode 100644 index 3621a1c..0000000 --- a/src/lexer.zig +++ /dev/null @@ -1,99 +0,0 @@ -const std = @import("std"); - -pub const Token = struct { - loc: Location, - type: Type, - - pub const Type = enum { - left_paren, - right_paren, - integer_literal, - plus, - minus, - invalid, - eof, - }; -}; - -pub const Location = struct { - start: usize, - end: usize, - - pub fn combine(a: Location, b: Location) Location { - std.debug.assert(a.end <= b.start); - return .{ .start = @min(a.start, b.start), .end = @max(a.end, b.end) }; - } - - /// Assumes that the location comes directly from an `integer_literal` token. - pub fn getInt(self: Location, file_source: []const u8) u64 { - var value: u64 = 0; - for (file_source[self.start..self.end]) |c| { - std.debug.assert('0' <= c and c <= '9'); - value = value * 10 + (c - '0'); - } - return value; - } -}; - -source: []const u8, -start: usize = 0, -pos: usize = 0, - -pub fn next(self: *Self) ?Token { - self.start = self.pos; - return s: switch (self.eat() orelse return self.create(.eof)) { - '(' => self.create(.left_paren), - ')' => self.create(.right_paren), - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' => self.integerLiteral(), - '+' => self.create(.plus), - '-' => self.create(.minus), - ' ' => { - self.start = self.pos; - continue :s (self.eat() orelse return self.create(.eof)); - }, - else => self.create(.invalid), - }; -} - -fn integerLiteral(self: *Self) Token { - var value: ?u64 = self.source[self.start] - '0'; - while (digitValue(self.peek())) |v| { - var nxt: ?u64 = null; - if (value) |val| - if (std.math.mul(u64, val, 10) catch null) |p| - if (std.math.add(u64, p, v) catch null) |s| { - nxt = s; - }; - - value = nxt; - _ = self.eat(); - } - return if (value != null) - self.create(.integer_literal) - else - self.create(.invalid); -} - -fn create(self: *Self, tajp: Token.Type) Token { - const start = self.start; - return .{ .loc = .{ .start = start, .end = self.pos }, .type = tajp }; -} - -fn eat(self: *Self) ?u8 { - const token = self.peek(); - if (token != null) self.pos += 1; - return token; -} - -fn peek(self: *Self) ?u8 { - return if (self.pos < self.source.len) self.source[self.pos] else null; -} - -const Self = @This(); - -fn digitValue(c: ?u8) ?u8 { - return switch (c orelse return null) { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' => c.? - '0', - else => null, - }; -} diff --git a/src/main.zig b/src/main.zig index 85fedcd..1ca22a3 100644 --- a/src/main.zig +++ b/src/main.zig @@ -6,7 +6,7 @@ const codegen = @import("./codegen.zig"); pub const peekable = peek.peekable; pub const Peekable = peek.Peekable; pub const Expr = parse.Expr; -pub const Lexer = @import("./lexer.zig"); +pub const Lexer = @import("./Lexer.zig"); pub const compile = @import("./compile.zig"); pub fn main() !void { -- cgit v1.2.3