use hence::assembler::ToCode; use std::fmt; #[derive(Debug, PartialEq, Eq, Clone)] pub struct StackResult { pub before: Vec, pub after: Vec, } 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, 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; #[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 {}