feat: Implement AST macros and templates
This commit introduces support for AST macros and templates, enabling users to define and use custom, reusable components within the visual DSL. Key changes include: - A new `MacroRegistry` to manage macro definitions. - A `MacroExpander` to process macro calls and expand templates. - A `MacroEvaluator` trait for evaluating expressions during expansion. - The `Expansion` node in `BoundKind` to preserve the original macro call and its expanded form for debugging. - Updates to the `Binder`, `Dumper`, and `UpvalueAnalyzer` to handle the new macro constructs. - New examples demonstrating various macro functionalities like `unless`, splicing, and nested macros.
This commit is contained in:
+38
-2
@@ -1,6 +1,7 @@
|
||||
use std::rc::Rc;
|
||||
use std::fmt::Debug;
|
||||
use crate::ast::types::{Identity, Value};
|
||||
use std::any::Any;
|
||||
use crate::ast::types::{Identity, Value, Object};
|
||||
|
||||
/// A generic AST Node wrapper to preserve identity and metadata
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -10,12 +11,28 @@ pub struct Node<K, T = ()> {
|
||||
pub ty: T,
|
||||
}
|
||||
|
||||
impl Object for Node<UntypedKind> {
|
||||
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<dyn CustomNode>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
impl Clone for Box<dyn CustomNode> {
|
||||
fn clone(&self) -> Self {
|
||||
self.clone_box()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum UntypedKind {
|
||||
Nop,
|
||||
Constant(Value),
|
||||
@@ -50,5 +67,24 @@ pub enum UntypedKind {
|
||||
Map {
|
||||
entries: Vec<(Node<UntypedKind>, Node<UntypedKind>)>,
|
||||
},
|
||||
/// A macro declaration that can be expanded at compile time.
|
||||
MacroDecl {
|
||||
name: Rc<str>,
|
||||
params: Vec<Rc<str>>,
|
||||
body: Box<Node<UntypedKind>>,
|
||||
},
|
||||
/// A template for AST nodes, allowing for substitutions. (Quasiquote)
|
||||
Template(Box<Node<UntypedKind>>),
|
||||
/// A placeholder inside a template to be replaced by a node or value. (Unquote)
|
||||
Placeholder(Box<Node<UntypedKind>>),
|
||||
/// A placeholder that flattens a sequence or merges a map into its surroundings. (Splice)
|
||||
Splice(Box<Node<UntypedKind>>),
|
||||
/// Represents an expanded macro call, preserving the original call for debugging.
|
||||
Expansion {
|
||||
/// The original call from the source AST.
|
||||
call: Box<Node<UntypedKind>>,
|
||||
/// The resulting AST after macro expansion.
|
||||
expanded: Box<Node<UntypedKind>>,
|
||||
},
|
||||
Extension(Box<dyn CustomNode>),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user