Refactor Value enum for Quote node
Replaces `Value::Object(Rc<dyn Object>)` for SyntaxNodes with a dedicated `Value::Quote(Rc<SyntaxNode>)`. This provides better type safety and clarity when dealing with AST nodes as values. Refactor Value enum for Quote node This commit introduces a new `Value::Quote` variant to represent quoted AST nodes directly, replacing the generic `Value::Object` for this purpose. This change simplifies the handling of quoted nodes by: - Directly storing an `Rc<SyntaxNode>` instead of relying on dynamic downcasting from `Rc<dyn Object>`. - Streamlining macro expansion logic by removing the need to check for `SyntaxNode` within `Value::Object`. - Improving type safety and explicitness in the `Value` enum.
This commit is contained in:
+15
-32
@@ -588,29 +588,21 @@ impl<E: MacroEvaluator> MacroExpander<E> {
|
||||
target: &mut Vec<Rc<SyntaxNode>>,
|
||||
) -> Result<(), String> {
|
||||
match val {
|
||||
Value::Object(obj) => {
|
||||
if let Some(node) = obj.as_any().downcast_ref::<SyntaxNode>() {
|
||||
match &node.kind {
|
||||
SyntaxKind::Tuple { elements } => {
|
||||
for e in elements {
|
||||
target.push(e.clone());
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
SyntaxKind::Block { exprs } => {
|
||||
for e in exprs {
|
||||
target.push(e.clone());
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
_ => {}
|
||||
Value::Quote(node) => match &node.kind {
|
||||
SyntaxKind::Tuple { elements } => {
|
||||
for e in elements {
|
||||
target.push(e.clone());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Err(format!(
|
||||
"Strict Splicing: Expected Tuple or Block node, but found {}",
|
||||
obj.type_name()
|
||||
))
|
||||
}
|
||||
SyntaxKind::Block { exprs } => {
|
||||
for e in exprs {
|
||||
target.push(e.clone());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
_ => Err("Strict Splicing: Expected Tuple or Block node".to_string()),
|
||||
},
|
||||
_ => Err(format!(
|
||||
"Strict Splicing: Expected sequence (Tuple/Block Node), but found Value: {}",
|
||||
val
|
||||
@@ -620,16 +612,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
|
||||
|
||||
fn value_to_node(&self, val: Value, identity: Identity) -> SyntaxNode {
|
||||
match val {
|
||||
Value::Object(obj) => {
|
||||
if let Some(node) = obj.as_any().downcast_ref::<SyntaxNode>() {
|
||||
return node.clone();
|
||||
}
|
||||
SyntaxNode {
|
||||
identity,
|
||||
kind: SyntaxKind::Constant(Value::Object(obj)),
|
||||
ty: (),
|
||||
}
|
||||
}
|
||||
Value::Quote(rc) => rc.as_ref().clone(),
|
||||
_ => SyntaxNode {
|
||||
identity,
|
||||
kind: SyntaxKind::Constant(val),
|
||||
@@ -659,7 +642,7 @@ mod tests {
|
||||
if let SyntaxKind::Identifier { symbol: ref sym, .. } = node.kind
|
||||
&& let Some(arg) = bindings.get(&sym.name)
|
||||
{
|
||||
return Ok(Value::Object(Rc::new(arg.clone()) as Rc<dyn Object>));
|
||||
return Ok(Value::Quote(Rc::new(arg.clone())));
|
||||
}
|
||||
Err(format!(
|
||||
"SimpleEvaluator cannot evaluate complex expression: {:?}",
|
||||
|
||||
@@ -22,7 +22,7 @@ use crate::ast::compiler::optimizer::Optimizer;
|
||||
use crate::ast::compiler::specializer::{FunctionRegistry, MonoCache, Specializer};
|
||||
use crate::ast::rtl::{self, intrinsics};
|
||||
use crate::ast::types::{
|
||||
NativeFunction, NodeIdentity, Object, Purity, SourceLocation, StaticType, Value,
|
||||
NativeFunction, NodeIdentity, Purity, SourceLocation, StaticType, Value,
|
||||
};
|
||||
|
||||
use crate::ast::diagnostics::{DiagnosticLevel, Diagnostics};
|
||||
@@ -121,7 +121,7 @@ impl MacroEvaluator for RuntimeMacroEvaluator {
|
||||
if let SyntaxKind::Identifier { symbol: sym, .. } = &node.kind
|
||||
&& let Some(arg_node) = bindings.get(&sym.name)
|
||||
{
|
||||
return Ok(Value::Object(Rc::new(arg_node.clone()) as Rc<dyn Object>));
|
||||
return Ok(Value::Quote(Rc::new(arg_node.clone())));
|
||||
}
|
||||
|
||||
let mut diag = Diagnostics::new();
|
||||
|
||||
+1
-13
@@ -1,5 +1,4 @@
|
||||
use crate::ast::types::{Identity, Keyword, Object, Purity, RecordLayout, StaticType, Value};
|
||||
use std::any::Any;
|
||||
use crate::ast::types::{Identity, Keyword, Purity, RecordLayout, StaticType, Value};
|
||||
use std::fmt::Debug;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
@@ -269,17 +268,6 @@ pub type SyntaxNode = Node<SyntaxPhase>;
|
||||
/// Type alias: the parser AST kind is now `NodeKind<SyntaxPhase>`.
|
||||
pub type SyntaxKind = NodeKind<SyntaxPhase>;
|
||||
|
||||
impl Object for Node<SyntaxPhase> {
|
||||
fn type_name(&self) -> &'static str {
|
||||
"ast-node"
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
fn into_rc_any(self: Rc<Self>) -> Rc<dyn Any> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub type TypedNode = Node<TypedPhase>;
|
||||
|
||||
|
||||
+6
-1
@@ -1,4 +1,5 @@
|
||||
use crate::ast::closure::Closure;
|
||||
use crate::ast::nodes::SyntaxNode;
|
||||
use chrono::{TimeZone, Utc};
|
||||
use std::any::Any;
|
||||
use std::cell::RefCell;
|
||||
@@ -263,7 +264,8 @@ pub enum Value {
|
||||
FieldAccessor(Keyword),
|
||||
Function(Rc<NativeFunction>),
|
||||
Closure(Rc<Closure>), // Compiled function with captured upvalues
|
||||
Object(Rc<dyn Object>), // For Series, Streams, SyntaxNodes, and custom extensions
|
||||
Quote(Rc<SyntaxNode>), // Quoted AST node (from 'expr or macro expansion)
|
||||
Object(Rc<dyn Object>), // RTL extensions: Series, Streams, and custom types
|
||||
Cell(Rc<RefCell<Value>>), // Boxed value for captures
|
||||
}
|
||||
|
||||
@@ -284,6 +286,7 @@ impl PartialEq for Value {
|
||||
(Value::FieldAccessor(a), Value::FieldAccessor(b)) => a == b,
|
||||
(Value::Function(a), Value::Function(b)) => Rc::ptr_eq(a, b),
|
||||
(Value::Closure(a), Value::Closure(b)) => Rc::ptr_eq(a, b),
|
||||
(Value::Quote(a), Value::Quote(b)) => Rc::ptr_eq(a, b),
|
||||
(Value::Object(a), Value::Object(b)) => Rc::ptr_eq(a, b),
|
||||
(Value::Cell(a), Value::Cell(b)) => Rc::ptr_eq(a, b),
|
||||
_ => false,
|
||||
@@ -625,6 +628,7 @@ impl Value {
|
||||
Value::FieldAccessor(k) => StaticType::FieldAccessor(*k),
|
||||
Value::Function(_) => StaticType::Any, // Dynamic function
|
||||
Value::Closure(_) => StaticType::Object("closure"),
|
||||
Value::Quote(_) => StaticType::Object("ast-node"),
|
||||
Value::Object(o) => StaticType::Object(o.type_name()),
|
||||
Value::Cell(c) => c.borrow().static_type(),
|
||||
}
|
||||
@@ -669,6 +673,7 @@ impl fmt::Display for Value {
|
||||
Value::FieldAccessor(k) => write!(f, ".{}", k.name()),
|
||||
Value::Function(f_meta) => write!(f, "<native fn, {:?}>", f_meta.purity),
|
||||
Value::Closure(_) => write!(f, "<closure>"),
|
||||
Value::Quote(_) => write!(f, "<ast-node>"),
|
||||
Value::Object(o) => write!(f, "<{:?}>", o),
|
||||
Value::Cell(c) => write!(f, "{}", c.borrow()),
|
||||
}
|
||||
|
||||
@@ -710,6 +710,7 @@ impl VM {
|
||||
Value::FieldAccessor(_) => "FieldAccessor",
|
||||
Value::Function(_) => "Function",
|
||||
Value::Closure(_) => "Closure",
|
||||
Value::Quote(_) => "Quote",
|
||||
Value::Object(_) => "Object",
|
||||
Value::Cell(_) => "Cell",
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user