using NubLang.Diagnostics; namespace NubLang.Syntax; public abstract class Token(SourceSpan span) { public SourceSpan Span { get; } = span; } public class WhitespaceToken(SourceSpan span) : Token(span); public class CommentToken(SourceSpan span, string comment) : Token(span) { public string Comment { get; } = comment; public override string ToString() { return "// " + Comment; } } public class IdentifierToken(SourceSpan span, string value) : Token(span) { public string Value { get; } = value; public override string ToString() { return Value; } } public class IntLiteralToken(SourceSpan span, string value, int @base) : Token(span) { public string Value { get; } = value; public int Base { get; } = @base; private string GetNumericValue() { return Base switch { 2 when Value.StartsWith("0b", StringComparison.OrdinalIgnoreCase) => Value[2..], 8 when Value.StartsWith("0o", StringComparison.OrdinalIgnoreCase) => Value[2..], 16 when Value.StartsWith("0x", StringComparison.OrdinalIgnoreCase) => Value[2..], _ => Value }; } public ulong AsU64 => Convert.ToUInt64(GetNumericValue(), Base); public long AsI64 => Convert.ToInt64(GetNumericValue(), Base); public uint AsU32 => Convert.ToUInt32(GetNumericValue(), Base); public int AsI32 => Convert.ToInt32(GetNumericValue(), Base); public ushort AsU16 => Convert.ToUInt16(GetNumericValue(), Base); public short AsI16 => Convert.ToInt16(GetNumericValue(), Base); public byte AsU8 => Convert.ToByte(GetNumericValue(), Base); public sbyte AsI8 => Convert.ToSByte(GetNumericValue(), Base); public float AsF32 => Convert.ToSingle(AsI32); public double AsF64 => Convert.ToDouble(AsI64); public override string ToString() { return Value; } } public class StringLiteralToken(SourceSpan span, string value) : Token(span) { public string Value { get; } = value; public override string ToString() { return $"\"{Value}\""; } } public class BoolLiteralToken(SourceSpan span, bool value) : Token(span) { public bool Value { get; } = value; public override string ToString() { return Value ? "true" : "false"; } } public class FloatLiteralToken(SourceSpan span, string value) : Token(span) { public string Value { get; } = value; public float AsF32 => Convert.ToSingle(Value); public double AsF64 => Convert.ToDouble(Value); public override string ToString() { return Value; } } public enum Symbol { // Default None, // Control If, Else, While, For, In, Break, Continue, Return, Let, Defer, // Declaration Func, Struct, Enum, Module, // Modifier Extern, Packed, Export, Colon, DoubleColon, OpenParen, CloseParen, OpenBrace, CloseBrace, OpenBracket, CloseBracket, Comma, Period, Assign, Bang, Equal, NotEqual, LessThan, LessThanOrEqual, GreaterThan, GreaterThanOrEqual, Plus, Minus, Star, ForwardSlash, Caret, Tilde, Ampersand, Semi, Percent, LeftShift, RightShift, Pipe, And, Or, At, QuestionMark, } public class SymbolToken(SourceSpan span, Symbol symbol) : Token(span) { public Symbol Symbol { get; } = symbol; public override string ToString() { return Symbol switch { Symbol.Func => "func", Symbol.If => "if", Symbol.Else => "else", Symbol.While => "while", Symbol.For => "for", Symbol.In => "in", Symbol.Break => "break", Symbol.Continue => "continue", Symbol.Return => "return", Symbol.Struct => "struct", Symbol.Let => "let", Symbol.Extern => "extern", Symbol.Module => "module", Symbol.Export => "export", Symbol.Defer => "defer", Symbol.Enum => "enum", Symbol.Equal => "==", Symbol.NotEqual => "!=", Symbol.LessThanOrEqual => "<=", Symbol.GreaterThanOrEqual => ">=", Symbol.LeftShift => "<<", Symbol.RightShift => ">>", Symbol.And => "&&", Symbol.Or => "||", Symbol.DoubleColon => "::", Symbol.Colon => ":", Symbol.OpenParen => "(", Symbol.CloseParen => ")", Symbol.OpenBrace => "{", Symbol.CloseBrace => "}", Symbol.OpenBracket => "[", Symbol.CloseBracket => "]", Symbol.Comma => ",", Symbol.Period => ".", Symbol.Assign => "=", Symbol.LessThan => "<", Symbol.GreaterThan => ">", Symbol.Plus => "+", Symbol.Minus => "-", Symbol.Star => "*", Symbol.ForwardSlash => "/", Symbol.Bang => "!", Symbol.Caret => "^", Symbol.Ampersand => "&", Symbol.Semi => ";", Symbol.Percent => "%", Symbol.Pipe => "|", Symbol.At => "@", Symbol.QuestionMark => "?", _ => "none", }; } }