asm done with parsing and linking. codegen all that's left

This commit is contained in:
2025-06-18 03:54:39 +01:00
parent 6a0b5c617a
commit 1210b19333
6 changed files with 366 additions and 63 deletions
+67 -6
View File
@@ -1,4 +1,4 @@
use std::path::PathBuf;
use std::{collections::HashMap, path::PathBuf};
use crate::{
AssembleError,
@@ -6,18 +6,77 @@ use crate::{
quick_hash,
};
pub fn resolve_symbols(nodes: &mut Vec<Node>) -> Result<(), AssembleError> {
let symbol_table = generate_symbol_table(&nodes)?;
for node in nodes.iter_mut() {
match node.opcode() {
Opcode::Lli => {
if let Token::Symbol(symbol) = node.arg(0).unwrap() {
if let Some(address) = symbol_table.get(&symbol) {
node.tokens[0] = Token::Immediate(*address);
} else {
return Err(AssembleError::UndefinedSymbol(symbol.clone()));
}
}
}
Opcode::Lui => {
if let Token::Symbol(symbol) = node.arg(0).unwrap() {
if let Some(address) = symbol_table.get(&symbol) {
node.tokens[0] = Token::Immediate(*address);
} else {
return Err(AssembleError::UndefinedSymbol(symbol.clone()));
}
}
}
Opcode::Jmp
| Opcode::Jeq
| Opcode::Jne
| Opcode::Jgt
| Opcode::Jge
| Opcode::Jlt
| Opcode::Jle => {
if let Token::Symbol(symbol) = node.arg(0).unwrap() {
if let Some(address) = symbol_table.get(&symbol) {
node.tokens[0] = Token::Immediate(*address);
} else {
return Err(AssembleError::UndefinedSymbol(symbol.clone()));
}
}
}
_ => (),
}
}
Ok(())
}
fn generate_symbol_table(
nodes: &Vec<Node>,
) -> Result<HashMap<Symbol, u32>, AssembleError> {
let mut table = HashMap::new();
for (i, node) in nodes.iter().enumerate() {
if let Some(symbol) = node.label() {
table.insert(symbol, 4 * i as u32);
}
}
Ok(table)
}
pub fn resolve_dependencies(mut nodes: Vec<Node>) -> Result<Vec<Node>, AssembleError> {
// first we get a list of imports
let mut dependencies = Vec::new();
for node in &nodes {
if let Opcode::Include = node.1 {
if let Opcode::Include = node.opcode() {
// we want the path, and the name
let name = if let Token::Symbol(name) = node.2.get(0).unwrap() {
let name = if let Token::Symbol(name) = node.arg(0).unwrap() {
name.name.clone()
} else {
unreachable!()
}; //node.2.get(0).unwrap()
let path = if let Token::StringLit(path) = node.2.get(1).unwrap() {
let path = if let Token::StringLit(path) = node.arg(1).unwrap() {
path
} else {
unreachable!()
@@ -32,7 +91,9 @@ pub fn resolve_dependencies(mut nodes: Vec<Node>) -> Result<Vec<Node>, AssembleE
// now we resolve the symbols on all the nodes
// we need to check all operands for unresolved signals
for (i, node) in nodes.clone().iter().enumerate() {
let Node(_, _, operands) = node;
let Node {
tokens: operands, ..
} = node;
for (j, token) in operands.iter().enumerate() {
if let Token::Symbol(symbol) = token {
for d in &dependencies {
@@ -53,7 +114,7 @@ pub fn resolve_dependencies(mut nodes: Vec<Node>) -> Result<Vec<Node>, AssembleE
}
for (i, j, symbol) in changes {
nodes[i as usize].2[j as usize] = Token::Symbol(symbol);
nodes[i as usize].tokens[j as usize] = Token::Symbol(symbol);
}
Ok(nodes)