const tokens = @import("tokens.zig"); const Token = tokens.Token; pub const ExprType = enum { Unary, Binary, Grouping, Number, Bool, Nil, String, }; pub const Expr = union(ExprType) { Unary: UnaryExpr, Binary: BinaryExpr, Grouping: Grouping, Number: Number, Bool: Bool, Nil: Nil, String: String, }; pub const UnaryExpr = struct { operator: Token, right: *Expr, }; pub fn mkUnary(operator: Token, right: *Expr) Expr { return Expr{ .Unary = UnaryExpr{ .operator = operator, .right = right, }, }; } pub const BinaryExpr = struct { left: *Expr, operator: Token, right: *Expr, }; pub fn mkBinary(left: *Expr, operator: Token, right: *Expr) Expr { return Expr{ .Binary = BinaryExpr{ .left = left, .operator = operator, .right = right, }, }; } pub const Grouping = struct { expression: *Expr, }; pub fn mkGrouping(expression: *Expr) Expr { return Expr{ .Grouping = Grouping{ .expression = expression, }, }; } /// Represents the default number literals in V. pub const NumberType = enum { Integer32, Integer64, Unsigned32, Unsigned64, Float32, Float64, }; /// "translation" of V number types to Zig number types for nicer /// representation. pub const Number = union(NumberType) { Integer32: i32, Integer64: i64, Unsigned32: u32, Unsigned64: u64, Float32: f32, Float64: f64, }; pub fn mkNum(comptime T: type, num: T) Expr { var expr = switch (T) { i32 => Expr{ .Number = Number{ .Integer32 = num } }, i64 => Expr{ .Number = Number{ .Integer64 = num } }, u32 => Expr{ .Number = Number{ .Unsigned32 = num } }, u64 => Expr{ .Number = Number{ .Unsigned64 = num } }, f32 => Expr{ .Number = Number{ .Float32 = num } }, f64 => Expr{ .Number = Number{ .Float64 = num } }, else => unreachable, }; return expr; } pub const Bool = bool; pub const Nil = void; pub const String = []u8;