diff options
| Commit | d17f1356cbe20f8c464668c74a2eb005643b80ba (patch) | |
|---|---|---|
| Author | 2025-02-13 22:17:41 +0200 | |
| Committer | 2025-02-13 22:17:41 +0200 | |
| Files | 0e01f13006ab5bd58d8fe89ac404c5e982c5c604 /assembler/src/parser | |
| tonkobali-d17f1356cbe20f8c464668c74a2eb005643b80ba.tar tonkobali-d17f1356cbe20f8c464668c74a2eb005643b80ba.tar.gz tonkobali-d17f1356cbe20f8c464668c74a2eb005643b80ba.zip | ||
| Parent | 1395b9eac37187227874c2bf4e768680c7dffd32 (diff) | |
feat(assembler): Split into files and remove def addrs code gen step
3 files changed, 92 insertions, 73 deletions
| -rw-r--r-- | assembler/src/parser/code_gen.rs | 13 | ||||
| -rw-r--r-- | assembler/src/parser/mod.rs | 78 | ||||
| -rw-r--r-- | assembler/src/parser/syntax.rs | 74 |
diff --git a/assembler/src/parser/code_gen.rs b/assembler/src/parser/code_gen.rs new file mode 100644 index 0000000..375a8cb --- /dev/null +++ b/assembler/src/parser/code_gen.rs @@ -0,0 +1,13 @@ +use super::{ Program, Address }; + +impl Program { + pub(crate) fn remove_definition_addresses(&mut self) { + for instr in &mut self.instructions { + for arg in &mut instr.args { + if let Address::Definitions(name) = arg { + *arg = self.definitions[name].clone(); + } + } + } + } +} diff --git a/assembler/src/parser/mod.rs b/assembler/src/parser/mod.rs index 7061286..af78478 100644 --- a/assembler/src/parser/mod.rs +++ b/assembler/src/parser/mod.rs @@ -1,5 +1,8 @@ +mod code_gen; +mod syntax; + use std::collections::HashMap; -use crate::{ Word, lexer::Token }; +use crate::Word; #[derive(Debug, Default)] pub(crate) struct Instruction { @@ -11,8 +14,8 @@ pub(crate) struct Instruction { pub(crate) enum Address { Memory(usize), Constants(usize), - Definitions(String), Instruction(usize), + Definitions(String), #[default] None, } @@ -31,74 +34,3 @@ pub(crate) struct Program { constants: Vec<Word>, instructions: Vec<Instruction>, } - -impl Program { - pub(crate) fn new(tokens: Vec<Token>) -> Program { - let mut prog = Program {..Default::default() }; - - let mut op_name = String::new(); - let mut op_args = Vec::new(); - let mut value = Address::None; - let mut symbol_def = String::new(); - - for token in tokens { - match token { - /* Names (lvalue) */ - Token::Operator(name) => { - if ! op_name.is_empty() { - prog.instructions.push(Instruction { - name: op_name, - args: op_args.clone(), - }); - } - op_name = name; - op_args.clear(); - }, - Token::Label(name) => { - // Predicting the index - let index = prog.instructions.len() + !op_name.is_empty() as usize; - prog.definitions.insert(name, Address::Instruction(index)); - }, - Token::SymbolDef(name) => symbol_def = name, - - /* Values (rvalue) */ - Token::Address(num) => { - value = Address::Memory(num as usize); - }, - Token::Number(num) => { - prog.constants.push(num); - value = Address::Constants(prog.constants.len() - 1); - }, - Token::String(str) => { - let index = prog.constants.len(); - for c in str.chars() { - prog.constants.push(c as Word); - } - value = Address::Constants(index); - }, - Token::Symbol(name) => { - value = Address::Definitions(name); - }, - } - - if value != Address::None { - if ! symbol_def.is_empty() { - prog.definitions.insert(symbol_def.clone(), value.take()); - symbol_def.clear(); - } - else { - op_args.push(value.take()); - } - } - } - - if ! op_name.is_empty() { - prog.instructions.push(Instruction { - name: op_name, - args: op_args.clone(), - }); - } - - prog - } -} diff --git a/assembler/src/parser/syntax.rs b/assembler/src/parser/syntax.rs new file mode 100644 index 0000000..e6eb810 --- /dev/null +++ b/assembler/src/parser/syntax.rs @@ -0,0 +1,74 @@ +use crate::{ Word, lexer::Token }; +use super::{ Program, Address, Instruction }; + +impl Program { + pub(crate) fn new(tokens: Vec<Token>) -> Program { + let mut prog = Program {..Default::default() }; + + let mut op_name = String::new(); + let mut op_args = Vec::new(); + let mut value = Address::None; + let mut symbol_def = String::new(); + + for token in tokens { + match token { + /* Names (lvalue) */ + Token::Operator(name) => { + if ! op_name.is_empty() { + prog.instructions.push(Instruction { + name: op_name, + args: op_args.clone(), + }); + } + op_name = name; + op_args.clear(); + }, + Token::Label(name) => { + // Predicting the index + let index = prog.instructions.len() + !op_name.is_empty() as usize; + prog.definitions.insert(name, Address::Instruction(index)); + }, + Token::SymbolDef(name) => symbol_def = name, + + /* Values (rvalue) */ + Token::Address(num) => { + value = Address::Memory(num as usize); + }, + Token::Number(num) => { + prog.constants.push(num); + value = Address::Constants(prog.constants.len() - 1); + }, + Token::String(str) => { + let index = prog.constants.len(); + for c in str.chars() { + prog.constants.push(c as Word); + } + value = Address::Constants(index); + }, + Token::Symbol(name) => { + value = Address::Definitions(name); + }, + } + + if value != Address::None { + if ! symbol_def.is_empty() { + prog.definitions.insert(symbol_def.clone(), value.take()); + symbol_def.clear(); + } + else { + op_args.push(value.take()); + } + } + } + + if ! op_name.is_empty() { + prog.instructions.push(Instruction { + name: op_name, + args: op_args.clone(), + }); + } + + prog + } +} + |
