Refactor: Use Symbol for identifiers and macro hygiene
Introduces a `Symbol` struct to represent identifiers, incorporating macro hygiene context. Updates various parts of the AST compiler and environment to use `Symbol` instead of raw `Rc<str>` for identifiers, improving robustness for macro expansions. Also includes: - Adds a new example `macro_hygiene.myc`. - Updates `.gitignore`. - Refactors `MacroExpander` to use `ExpansionState` for cleaner template expansion. - Adjusts `VM::eval_observed` to ensure `after_eval` is called correctly. - Resets `Environment` for each test run and compilation/dumping in `main.rs`.
This commit is contained in:
+26
-5
@@ -3,6 +3,27 @@ use std::fmt::Debug;
|
||||
use std::any::Any;
|
||||
use crate::ast::types::{Identity, Value, Object};
|
||||
|
||||
/// A name with an optional context for macro hygiene.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Symbol {
|
||||
pub name: Rc<str>,
|
||||
/// Points to the identity of the Expansion node if this symbol
|
||||
/// was created/referenced inside a macro expansion.
|
||||
pub context: Option<Identity>,
|
||||
}
|
||||
|
||||
impl From<Rc<str>> for Symbol {
|
||||
fn from(name: Rc<str>) -> 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)]
|
||||
pub struct Node<K, T = ()> {
|
||||
@@ -36,14 +57,14 @@ impl Clone for Box<dyn CustomNode> {
|
||||
pub enum UntypedKind {
|
||||
Nop,
|
||||
Constant(Value),
|
||||
Identifier(Rc<str>),
|
||||
Identifier(Symbol),
|
||||
If {
|
||||
cond: Box<Node<UntypedKind>>,
|
||||
then_br: Box<Node<UntypedKind>>,
|
||||
else_br: Option<Box<Node<UntypedKind>>>,
|
||||
},
|
||||
Def {
|
||||
name: Rc<str>,
|
||||
name: Symbol,
|
||||
value: Box<Node<UntypedKind>>,
|
||||
},
|
||||
Assign {
|
||||
@@ -51,7 +72,7 @@ pub enum UntypedKind {
|
||||
value: Box<Node<UntypedKind>>,
|
||||
},
|
||||
Lambda {
|
||||
params: Vec<Rc<str>>,
|
||||
params: Vec<Symbol>,
|
||||
body: Rc<Node<UntypedKind>>,
|
||||
},
|
||||
Call {
|
||||
@@ -69,8 +90,8 @@ pub enum UntypedKind {
|
||||
},
|
||||
/// A macro declaration that can be expanded at compile time.
|
||||
MacroDecl {
|
||||
name: Rc<str>,
|
||||
params: Vec<Rc<str>>,
|
||||
name: Symbol,
|
||||
params: Vec<Symbol>,
|
||||
body: Box<Node<UntypedKind>>,
|
||||
},
|
||||
/// A template for AST nodes, allowing for substitutions. (Quasiquote)
|
||||
|
||||
Reference in New Issue
Block a user