//! Contains [`TokenType`] and [`Token`]'s. Adapted from Harry's old lexer since it was //! easier to build from scratch and edit his code than it would be to try and wrangle it //! into shape. use common::prelude::*; use crate::source::{ source_info::SourceInfo, token_info::{ DirectiveToken, InstructionToken, LabelToken, RegisterToken, SymbolToken, }, }; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum TokenType { /// Symbol reference (e.g., `loop_start`, `my_data`). Symbol(SymbolToken), /// CPU register (e.g., `r1`, `r2`, `sp`). Register(RegisterToken), /// Immediate value (e.g., `42`, `0xFF`). Immediate(u32), /// String literal (e.g., `"hello world"`). String(String), /// Assembly instruction (e.g., `add`, `jmp`, `nop`). Instruction(InstructionToken), /// Label definition (e.g., `loop_start:`). Label(LabelToken), /// Assembler directive (e.g., `.global`, `.section`, `.dw`, `.resb`). Directive(DirectiveToken), /// Comma separator. Comma, /// End of line. Newline, /// End of file. Eof, /// A line comment. This is to be filtered out of the token stream. Comment, } #[derive(Debug)] pub struct Token { /// The type of the token. pub token_type: TokenType, /// Where in the source code is this [`Token`]? pub source_info: SourceInfo, } impl Token { #[must_use] pub const fn new(token_type: TokenType, source_info: SourceInfo) -> Self { Self { token_type, source_info, } } #[must_use] pub const fn symbol(name: String, source_info: SourceInfo) -> Self { Self::new(TokenType::Symbol(SymbolToken { name }), source_info) } #[must_use] pub const fn label(name: String, source_info: SourceInfo) -> Self { Self::new(TokenType::Label(LabelToken { name }), source_info) } #[must_use] pub const fn instruction(mnemonic: String, source_info: SourceInfo) -> Self { Self::new( TokenType::Instruction(InstructionToken { mnemonic }), source_info, ) } #[must_use] pub const fn register(reg: Register, source_info: SourceInfo) -> Self { Self::new(TokenType::Register(RegisterToken { reg }), source_info) } #[must_use] pub const fn immediate(value: u32, source_info: SourceInfo) -> Self { Self::new(TokenType::Immediate(value), source_info) } #[must_use] pub const fn directive(directive: String, source_info: SourceInfo) -> Self { Self::new( TokenType::Directive(DirectiveToken { directive }), source_info, ) } }