#[derive(Debug, PartialEq, Clone)]
pub enum ASTNode {
Program(Vec<ASTNode>),
VariableDeclaration(String, Option<Box<ASTNode>>),
Assignment(String, Box<ASTNode>),
BinaryExpression(Box<ASTNode>, String, Box<ASTNode>),
NumberLiteral(i64),
FloatLiteral(f64),
StringLiteral(String),
Identifier(String),
FunctionDeclaration(String, Vec<String>, Box<ASTNode>),
FunctionCall(String, Vec<Box<ASTNode>>),
IfStatement(Box<ASTNode>, Box<ASTNode>, Option<Box<ASTNode>>),
WhileStatement(Box<ASTNode>, Box<ASTNode>),
ReturnStatement(Option<Box<ASTNode>>),
MemberAccess(Box<ASTNode>, String), MethodCall(Box<ASTNode>, String, Vec<Box<ASTNode>>), BooleanLiteral(bool),
}
pub trait ASTNodeTrait {
fn to_string(&self) -> String;
}
impl ASTNodeTrait for ASTNode {
fn to_string(&self) -> String {
match self {
ASTNode::Program(statements) => {
let mut result = String::new();
for statement in statements {
result.push_str(&statement.to_string());
result.push('\n');
}
result
}
ASTNode::VariableDeclaration(name, initializer) => {
let init_str = if let Some(init) = initializer {
format!(" = {}", init.to_string())
} else {
String::new()
};
format!("let {}{}", name, init_str)
}
ASTNode::Assignment(name, value) => format!("{} = {}", name, value.to_string()),
ASTNode::BinaryExpression(left, operator, right) => format!("{} {} {}", left.to_string(), operator, right.to_string()),
ASTNode::NumberLiteral(value) => value.to_string(),
ASTNode::FloatLiteral(value) => value.to_string(),
ASTNode::StringLiteral(value) => format!("\"{}\"", value),
ASTNode::Identifier(name) => name.clone(),
ASTNode::FunctionDeclaration(name, params, body) => {
let params_str = params.join(", ");
format!("fn {}({}) {}", name, params_str, body.to_string())
}
ASTNode::FunctionCall(name, args) => {
let args_str: Vec<String> = args.iter().map(|arg| arg.to_string()).collect();
format!("{}({})", name, args_str.join(", "))
}
ASTNode::IfStatement(condition, then_branch, else_branch) => {
let else_str = if let Some(else_branch) = else_branch {
format!(" else {}", else_branch.to_string())
} else {
String::new()
};
format!("if {} {}{}", condition.to_string(), then_branch.to_string(), else_str)
}
ASTNode::WhileStatement(condition, body) => format!("while {} {}", condition.to_string(), body.to_string()),
ASTNode::ReturnStatement(value) => {
if let Some(value) = value {
format!("return {}", value.to_string())
} else {
"return".to_string()
}
}
ASTNode::MemberAccess(object, property) => format!("{}.{}", object.to_string(), property),
ASTNode::MethodCall(object, method, args) => {
let args_str: Vec<String> = args.iter().map(|arg| arg.to_string()).collect();
format!("{}.{}/{}", object.to_string(), method, args_str.join(", "))
}
ASTNode::BooleanLiteral(value) => value.to_string(),
}
}
}