53 lines
1.3 KiB
Rust
53 lines
1.3 KiB
Rust
use itertools::Itertools;
|
|
use std::fmt;
|
|
|
|
use crate::{arg, assembler};
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub enum Node {
|
|
Comment(String),
|
|
Label(String),
|
|
Call { name: String, arg: Option<arg::Arg> },
|
|
MacroCall { name: String, args: Vec<arg::Arg> },
|
|
}
|
|
|
|
impl fmt::Display for Node {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match self {
|
|
Node::Comment(x) => write!(f, "; {}", x),
|
|
Node::Label(x) => write!(f, "{}:", x),
|
|
Node::Call { name, arg } => {
|
|
if let Some(a) = arg {
|
|
write!(f, "{} {}", name, a)
|
|
} else {
|
|
write!(f, "{}", name)
|
|
}
|
|
}
|
|
Node::MacroCall { name, args } => {
|
|
if args.is_empty() {
|
|
write!(f, ".{}", name)
|
|
} else {
|
|
write!(f, ".{} {}", name, args.iter().join(", "))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl assembler::ToCode for Node {}
|
|
|
|
pub type Body = Vec<Node>;
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct AST {
|
|
pub body: Vec<Node>,
|
|
}
|
|
|
|
impl fmt::Display for AST {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "{}", itertools::free::join(&self.body, "\n"))
|
|
}
|
|
}
|
|
|
|
impl assembler::ToCode for AST {}
|