108 lines
2.8 KiB
Rust
108 lines
2.8 KiB
Rust
use hence::assembler::ToCode;
|
|
use std::fmt;
|
|
|
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
|
pub struct StackResult {
|
|
pub before: Vec<String>,
|
|
pub after: Vec<String>,
|
|
}
|
|
|
|
impl fmt::Display for StackResult {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(
|
|
f,
|
|
"{}--{}",
|
|
if self.before.is_empty() {
|
|
"".to_string()
|
|
} else {
|
|
format!("{} ", self.before.join(" "))
|
|
},
|
|
if self.after.is_empty() {
|
|
"".to_string()
|
|
} else {
|
|
format!("{} ", self.after.join(" "))
|
|
}
|
|
)
|
|
}
|
|
}
|
|
|
|
impl ToCode for StackResult {}
|
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
pub enum Node {
|
|
Comment(String),
|
|
String {
|
|
mode: String,
|
|
string: String,
|
|
},
|
|
Number(i32),
|
|
WordDefinition {
|
|
name: String,
|
|
stack: Option<StackResult>,
|
|
body: Body,
|
|
},
|
|
Condition {
|
|
if_body: Body,
|
|
else_body: Body,
|
|
},
|
|
Word(String),
|
|
}
|
|
|
|
impl fmt::Display for Node {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match self {
|
|
Node::Comment(x) => write!(f, "\\ {}", x),
|
|
Node::String { mode, string } => write!(f, "{}\" {}\"", mode, string),
|
|
Node::Number(x) => write!(f, "{}", x),
|
|
Node::WordDefinition { name, stack, body } => write!(
|
|
f,
|
|
": {}{} {} ;",
|
|
name,
|
|
match stack {
|
|
Some(x) => format!(" {}", x),
|
|
None => "".to_string(),
|
|
},
|
|
// body.iter().map(|x| x.to_code()).join(" ")
|
|
itertools::free::join(body, " ")
|
|
),
|
|
Node::Condition { if_body, else_body } => {
|
|
if else_body.is_empty() {
|
|
write!(
|
|
f,
|
|
"if {} then",
|
|
// if_body.iter().map(|x| x.to_code()).join(" ")
|
|
itertools::free::join(if_body, " ")
|
|
)
|
|
} else {
|
|
write!(
|
|
f,
|
|
"if {} else {} then",
|
|
// if_body.iter().map(|x| x.to_code()).join(" "),
|
|
itertools::free::join(if_body, " "),
|
|
// else_body.iter().map(|x| x.to_code()).join(" ")
|
|
itertools::free::join(else_body, " "),
|
|
)
|
|
}
|
|
}
|
|
Node::Word(x) => write!(f, "{}", x),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl ToCode for Node {}
|
|
|
|
pub type Body = Vec<Node>;
|
|
|
|
#[derive(Debug)]
|
|
pub struct AST {
|
|
pub body: Body,
|
|
}
|
|
|
|
impl fmt::Display for AST {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "{}", itertools::free::join(&self.body, "\n"))
|
|
}
|
|
}
|
|
|
|
impl ToCode for AST {}
|