use crate::ast::types::{Identity, Object, Value}; use std::any::Any; use std::fmt::Debug; use std::rc::Rc; /// A name with an optional context for macro hygiene. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Symbol { pub name: Rc, /// Points to the identity of the Expansion node if this symbol /// was created/referenced inside a macro expansion. pub context: Option, } impl From> for Symbol { fn from(name: Rc) -> Self { Self { name, context: None, } } } impl From<&str> for Symbol { fn from(name: &str) -> Self { Self { name: Rc::from(name), context: None, } } } /// A generic AST Node wrapper to preserve identity and metadata #[derive(Debug, Clone, PartialEq)] pub struct Node { pub identity: Identity, pub kind: K, pub ty: T, } impl Object for Node { fn type_name(&self) -> &'static str { "ast-node" } fn as_any(&self) -> &dyn Any { self } } /// The base for custom node types (extensions) pub trait CustomNode: Debug { fn display_name(&self) -> &'static str; fn clone_box(&self) -> Box; } impl Clone for Box { fn clone(&self) -> Self { self.clone_box() } } #[derive(Debug, Clone)] pub enum UntypedKind { Nop, Constant(Value), /// A general identifier (used for both references and declarations in the untyped AST). Identifier(Symbol), /// A first-class field accessor (e.g. .name) FieldAccessor(crate::ast::types::Keyword), If { cond: Box>, then_br: Box>, else_br: Option>>, }, Def { target: Box>, value: Box>, }, Assign { target: Box>, value: Box>, }, Lambda { params: Box>, body: Rc>, }, Call { callee: Box>, args: Box>, }, Again { args: Box>, }, Pipe { inputs: Vec>, lambda: Box>, }, Block { statements: Vec>, result: Box>, }, Tuple { elements: Vec>, }, Record { fields: Vec<(Node, Node)>, }, /// A macro declaration that can be expanded at compile time. MacroDecl { name: Symbol, params: Box>, body: Box>, }, /// A template for AST nodes, allowing for substitutions. (Quasiquote) Template(Box>), /// A placeholder inside a template to be replaced by a node or value. (Unquote) Placeholder(Box>), /// A placeholder that flattens a sequence or merges a record into its surroundings. (Splice) Splice(Box>), /// Represents an expanded macro call, preserving the original call for debugging. Expansion { /// The original call from the source AST. call: Box>, /// The resulting AST after macro expansion. expanded: Box>, }, /// A diagnostic poison node, allowing compilation to continue after an error. Error, Extension(Box), }