Website Summary Files Commits Branches @commit @diff @stats
path: root / assembler / src / parser
diff options
context:
space:
mode:
Commitd17f1356cbe20f8c464668c74a2eb005643b80ba (patch)
Author
 Syndamia <kamen@syndamia.com>
2025-02-13 22:17:41 +0200
Committer
 Syndamia <kamen@syndamia.com>
2025-02-13 22:17:41 +0200
Files0e01f13006ab5bd58d8fe89ac404c5e982c5c604 /assembler/src/parser
tonkobali-d17f1356cbe20f8c464668c74a2eb005643b80ba.tar
tonkobali-d17f1356cbe20f8c464668c74a2eb005643b80ba.tar.gz
tonkobali-d17f1356cbe20f8c464668c74a2eb005643b80ba.zip
Parent1395b9eac37187227874c2bf4e768680c7dffd32 (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.rs13
-rw-r--r--assembler/src/parser/mod.rs78
-rw-r--r--assembler/src/parser/syntax.rs74
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
+ }
+}
+