refactor: separate parser and compiler AST node structures
Simplified the AST architecture by removing the overly complex Node<K,
T> structure and replacing it with specialized types for
each phase:
- Introduced UntypedNode in nodes.rs for the Parser and Macro system,
eliminating redundant ty: () initializations.
- Defined a new generic Node<T> in bound_nodes.rs for all compiler
stages, where T represents the phase-specific metadata.
- Updated the Binder to act as the bridge between UntypedNode and
Node<()>.
- Simplified type aliases: TypedNode, AnalyzedNode, and ExecNode now
leverage the streamlined Node<T> structure.
- Updated Parser, Macros, Type-Checker, Optimizer, and VM to reflect
the architectural changes.
- Fixed import chains and resolved needless borrows via clippy.
This change improves type safety, reduces boilerplate code in the
parser, and makes the compiler stages more idiomatic and
readable.
This commit is contained in:
+22
-22
@@ -1,8 +1,8 @@
|
||||
use crate::ast::compiler::bound_nodes::{
|
||||
Address, BoundKind, BoundNode, DeclarationKind, GlobalIdx, LocalSlot, UpvalueIdx,
|
||||
Address, BoundKind, DeclarationKind, GlobalIdx, LocalSlot, Node, UpvalueIdx,
|
||||
};
|
||||
use crate::ast::diagnostics::Diagnostics;
|
||||
use crate::ast::nodes::{Node, Symbol, UntypedKind};
|
||||
use crate::ast::nodes::{Symbol, UntypedKind, UntypedNode};
|
||||
use crate::ast::types::{Identity, StaticType, Purity};
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
@@ -114,7 +114,7 @@ pub enum ExprContext {
|
||||
}
|
||||
|
||||
pub type BindingResult = (
|
||||
BoundNode,
|
||||
Node,
|
||||
HashMap<Identity, Vec<Identity>>,
|
||||
Vec<CompilerScope>,
|
||||
u32,
|
||||
@@ -152,7 +152,7 @@ impl Binder {
|
||||
initial_scopes: Vec<CompilerScope>,
|
||||
initial_slot_count: u32,
|
||||
fixed_scope_idx: i32,
|
||||
node: &Node<UntypedKind>,
|
||||
node: &UntypedNode,
|
||||
diagnostics: &mut Diagnostics,
|
||||
) -> Result<BindingResult, String> {
|
||||
let mut binder = Self::new(initial_scopes, initial_slot_count, fixed_scope_idx);
|
||||
@@ -208,10 +208,10 @@ impl Binder {
|
||||
|
||||
pub fn bind(
|
||||
&mut self,
|
||||
node: &Node<UntypedKind>,
|
||||
node: &UntypedNode,
|
||||
ctx: ExprContext,
|
||||
diag: &mut Diagnostics,
|
||||
) -> BoundNode {
|
||||
) -> Node {
|
||||
match &node.kind {
|
||||
UntypedKind::Nop => self.make_node(node.identity.clone(), BoundKind::Nop),
|
||||
UntypedKind::Constant(v) => {
|
||||
@@ -241,10 +241,10 @@ impl Binder {
|
||||
then_br,
|
||||
else_br,
|
||||
} => {
|
||||
let cond = self.bind(cond, ExprContext::Expression, diag);
|
||||
let cond = self.bind(cond.as_ref(), ExprContext::Expression, diag);
|
||||
|
||||
self.functions.last_mut().unwrap().push_scope();
|
||||
let then_br = self.bind(then_br, ctx, diag);
|
||||
let then_br = self.bind(then_br.as_ref(), ctx, diag);
|
||||
self.functions.last_mut().unwrap().pop_scope();
|
||||
|
||||
let mut else_br_bound = None;
|
||||
@@ -296,7 +296,7 @@ impl Binder {
|
||||
}
|
||||
} else {
|
||||
let val_node = self.bind(value, ExprContext::Expression, diag);
|
||||
let target_node = self.bind_pattern(target, DeclarationKind::Variable, diag);
|
||||
let target_node = self.bind_pattern(target.as_ref(), DeclarationKind::Variable, diag);
|
||||
|
||||
self.make_node(
|
||||
node.identity.clone(),
|
||||
@@ -324,7 +324,7 @@ impl Binder {
|
||||
self.make_node(node.identity.clone(), BoundKind::Error)
|
||||
}
|
||||
} else {
|
||||
let target_node = self.bind_assign_pattern(target, diag);
|
||||
let target_node = self.bind_assign_pattern(target.as_ref(), diag);
|
||||
self.make_node(
|
||||
node.identity.clone(),
|
||||
BoundKind::Destructure {
|
||||
@@ -357,11 +357,11 @@ impl Binder {
|
||||
self.functions
|
||||
.push(FunctionCompiler::new(identity.clone(), vec![], 0));
|
||||
|
||||
let params_bound = self.bind_pattern(params, DeclarationKind::Parameter, diag);
|
||||
let body_bound = self.bind(body, ExprContext::Expression, diag);
|
||||
let params_bound = self.bind_pattern(params.as_ref(), DeclarationKind::Parameter, diag);
|
||||
let body_bound = self.bind(body.as_ref(), ExprContext::Expression, diag);
|
||||
let compiled_fn = self.functions.pop().unwrap();
|
||||
|
||||
fn count_params(node: &BoundNode) -> Option<u32> {
|
||||
fn count_params(node: &Node) -> Option<u32> {
|
||||
match &node.kind {
|
||||
BoundKind::Define {
|
||||
kind: DeclarationKind::Parameter,
|
||||
@@ -394,7 +394,7 @@ impl Binder {
|
||||
|
||||
UntypedKind::Call { callee, args } => {
|
||||
let callee = self.bind(callee, ExprContext::Expression, diag);
|
||||
let args = self.bind(args, ExprContext::Expression, diag);
|
||||
let args = self.bind(args.as_ref(), ExprContext::Expression, diag);
|
||||
|
||||
self.make_node(
|
||||
node.identity.clone(),
|
||||
@@ -413,7 +413,7 @@ impl Binder {
|
||||
);
|
||||
return self.make_node(node.identity.clone(), BoundKind::Error);
|
||||
}
|
||||
let args = self.bind(args, ExprContext::Expression, diag);
|
||||
let args = self.bind(args.as_ref(), ExprContext::Expression, diag);
|
||||
self.make_node(
|
||||
node.identity.clone(),
|
||||
BoundKind::Again {
|
||||
@@ -489,7 +489,7 @@ impl Binder {
|
||||
}
|
||||
|
||||
UntypedKind::Expansion { call, expanded } => {
|
||||
let bound_expanded = self.bind(expanded, ctx, diag);
|
||||
let bound_expanded = self.bind(expanded.as_ref(), ctx, diag);
|
||||
self.make_node(
|
||||
node.identity.clone(),
|
||||
BoundKind::Expansion {
|
||||
@@ -520,7 +520,7 @@ impl Binder {
|
||||
);
|
||||
self.make_node(node.identity.clone(), BoundKind::Error)
|
||||
}
|
||||
UntypedKind::Error => crate::ast::compiler::bound_nodes::BoundNode {
|
||||
UntypedKind::Error => crate::ast::compiler::bound_nodes::Node {
|
||||
identity: node.identity.clone(),
|
||||
kind: crate::ast::compiler::bound_nodes::BoundKind::Error,
|
||||
ty: (),
|
||||
@@ -600,10 +600,10 @@ impl Binder {
|
||||
|
||||
fn bind_pattern(
|
||||
&mut self,
|
||||
node: &Node<UntypedKind>,
|
||||
node: &UntypedNode,
|
||||
kind: DeclarationKind,
|
||||
diag: &mut Diagnostics,
|
||||
) -> BoundNode {
|
||||
) -> Node {
|
||||
match &node.kind {
|
||||
UntypedKind::Identifier(sym) => {
|
||||
if let Some(addr) = self.declare_variable(sym, node.identity.clone(), kind, diag) {
|
||||
@@ -645,9 +645,9 @@ impl Binder {
|
||||
|
||||
fn bind_assign_pattern(
|
||||
&mut self,
|
||||
node: &Node<UntypedKind>,
|
||||
node: &UntypedNode,
|
||||
diag: &mut Diagnostics,
|
||||
) -> BoundNode {
|
||||
) -> Node {
|
||||
match &node.kind {
|
||||
UntypedKind::Identifier(sym) => {
|
||||
if let Some(addr) = self.resolve_variable(sym, diag, &node.identity) {
|
||||
@@ -684,7 +684,7 @@ impl Binder {
|
||||
}
|
||||
}
|
||||
|
||||
fn make_node(&self, identity: Identity, kind: BoundKind<()>) -> BoundNode {
|
||||
fn make_node(&self, identity: Identity, kind: BoundKind<()>) -> Node {
|
||||
Node {
|
||||
identity,
|
||||
kind,
|
||||
|
||||
Reference in New Issue
Block a user