// © 2023 John Breaux //! A bare-bones toy assembler for the TI MSP430, for use in MicroCorruption //! //! This project aims to assemble any valid msp430 instructions, while being lenient about the //! syntax. After all, a real-world parser is going to face all kinds of malformed input, and it //! would be nice to support that kind of input (or, if it's completely unsalvageable, provide a //! useful message to the author.) //! //! The [`Parser`](preamble::Parser) will ignore whitespace, excluding newlines, //! unless syntactically relevant. It will also discard comma-separators between operands of a //! two-operand instruction. //! //! It returns an AST structured as follows //! ```text //! Root //! ├─ Line //! │ └─ Empty //! ├─ Line //! │ └─ Comment //! ├─ Line //! │ └─ Directive // Pre- or Post-processor directive //! ├─ Linel //! │ └─ Label // Label definition //! ├─ Line //! │ └─ Instruction //! │ ├─ Opcode //! │ └─ Encoding::Single //! │ ├─ Width //! │ └─ PrimaryOperand //! │ ├─ Identifier // Label, for relative-addressed data/code //! │ ├─ Register // Direct, indexed, indirect or indirect-post-increment register. //! │ └─ Number // Index, absolute address or immediate value. //! ├─ Line //! │ └─ Instruction //! │ ├─ Opcode //! │ └─ Encoding::Double //! │ ├─ Width //! │ ├─ PrimaryOperand //! │ ├─ Identifier // Label, for relative-addressed data/code //! │ │ ├─ Register // Direct, indexed, indirect or indirect-post-increment register. //! │ │ └─ Number // Index, absolute address or immediate value. //! │ └─ SecondaryOperand //! │ ├─ Identifier // Label, for relative-addressed data/code //! │ ├─ Register // Direct or indexed register //! │ └─ Number // Index or absolute address //! ├─ Line //! │ └─ Instruction //! │ ├─ Opcode //! │ └─ Encoding::Jump //! │ └─ JumpTarget //! │ ├─ Identifier // Label //! │ └─ Number // Even, PC-relative offset in range (-1024..=1022) //! └─ Line //! └─ EndOfFile //! ``` pub mod util { use std::{ fmt::{Debug, Display}, ops::{Index, Range}, }; /// A [Clone] + [Copy] + [!Iterator](Iterator) <\code> version of a [Range] #[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Span { pub start: Idx, pub end: Idx, } impl From> for Range { fn from(value: Span) -> Self { value.start..value.end } } impl From> for Span { fn from(value: Range) -> Self { Self { start: value.start, end: value.end } } } impl Index> for [T] { type Output = [T]; fn index(&self, index: Span) -> &Self::Output { self.index(Range::from(index)) } } impl Index> for str { type Output = str; fn index(&self, index: Span) -> &Self::Output { self.index(Range::from(index)) } } impl Debug for Span { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{:?}..{:?}", self.start, self.end) } } impl Display for Span { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}..{}", self.start, self.end) } } } pub mod lexer; pub mod preprocessor; pub mod parser; pub mod assembler;