76 lines
1.7 KiB
Rust
76 lines
1.7 KiB
Rust
use hence::assembler::ToCode;
|
|
use itertools::Itertools;
|
|
|
|
#[derive(Debug)]
|
|
pub struct StackResult {
|
|
pub before: Vec<String>,
|
|
pub after: Vec<String>,
|
|
}
|
|
|
|
impl ToCode for StackResult {
|
|
fn to_code(&self) -> String {
|
|
format!(
|
|
"{}--{}",
|
|
if self.before.is_empty() {
|
|
"".to_string()
|
|
} else {
|
|
format!("{} ", self.before.join(" "))
|
|
},
|
|
if self.after.is_empty() {
|
|
"".to_string()
|
|
} else {
|
|
format!("{} ", self.after.join(" "))
|
|
}
|
|
)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum Node {
|
|
Comment(String),
|
|
String {
|
|
mode: String,
|
|
string: String,
|
|
},
|
|
Number(i32),
|
|
WordDefinition {
|
|
name: String,
|
|
stack: Option<StackResult>,
|
|
body: Body,
|
|
},
|
|
Word(String),
|
|
}
|
|
|
|
impl ToCode for Node {
|
|
fn to_code(&self) -> String {
|
|
match self {
|
|
Node::Comment(x) => format!("\\ {}", x),
|
|
Node::String { mode, string } => format!("{}\" {}\"", mode, string),
|
|
Node::Number(x) => x.to_string(),
|
|
Node::WordDefinition { name, stack, body } => format!(
|
|
": {}{} {} ;",
|
|
name,
|
|
match stack {
|
|
Some(x) => format!(" {}", x.to_code()),
|
|
None => "".to_string(),
|
|
},
|
|
body.iter().map(|x| x.to_code()).join(" ")
|
|
),
|
|
Node::Word(x) => x.clone(),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub type Body = Vec<Node>;
|
|
|
|
#[derive(Debug)]
|
|
pub struct AST {
|
|
pub body: Body,
|
|
}
|
|
|
|
impl ToCode for AST {
|
|
fn to_code(&self) -> String {
|
|
self.body.iter().map(|x| x.to_code()).join(" ")
|
|
}
|
|
}
|