asm done with parsing and linking. codegen all that's left
This commit is contained in:
+74
-7
@@ -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)]
|
||||
|
||||
Reference in New Issue
Block a user