const std = @import("std"); pub const TokenType = enum { // Single-character tokens. LEFT_PAREN, RIGHT_PAREN, LEFT_BRACE, RIGHT_BRACE, COMMA, DOT, MINUS, PLUS, SEMICOLON, SLASH, STAR, // One or two character tokens. BANG, BANG_EQUAL, EQUAL, EQUAL_EQUAL, GREATER, GREATER_EQUAL, LESS, LESS_EQUAL, // Literals. IDENTIFIER, STRING, NUMBER, // Keywords. AND, CLASS, ELSE, FALSE, FUN, FOR, IF, NIL, OR, PRINT, RETURN, SUPER, THIS, TRUE, VAR, WHILE, EOF, }; pub fn TokenFactory( comptime T: type, ) type { return struct { const Self = @This(); ttype: TokenType, lexeme: []u8, line: usize, literal: T, pub fn init( ttype: TokenType, lexeme: []u8, line: usize, literal: T, ) Self { return Self{ .ttype = ttype, .lexeme = lexeme, .line = line, .literal = literal, }; } pub fn printToken(self: Self, stdout: var) !void { if (T == void) { try stdout.print( "Token(type={x}, lexeme='{}', line={})\n", self.ttype, self.lexeme, self.line, ); } else { try stdout.print( "Token(type={x}, lexeme='{}', line={} literal='{}')\n", self.ttype, self.lexeme, self.line, self.literal, ); } } }; } pub const SimpleToken = TokenFactory(void); pub const SliceToken = TokenFactory([]u8); pub const NumberToken = TokenFactory(f32); pub const Token = union(enum) { Simple: SimpleToken, Slice: SliceToken, Number: NumberToken, };