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
+74 -7
View File
@@ -2,23 +2,76 @@ use std::{fmt, str::FromStr};
use common::prelude::Register;
use crate::AssembleError;
#[derive(Debug, Clone)]
pub struct Node(pub Option<Symbol>, pub Opcode, pub Vec<Token>);
pub struct Node {
pub symbol: Option<Symbol>,
pub opcode: Opcode,
pub tokens: Vec<Token>,
}
#[macro_export]
#[macro_use]
macro_rules! node {
($symbol: expr, $opcode: expr, args: $tokens: expr) => {
Node::new($symbol.clone(), $opcode.clone(), $tokens.clone())
};
($symbol: expr, $opcode: expr, $($tokens: expr),+) => {
Node::new($symbol.clone(), $opcode.clone(), vec![$($tokens.clone()),+])
};
}
impl Node {
pub fn new(symbol: Option<Symbol>, opcode: Opcode, tokens: Vec<Token>) -> Node {
Node {
symbol,
opcode,
tokens,
}
}
pub fn label(&self) -> Option<Symbol> {
self.symbol.clone()
}
pub fn opcode(&self) -> Opcode {
self.opcode.clone()
}
pub fn args(&self) -> Vec<Token> {
self.tokens.clone()
}
pub fn arg(&self, index: usize) -> Result<Token, AssembleError> {
self.args()
.get(index)
.cloned()
.ok_or(AssembleError::InvalidArg)
}
}
impl fmt::Display for Node {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let symbol = match &self.0 {
Some(symbol) => format!("{symbol}"),
let symbol = match &self.label() {
Some(symbol) => format!("{}:\n", symbol),
None => "".to_string(),
};
write!(f, "Node: {} {} {:?}", symbol, self.1, self.2)
write!(
f,
"\x1b[93m{} \t\x1b[94m{} \x1b[37m{:?} \x1b[0m",
symbol,
self.opcode(),
self.args()
)
}
}
impl fmt::Display for Symbol {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}::{}", self.module, self.name)
write!(f, "{} ( module: {})", self.name, self.module)
}
}
@@ -82,18 +135,29 @@ impl fmt::Display for Opcode {
Opcode::Push => write!(f, "push"),
Opcode::Pop => write!(f, "pop"),
Opcode::Lwi => write!(f, "lwi"),
// utility - removed at compile time
Opcode::Include => write!(f, "include"),
// special - generated by assembler
Opcode::Data => write!(f, "data"),
}
}
}
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Eq, Hash)]
pub struct Symbol {
pub name: String,
pub module: Module,
}
#[derive(Debug, Clone)]
impl PartialEq for Symbol {
fn eq(&self, other: &Self) -> bool {
self.name == other.name && self.module == other.module
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Module {
Resolved(u64),
Unresolved(String),
@@ -182,6 +246,9 @@ pub enum Opcode {
Pop,
Lwi,
Include,
// fake instructions (these aren't present in the binary as instructions)
Data,
}
#[derive(Debug)]