hence/henceforth/src/lib/parser/ast.rs

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(" ")
}
}