summaryrefslogtreecommitdiff
path: root/src/tokens/assembler.rs
diff options
context:
space:
mode:
authorBen Bridle <ben@derelict.engineering>2025-03-06 20:33:27 +1300
committerBen Bridle <ben@derelict.engineering>2025-03-11 16:59:26 +1300
commit1ecee352f5844b0809d7ae66df52e34f42b44c8e (patch)
tree472b6fd57ff7f64ac3f8cd676cbe7a113ba01f05 /src/tokens/assembler.rs
parentf2ed89083f5326a7a6f0a1720033d3388aa431fb (diff)
downloadtorque-asm-1ecee352f5844b0809d7ae66df52e34f42b44c8e.zip
Rewrite entire assembler
The language is now more general, the code is better structured, error reporting is more detailed, and many new language features have been implemented: - conditional blocks - first-class strings - more expression operators - binary literals - negative values - invocations in constant expressions
Diffstat (limited to 'src/tokens/assembler.rs')
-rw-r--r--src/tokens/assembler.rs162
1 files changed, 0 insertions, 162 deletions
diff --git a/src/tokens/assembler.rs b/src/tokens/assembler.rs
deleted file mode 100644
index 048062b..0000000
--- a/src/tokens/assembler.rs
+++ /dev/null
@@ -1,162 +0,0 @@
-use crate::*;
-
-
-#[derive(Clone)]
-pub enum AssembledToken {
- Word(AssembledWord),
- LabelDefinition(LabelDefinition),
- PinnedAddress(PinnedAddress),
- Error(AssemblerError),
-}
-
-#[derive(Clone)]
-pub struct AssembledWord {
- pub source: SourceSpan,
- pub value: usize,
- pub bits: usize,
- pub fields: Vec<AssembledField>,
- pub errors: Vec<AssemblerError>,
-}
-
-impl AssembledWord {
- pub fn count(&self) -> usize {
- // If there is at least one field, and all fields have empty string
- // values, then count will be zero. Else count will be at least one.
- let mut count = 0;
- let mut all_strings = !self.fields.is_empty();
- for field in &self.fields {
- if let IntegerArgument::String(string) = &field.value {
- count = std::cmp::max(count, string.chars.len());
- } else {
- all_strings = false;
- }
- }
- if !all_strings {
- count = std::cmp::max(count, 1);
- }
- return count;
- }
-}
-
-#[derive(Clone)]
-pub struct AssembledField {
- pub source: SourceSpan,
- pub value: IntegerArgument,
- /// Length of field in bits
- pub bits: usize,
- /// Distance to left-shift field in value
- pub shift: usize,
-}
-
-#[derive(Clone)]
-pub struct AssembledExpression {
- pub source: SourceSpan,
- pub tokens: Vec<AssembledExpressionToken>,
-}
-
-#[derive(Clone)]
-pub enum AssembledExpressionToken {
- Integer(TrackedInteger),
- LabelReference(Tracked<String>),
- Operator(Operator),
- Expression(Box<AssembledExpression>),
-}
-
-#[derive(Clone)]
-pub enum Argument {
- Integer(IntegerArgument),
- Block(Vec<AssembledToken>),
-}
-
-#[derive(Clone)]
-pub enum IntegerArgument {
- LabelReference(Tracked<String>),
- Integer(TrackedInteger),
- Expression(AssembledExpression),
- String(TrackedString),
-}
-
-#[derive(Clone)]
-pub struct AssemblerError {
- pub source: SourceSpan,
- pub variant: AssemblerErrorVariant,
-}
-
-#[derive(Clone, Debug)]
-pub enum AssemblerErrorVariant {
- DefinitionNotFound(String),
- NotAnInteger,
- NotABlock,
- IntegerInBlock,
- StringInExpression,
- /// expected, received
- IncorrectArgumentCount(usize, usize),
- /// expected, received, index
- IncorrectArgumentType(ArgumentVariant, ArgumentVariant),
-}
-
-// ------------------------------------------------------------------------ //
-
-macro_rules! indent {
- ($indent:expr => $($tokens:tt)*) => {{
- for _ in 0..$indent { print!(" "); }
- println!($($tokens)*);
- }};
-}
-
-pub fn print_assembled_tokens(tokens: &[AssembledToken]) {
- for token in tokens {
- match token {
- AssembledToken::LabelDefinition(definition) => {
- println!("LABEL {}", definition.name)
- }
- AssembledToken::PinnedAddress(address) => {
- println!("PINNED {}", address.address)
- }
- AssembledToken::Word(word) => {
- println!("WORD {:b}", word.value);
- for field in &word.fields {
- print!(" FIELD ({} << {}) ", field.bits, field.shift);
- match &field.value {
- IntegerArgument::LabelReference(name) => {
- println!("LABEL '{name}'");
- }
- IntegerArgument::Integer(integer) => {
- println!("INTEGER '{}'", integer.value);
- }
- IntegerArgument::String(string) => {
- println!("STRING {string}");
- }
- IntegerArgument::Expression(expr) => {
- println!("EXPRESSION");
- print_assembled_expression(2, expr);
- }
- }
- }
- }
- AssembledToken::Error(error) => {
- println!("ERROR {:?}", error.variant)
- }
- }
- }
-}
-
-fn print_assembled_expression(indent: usize, expr: &AssembledExpression) {
- for token in &expr.tokens {
- match token {
- AssembledExpressionToken::Integer(integer) => {
- indent!(indent => "INTEGER {}", integer.value)
- }
- AssembledExpressionToken::LabelReference(name) => {
- indent!(indent => "LABEL '{name}'")
- }
- AssembledExpressionToken::Operator(operator) => {
- indent!(indent => "OPERATOR {operator:?}")
- }
- AssembledExpressionToken::Expression(expr) => {
- indent!(indent => "EXPRESSION");
- print_assembled_expression(indent+1, expr);
- }
- }
- }
-}