//! Because these are u32, the max size for source is limited to 4GiB
//! Which means that for reading source, the maximum bytes read should be
//! std.math.maxInt(u32)
const std = @import("std");

const Self = @This();

/// Token type
pub const Type = enum {
    // Whitespace
    comment,
    whitespace,

    // Single-char tokens
    left_paren,
    right_paren,
    left_brace,
    right_brace,
    comma,
    dot,
    minus,
    plus,
    semicolon,
    slash,
    star,

    // one or two char tokens
    bang,
    bang_equal,
    equal,
    equal_equal,
    greater,
    greater_equal,
    less,
    less_equal,

    // literals
    identifier,
    string,
    number,

    // keywords
    kw_and,
    kw_class,
    kw_else,
    kw_false,
    kw_fun,
    kw_for,
    kw_if,
    kw_nil,
    kw_or,
    kw_print,
    kw_return,
    kw_super,
    kw_this,
    kw_true,
    kw_var,
    kw_while,

    eof,
};

pub const Literal = union {
    number: f32,
};

token_type: Type,
lexeme: []const u8,
line: u32,
// For the jlox interpreter, use a tagged union for literals
literal: ?Literal,

pub fn format(value: Self, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
    _ = fmt;
    _ = options;

    try writer.print("{any} '{s}' {?any}", .{ value.token_type, value.lexeme, value.literal });
}