Update various types to use their own definitions

This commit refactors several modules to use the defined types from
`ast::types` and `ast::nodes` directly, rather than using fully
qualified paths. This improves code readability and reduces redundancy.

Specifically, the following changes were made:

- In `analyzer.rs`, `crate::ast::types::Identity` and
  `crate::ast::types::Purity` are now used directly.
- In `binder.rs`, `crate::ast::types::NodeIdentity`,
  `crate::ast::types::SourceLocation`,
  `crate::ast::types::RecordLayout`, and `crate::ast::types::Value` are
  now used directly.
- In `macros.rs`, types like `Address`, `VirtualId`, `NodeIdentity`,
  `SourceLocation`, `StaticType`, and `Purity` are now used directly.
- In `optimizer/engine.rs`, `Address<VirtualId>` is now used directly.
- In `type_checker.rs`, `BoundPhase`, `Signature`, `Keyword`, and
  `RecordLayout` are now used directly.
- In `environment.rs`, `CompilerScope`, `LocalInfo`, `CapturePass`,
  `AnalyzedPhase`, `NativeFunction`, and `Closure` are now used
  directly.
- In `nodes.rs`, `RecordLayout`, `Keyword`, `Purity`, and `StaticType`
  are now used directly.
- In `parser.rs`, `SourceLocation` and `NodeIdentity` are now used
  directly.
- In `rtl/math.rs`, `NativeFunction`, `Purity`, `Signature`,
  `StaticType`, `Value`, `RefCell`, and `Rc` are now used directly.
- In `rtl/streams.rs`, `ScalarValue`, `SeriesMember`, `Object`,
  `PipeFn`, `Value`, `VM`, `RingBuffer`, `RecordSeries`, `SeriesView`,
  `build_map_stream`, and `build_pipeline_node` are now used directly.
- In `rtl/type_registry.rs`, `RecordLayout`, `Keyword`, `Purity`,
  `Signature`, `StaticType`, and `Value` are now used directly.
- In `vm.rs`, `RecordSeries`, `SeriesView`, `build_map_stream`,
  `build_pipeline_node`, `StreamNode`, `Object`, and `PipeFn` are now
  used directly.
- In `utils/tester.rs`, `TypedNode` is now used directly.
This commit is contained in:
2026-03-22 18:30:56 +01:00
parent 1cbc656554
commit 007446a167
13 changed files with 112 additions and 104 deletions
+4 -4
View File
@@ -2,18 +2,18 @@ use crate::ast::nodes::{
Address, AnalyzedNode, GlobalIdx, IdentifierBinding, Node, Address, AnalyzedNode, GlobalIdx, IdentifierBinding, Node,
NodeKind, NodeMetrics, TypedNode, TypedPhase, NodeKind, NodeMetrics, TypedNode, TypedPhase,
}; };
use crate::ast::types::Purity; use crate::ast::types::{Identity, Purity};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::rc::Rc; use std::rc::Rc;
pub struct Analyzer<'a> { pub struct Analyzer<'a> {
root_purity: &'a [Purity], root_purity: &'a [Purity],
/// Stack of currently visiting lambdas to detect direct recursion. /// Stack of currently visiting lambdas to detect direct recursion.
lambda_stack: Vec<crate::ast::types::Identity>, lambda_stack: Vec<Identity>,
/// Map of global index to its Lambda identity if known. /// Map of global index to its Lambda identity if known.
globals_to_lambdas: HashMap<GlobalIdx, crate::ast::types::Identity>, globals_to_lambdas: HashMap<GlobalIdx, Identity>,
/// Set of identities that were found to be recursive. /// Set of identities that were found to be recursive.
recursive_identities: HashSet<crate::ast::types::Identity>, recursive_identities: HashSet<Identity>,
} }
impl<'a> Analyzer<'a> { impl<'a> Analyzer<'a> {
+5 -5
View File
@@ -4,7 +4,7 @@ use crate::ast::nodes::{
UpvalueIdx, VirtualId, UpvalueIdx, VirtualId,
}; };
use crate::ast::diagnostics::Diagnostics; use crate::ast::diagnostics::Diagnostics;
use crate::ast::types::{Identity, Purity, StaticType}; use crate::ast::types::{Identity, NodeIdentity, Purity, RecordLayout, SourceLocation, StaticType, Value};
use std::collections::HashMap; use std::collections::HashMap;
use std::rc::Rc; use std::rc::Rc;
@@ -139,7 +139,7 @@ impl Binder {
fixed_scope_idx, fixed_scope_idx,
}; };
binder.functions.push(FunctionCompiler::new( binder.functions.push(FunctionCompiler::new(
crate::ast::types::NodeIdentity::new(crate::ast::types::SourceLocation { NodeIdentity::new(SourceLocation {
line: 0, line: 0,
col: 0, col: 0,
}), }),
@@ -488,10 +488,10 @@ impl Binder {
let key_node = self.bind(k, ExprContext::Expression, diag); let key_node = self.bind(k, ExprContext::Expression, diag);
let val_node = self.bind(v, ExprContext::Expression, diag); let val_node = self.bind(v, ExprContext::Expression, diag);
if let NodeKind::Constant(crate::ast::types::Value::Keyword(kw)) = if let NodeKind::Constant(Value::Keyword(kw)) =
&key_node.kind &key_node.kind
{ {
layout_fields.push((*kw, crate::ast::types::StaticType::Any)); layout_fields.push((*kw, StaticType::Any));
} else { } else {
diag.push_error( diag.push_error(
format!( format!(
@@ -504,7 +504,7 @@ impl Binder {
bound_fields.push((Rc::new(key_node), Rc::new(val_node))); bound_fields.push((Rc::new(key_node), Rc::new(val_node)));
} }
let layout = crate::ast::types::RecordLayout::get_or_create(layout_fields); let layout = RecordLayout::get_or_create(layout_fields);
self.make_node( self.make_node(
node.identity.clone(), node.identity.clone(),
+13 -11
View File
@@ -642,10 +642,12 @@ impl<E: MacroEvaluator> MacroExpander<E> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::ast::nodes::Address; use crate::ast::compiler::binder::{CompilerScope, LocalInfo};
use crate::ast::compiler::Binder; use crate::ast::compiler::Binder;
use crate::ast::diagnostics::Diagnostics;
use crate::ast::nodes::{Address, VirtualId};
use crate::ast::parser::Parser; use crate::ast::parser::Parser;
use crate::ast::types::{Object, Value}; use crate::ast::types::{NodeIdentity, Object, Purity, SourceLocation, StaticType, Value};
struct SimpleEvaluator; struct SimpleEvaluator;
impl MacroEvaluator for SimpleEvaluator { impl MacroEvaluator for SimpleEvaluator {
@@ -787,19 +789,19 @@ mod tests {
let mut locals = HashMap::new(); let mut locals = HashMap::new();
locals.insert( locals.insert(
Symbol::from("*"), Symbol::from("*"),
crate::ast::compiler::binder::LocalInfo { LocalInfo {
addr: Address::Local(crate::ast::nodes::VirtualId(0)), addr: Address::Local(VirtualId(0)),
identity: crate::ast::types::NodeIdentity::new(crate::ast::types::SourceLocation { identity: NodeIdentity::new(SourceLocation {
line: 0, line: 0,
col: 0, col: 0,
}), }),
_ty: crate::ast::types::StaticType::Any, _ty: StaticType::Any,
purity: crate::ast::types::Purity::Pure, purity: Purity::Pure,
}, },
); );
let initial_scopes = vec![crate::ast::compiler::binder::CompilerScope { locals }]; let initial_scopes = vec![CompilerScope { locals }];
let mut diag = crate::ast::diagnostics::Diagnostics::new(); let mut diag = Diagnostics::new();
// fixed_scope_idx = 0 means scope 0 is frozen (Global) // fixed_scope_idx = 0 means scope 0 is frozen (Global)
let result = Binder::bind_root(initial_scopes, 1, 0, &expanded, &mut diag); let result = Binder::bind_root(initial_scopes, 1, 0, &expanded, &mut diag);
assert!( assert!(
@@ -824,7 +826,7 @@ mod tests {
let mut expander = MacroExpander::new(MacroRegistry::new(), SimpleEvaluator); let mut expander = MacroExpander::new(MacroRegistry::new(), SimpleEvaluator);
let expanded = expander.expand(syntax).unwrap(); let expanded = expander.expand(syntax).unwrap();
let mut diag = crate::ast::diagnostics::Diagnostics::new(); let mut diag = Diagnostics::new();
let result = Binder::bind_root(vec![], 0, 0, &expanded, &mut diag); let result = Binder::bind_root(vec![], 0, 0, &expanded, &mut diag);
assert!(result.is_ok(), "Hygiene failed: {:?}", result.err()); assert!(result.is_ok(), "Hygiene failed: {:?}", result.err());
} }
@@ -844,7 +846,7 @@ mod tests {
let mut expander = MacroExpander::new(MacroRegistry::new(), SimpleEvaluator); let mut expander = MacroExpander::new(MacroRegistry::new(), SimpleEvaluator);
let expanded = expander.expand(syntax).unwrap(); let expanded = expander.expand(syntax).unwrap();
let mut diag = crate::ast::diagnostics::Diagnostics::new(); let mut diag = Diagnostics::new();
let result = Binder::bind_root(vec![], 0, 0, &expanded, &mut diag); let result = Binder::bind_root(vec![], 0, 0, &expanded, &mut diag);
assert!( assert!(
result.is_ok(), result.is_ok(),
+2 -2
View File
@@ -1,6 +1,6 @@
use crate::ast::nodes::{ use crate::ast::nodes::{
Address, AnalyzedNode, AssignBinding, GlobalAnalyzedRegistry, Address, AnalyzedNode, AssignBinding, GlobalAnalyzedRegistry,
IdentifierBinding, LambdaBinding, Node, NodeKind, UpvalueIdx, IdentifierBinding, LambdaBinding, Node, NodeKind, UpvalueIdx, VirtualId,
}; };
use crate::ast::types::{Purity, Value}; use crate::ast::types::{Purity, Value};
use crate::ast::vm::Closure; use crate::ast::vm::Closure;
@@ -756,7 +756,7 @@ impl Optimizer {
} }
/// Extracts the address from a Def pattern node (when it's a simple Identifier with Declaration binding). /// Extracts the address from a Def pattern node (when it's a simple Identifier with Declaration binding).
fn extract_def_addr(pattern: &AnalyzedNode) -> Option<Address<crate::ast::nodes::VirtualId>> { fn extract_def_addr(pattern: &AnalyzedNode) -> Option<Address<VirtualId>> {
if let NodeKind::Identifier { if let NodeKind::Identifier {
binding: IdentifierBinding::Declaration { addr, .. }, binding: IdentifierBinding::Declaration { addr, .. },
.. ..
+10 -9
View File
@@ -1,9 +1,9 @@
use crate::ast::nodes::{ use crate::ast::nodes::{
Address, AssignBinding, BoundLike, DefBinding, IdentifierBinding, LambdaBinding, Node, Address, AssignBinding, BoundLike, BoundPhase, DefBinding, IdentifierBinding, LambdaBinding,
NodeKind, TypedNode, TypedPhase, VirtualId, Node, NodeKind, TypedNode, TypedPhase, VirtualId,
}; };
use crate::ast::diagnostics::Diagnostics; use crate::ast::diagnostics::Diagnostics;
use crate::ast::types::StaticType; use crate::ast::types::{Keyword, RecordLayout, Signature, StaticType};
use std::collections::HashMap; use std::collections::HashMap;
use std::rc::Rc; use std::rc::Rc;
@@ -84,7 +84,7 @@ impl TypeChecker {
pub fn check( pub fn check(
&self, &self,
node: &Node<crate::ast::nodes::BoundPhase>, node: &Node<BoundPhase>,
arg_types: &[StaticType], arg_types: &[StaticType],
diag: &mut Diagnostics, diag: &mut Diagnostics,
) -> TypedNode { ) -> TypedNode {
@@ -134,7 +134,7 @@ impl TypeChecker {
let ret_ty = body_typed.ty.clone(); let ret_ty = body_typed.ty.clone();
let final_params_ty = params_typed.ty.clone(); let final_params_ty = params_typed.ty.clone();
let fn_ty = StaticType::Function(Box::new(crate::ast::types::Signature { let fn_ty = StaticType::Function(Box::new(Signature {
params: final_params_ty, params: final_params_ty,
ret: ret_ty, ret: ret_ty,
})); }));
@@ -319,7 +319,7 @@ impl TypeChecker {
StaticType::Record(layout) => layout StaticType::Record(layout) => layout
.fields .fields
.get(i) .get(i)
.map(|(_, ty): &(crate::ast::types::Keyword, StaticType)| ty.clone()) .map(|(_, ty): &(Keyword, StaticType)| ty.clone())
.unwrap_or(StaticType::Any), .unwrap_or(StaticType::Any),
StaticType::Error => StaticType::Error, StaticType::Error => StaticType::Error,
_ => StaticType::Any, _ => StaticType::Any,
@@ -627,7 +627,7 @@ impl TypeChecker {
let body_typed = self.check_node(body, &mut lambda_ctx, diag); let body_typed = self.check_node(body, &mut lambda_ctx, diag);
let ret_ty = body_typed.ty.clone(); let ret_ty = body_typed.ty.clone();
let fn_ty = StaticType::Function(Box::new(crate::ast::types::Signature { let fn_ty = StaticType::Function(Box::new(Signature {
params: params_typed.ty.clone(), params: params_typed.ty.clone(),
ret: ret_ty, ret: ret_ty,
})); }));
@@ -780,7 +780,7 @@ impl TypeChecker {
typed_fields.push((Rc::new(kt), Rc::new(vt))); typed_fields.push((Rc::new(kt), Rc::new(vt)));
} }
let new_layout = crate::ast::types::RecordLayout::get_or_create(fields_ty); let new_layout = RecordLayout::get_or_create(fields_ty);
( (
NodeKind::Record { NodeKind::Record {
fields: typed_fields, fields: typed_fields,
@@ -841,10 +841,11 @@ impl TypeChecker {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::ast::environment::Environment;
use crate::ast::types::StaticType; use crate::ast::types::StaticType;
fn check_source(source: &str) -> TypedNode { fn check_source(source: &str) -> TypedNode {
let env = crate::ast::environment::Environment::new(); let env = Environment::new();
env.compile(source).into_result().unwrap() env.compile(source).into_result().unwrap()
} }
+27 -27
View File
@@ -1,9 +1,9 @@
use crate::ast::compiler::analyzer::Analyzer; use crate::ast::compiler::analyzer::Analyzer;
use crate::ast::compiler::binder::Binder; use crate::ast::compiler::binder::{Binder, CompilerScope, LocalInfo};
use crate::ast::compiler::{TypeChecker, TypedNode}; use crate::ast::compiler::{CapturePass, TypeChecker, TypedNode};
use crate::ast::nodes::{Symbol, SyntaxKind, SyntaxNode}; use crate::ast::nodes::{AnalyzedPhase, Symbol, SyntaxKind, SyntaxNode};
use crate::ast::parser::Parser; use crate::ast::parser::Parser;
use crate::ast::vm::{TracingObserver, VM}; use crate::ast::vm::{Closure, TracingObserver, VM};
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@@ -19,9 +19,9 @@ use crate::ast::compiler::lowering::Lowering;
use crate::ast::compiler::macros::{MacroEvaluator, MacroExpander, MacroRegistry}; use crate::ast::compiler::macros::{MacroEvaluator, MacroExpander, MacroRegistry};
use crate::ast::compiler::optimizer::Optimizer; use crate::ast::compiler::optimizer::Optimizer;
use crate::ast::compiler::specializer::{FunctionRegistry, MonoCache, Specializer}; use crate::ast::compiler::specializer::{FunctionRegistry, MonoCache, Specializer};
use crate::ast::rtl::intrinsics; use crate::ast::rtl::{self, intrinsics};
use crate::ast::types::{ use crate::ast::types::{
NodeIdentity, Object, Purity, SourceLocation, StaticType, Value, NativeFunction, NodeIdentity, Object, Purity, SourceLocation, StaticType, Value,
}; };
use crate::ast::diagnostics::{DiagnosticLevel, Diagnostics}; use crate::ast::diagnostics::{DiagnosticLevel, Diagnostics};
@@ -75,7 +75,7 @@ pub struct Environment {
pub root_purity: Rc<RefCell<Vec<Purity>>>, pub root_purity: Rc<RefCell<Vec<Purity>>>,
pub root_values: Rc<RefCell<Vec<Value>>>, pub root_values: Rc<RefCell<Vec<Value>>>,
pub fixed_scope_idx: i32, pub fixed_scope_idx: i32,
pub root_scopes: Rc<RefCell<Vec<crate::ast::compiler::binder::CompilerScope>>>, pub root_scopes: Rc<RefCell<Vec<CompilerScope>>>,
pub root_slot_count: Rc<RefCell<u32>>, pub root_slot_count: Rc<RefCell<u32>>,
pub function_registry: Rc<RefCell<GlobalFunctionRegistry>>, pub function_registry: Rc<RefCell<GlobalFunctionRegistry>>,
pub typed_function_registry: Rc<RefCell<GlobalAnalyzedRegistry>>, pub typed_function_registry: Rc<RefCell<GlobalAnalyzedRegistry>>,
@@ -93,7 +93,7 @@ struct EnvFunctionRegistry {
} }
impl FunctionRegistry for EnvFunctionRegistry { impl FunctionRegistry for EnvFunctionRegistry {
fn resolve(&self, addr: Address<VirtualId>) -> Option<Rc<Node<crate::ast::nodes::AnalyzedPhase>>> { fn resolve(&self, addr: Address<VirtualId>) -> Option<Rc<Node<AnalyzedPhase>>> {
if let Address::Global(idx) = addr { if let Address::Global(idx) = addr {
self.analyzed_registry.borrow().get(&idx).cloned() self.analyzed_registry.borrow().get(&idx).cloned()
} else { } else {
@@ -103,7 +103,7 @@ impl FunctionRegistry for EnvFunctionRegistry {
} }
struct RuntimeMacroEvaluator { struct RuntimeMacroEvaluator {
root_scopes: Rc<RefCell<Vec<crate::ast::compiler::binder::CompilerScope>>>, root_scopes: Rc<RefCell<Vec<CompilerScope>>>,
root_slot_count: Rc<RefCell<u32>>, root_slot_count: Rc<RefCell<u32>>,
root_types: Rc<RefCell<Vec<StaticType>>>, root_types: Rc<RefCell<Vec<StaticType>>>,
root_values: Rc<RefCell<Vec<Value>>>, root_values: Rc<RefCell<Vec<Value>>>,
@@ -128,7 +128,7 @@ impl MacroEvaluator for RuntimeMacroEvaluator {
let initial_slot_count = *self.root_slot_count.borrow(); let initial_slot_count = *self.root_slot_count.borrow();
let (bound_ast, captures, _, _) = Binder::bind_root(initial_scopes, initial_slot_count, self.fixed_scope_idx, node, &mut diag)?; let (bound_ast, captures, _, _) = Binder::bind_root(initial_scopes, initial_slot_count, self.fixed_scope_idx, node, &mut diag)?;
let bound_ast = crate::ast::compiler::captures::CapturePass::apply(bound_ast, &captures); let bound_ast = CapturePass::apply(bound_ast, &captures);
let checker = TypeChecker::new(self.root_types.clone()); let checker = TypeChecker::new(self.root_types.clone());
let typed_ast = checker.check(&bound_ast, &[], &mut diag); let typed_ast = checker.check(&bound_ast, &[], &mut diag);
@@ -161,7 +161,7 @@ impl Environment {
root_purity: Rc::new(RefCell::new(Vec::new())), root_purity: Rc::new(RefCell::new(Vec::new())),
root_values: Rc::new(RefCell::new(Vec::new())), root_values: Rc::new(RefCell::new(Vec::new())),
fixed_scope_idx: -1, fixed_scope_idx: -1,
root_scopes: Rc::new(RefCell::new(vec![crate::ast::compiler::binder::CompilerScope::new()])), root_scopes: Rc::new(RefCell::new(vec![CompilerScope::new()])),
root_slot_count: Rc::new(RefCell::new(0)), root_slot_count: Rc::new(RefCell::new(0)),
function_registry: Rc::new(RefCell::new(HashMap::new())), function_registry: Rc::new(RefCell::new(HashMap::new())),
typed_function_registry: Rc::new(RefCell::new(HashMap::new())), typed_function_registry: Rc::new(RefCell::new(HashMap::new())),
@@ -173,12 +173,12 @@ impl Environment {
search_paths: Rc::new(RefCell::new(Vec::new())), search_paths: Rc::new(RefCell::new(Vec::new())),
loaded_modules: Rc::new(RefCell::new(HashSet::new())), loaded_modules: Rc::new(RefCell::new(HashSet::new())),
}; };
crate::ast::rtl::register(&env); rtl::register(&env);
let mut env = env; let mut env = env;
env.fixed_scope_idx = 0; env.fixed_scope_idx = 0;
// Push the first mutable user scope (Level 1) // Push the first mutable user scope (Level 1)
env.root_scopes.borrow_mut().push(crate::ast::compiler::binder::CompilerScope::new()); env.root_scopes.borrow_mut().push(CompilerScope::new());
// Automatically add standard search paths (CWD and CWD/rtl) // Automatically add standard search paths (CWD and CWD/rtl)
if let Ok(cwd) = std::env::current_dir() { if let Ok(cwd) = std::env::current_dir() {
@@ -401,7 +401,7 @@ impl Environment {
let slot = VirtualId(*slot_count); let slot = VirtualId(*slot_count);
current_scope.locals.insert( current_scope.locals.insert(
sym.clone(), sym.clone(),
crate::ast::compiler::binder::LocalInfo { LocalInfo {
addr: Address::Local(slot), addr: Address::Local(slot),
identity: node.identity.clone(), identity: node.identity.clone(),
_ty: StaticType::Any, _ty: StaticType::Any,
@@ -462,7 +462,7 @@ impl Environment {
*self.root_scopes.borrow_mut() = final_scopes; *self.root_scopes.borrow_mut() = final_scopes;
*self.root_slot_count.borrow_mut() = final_slot_count; *self.root_slot_count.borrow_mut() = final_slot_count;
let bound_ast = crate::ast::compiler::captures::CapturePass::apply(bound_ast, &captures); let bound_ast = CapturePass::apply(bound_ast, &captures);
// Pre-allocate global slots to prevent out-of-bounds during specialization/optimization // Pre-allocate global slots to prevent out-of-bounds during specialization/optimization
{ {
@@ -520,7 +520,7 @@ impl Environment {
&self, &self,
name: &str, name: &str,
ty: StaticType, ty: StaticType,
func: Rc<crate::ast::types::NativeFunction>, func: Rc<NativeFunction>,
) { ) {
let mut types = self.root_types.borrow_mut(); let mut types = self.root_types.borrow_mut();
let mut values = self.root_values.borrow_mut(); let mut values = self.root_values.borrow_mut();
@@ -535,7 +535,7 @@ impl Environment {
let global_idx = GlobalIdx(*slot_count); let global_idx = GlobalIdx(*slot_count);
root_scopes[0].locals.insert( root_scopes[0].locals.insert(
Symbol::from(name), Symbol::from(name),
crate::ast::compiler::binder::LocalInfo { LocalInfo {
addr: Address::Global(global_idx), addr: Address::Global(global_idx),
identity, identity,
_ty: ty.clone(), _ty: ty.clone(),
@@ -559,7 +559,7 @@ impl Environment {
self.register_native( self.register_native(
name, name,
ty, ty,
Rc::new(crate::ast::types::NativeFunction { Rc::new(NativeFunction {
func: Rc::new(func), func: Rc::new(func),
purity: purity_level, purity: purity_level,
}), }),
@@ -580,7 +580,7 @@ impl Environment {
let global_idx = GlobalIdx(*slot_count); let global_idx = GlobalIdx(*slot_count);
root_scopes[0].locals.insert( root_scopes[0].locals.insert(
Symbol::from(name), Symbol::from(name),
crate::ast::compiler::binder::LocalInfo { LocalInfo {
addr: Address::Global(global_idx), addr: Address::Global(global_idx),
identity, identity,
_ty: ty.clone(), _ty: ty.clone(),
@@ -650,7 +650,7 @@ impl Environment {
Lowering::lower(optimized) Lowering::lower(optimized)
} }
pub fn instantiate(&self, node: ExecNode) -> Rc<crate::ast::types::NativeFunction> { pub fn instantiate(&self, node: ExecNode) -> Rc<NativeFunction> {
let root_values = self.root_values.clone(); let root_values = self.root_values.clone();
if let NodeKind::Lambda { if let NodeKind::Lambda {
params, params,
@@ -659,7 +659,7 @@ impl Environment {
} = &node.kind } = &node.kind
&& info.upvalues.is_empty() && info.upvalues.is_empty()
{ {
let closure = Rc::new(crate::ast::vm::Closure::new( let closure = Rc::new(Closure::new(
params.clone(), params.clone(),
body.ty.original.clone(), body.ty.original.clone(),
body.clone(), body.clone(),
@@ -667,9 +667,9 @@ impl Environment {
info.positional_count, info.positional_count,
node.ty.stack_size, node.ty.stack_size,
)); ));
let closure_obj: Rc<dyn crate::ast::types::Object> = closure; let closure_obj: Rc<dyn Object> = closure;
return Rc::new(crate::ast::types::NativeFunction { return Rc::new(NativeFunction {
purity: Purity::Impure, purity: Purity::Impure,
func: Rc::new(move |args| { func: Rc::new(move |args| {
let mut vm = VM::new(root_values.clone()); let mut vm = VM::new(root_values.clone());
@@ -682,7 +682,7 @@ impl Environment {
} }
let exec_node = Rc::new(node); let exec_node = Rc::new(node);
Rc::new(crate::ast::types::NativeFunction { Rc::new(NativeFunction {
purity: Purity::Impure, purity: Purity::Impure,
func: Rc::new(move |args| { func: Rc::new(move |args| {
let mut vm = VM::new(root_values.clone()); let mut vm = VM::new(root_values.clone());
@@ -694,7 +694,7 @@ impl Environment {
if let Value::Object(obj) = &res if let Value::Object(obj) = &res
&& obj && obj
.as_any() .as_any()
.downcast_ref::<crate::ast::vm::Closure>() .downcast_ref::<Closure>()
.is_some() .is_some()
{ {
match vm.run_with_args(obj.clone(), args) { match vm.run_with_args(obj.clone(), args) {
@@ -722,7 +722,7 @@ impl Environment {
let optimization = self.optimization; let optimization = self.optimization;
let compiler = Rc::new( let compiler = Rc::new(
move |func_template: Rc<Node<crate::ast::nodes::AnalyzedPhase>>, move |func_template: Rc<Node<AnalyzedPhase>>,
arg_types: &[StaticType]| arg_types: &[StaticType]|
-> Result<(Value, StaticType), String> { -> Result<(Value, StaticType), String> {
let mut diag = Diagnostics::new(); let mut diag = Diagnostics::new();
@@ -837,7 +837,7 @@ impl Environment {
// All Myc scripts are wrapped in a parameterless lambda for consistency. // All Myc scripts are wrapped in a parameterless lambda for consistency.
let mut final_result = result; let mut final_result = result;
if let Ok(Value::Object(obj)) = &final_result if let Ok(Value::Object(obj)) = &final_result
&& let Some(_closure) = obj.as_any().downcast_ref::<crate::ast::vm::Closure>() && let Some(_closure) = obj.as_any().downcast_ref::<Closure>()
{ {
final_result = vm.run_with_args_observed(&mut observer, obj.clone(), &[]); final_result = vm.run_with_args_observed(&mut observer, obj.clone(), &[]);
} }
+10 -10
View File
@@ -1,4 +1,4 @@
use crate::ast::types::{Identity, Object, StaticType, Value}; use crate::ast::types::{Identity, Keyword, Object, Purity, RecordLayout, StaticType, Value};
use std::any::Any; use std::any::Any;
use std::fmt::Debug; use std::fmt::Debug;
use std::rc::Rc; use std::rc::Rc;
@@ -176,7 +176,7 @@ impl CompilerPhase for BoundPhase {
type DefInfo = DefBinding; type DefInfo = DefBinding;
type AssignInfo = AssignBinding<VirtualId>; type AssignInfo = AssignBinding<VirtualId>;
type LambdaInfo = LambdaBinding<VirtualId>; type LambdaInfo = LambdaBinding<VirtualId>;
type RecordLayout = Arc<crate::ast::types::RecordLayout>; type RecordLayout = Arc<RecordLayout>;
} }
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
@@ -188,7 +188,7 @@ impl CompilerPhase for TypedPhase {
type DefInfo = DefBinding; type DefInfo = DefBinding;
type AssignInfo = AssignBinding<VirtualId>; type AssignInfo = AssignBinding<VirtualId>;
type LambdaInfo = LambdaBinding<VirtualId>; type LambdaInfo = LambdaBinding<VirtualId>;
type RecordLayout = Arc<crate::ast::types::RecordLayout>; type RecordLayout = Arc<RecordLayout>;
} }
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
@@ -200,7 +200,7 @@ impl CompilerPhase for AnalyzedPhase {
type DefInfo = DefBinding; type DefInfo = DefBinding;
type AssignInfo = AssignBinding<VirtualId>; type AssignInfo = AssignBinding<VirtualId>;
type LambdaInfo = LambdaBinding<VirtualId>; type LambdaInfo = LambdaBinding<VirtualId>;
type RecordLayout = Arc<crate::ast::types::RecordLayout>; type RecordLayout = Arc<RecordLayout>;
} }
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
@@ -212,7 +212,7 @@ impl CompilerPhase for RuntimePhase {
type DefInfo = DefBinding; type DefInfo = DefBinding;
type AssignInfo = AssignBinding<StackOffset>; type AssignInfo = AssignBinding<StackOffset>;
type LambdaInfo = LambdaBinding<StackOffset>; type LambdaInfo = LambdaBinding<StackOffset>;
type RecordLayout = Arc<crate::ast::types::RecordLayout>; type RecordLayout = Arc<RecordLayout>;
} }
/// Convenience alias for all post-binding phases that share the same /// Convenience alias for all post-binding phases that share the same
@@ -225,7 +225,7 @@ pub trait BoundLike:
DefInfo = DefBinding, DefInfo = DefBinding,
AssignInfo = AssignBinding<VirtualId>, AssignInfo = AssignBinding<VirtualId>,
LambdaInfo = LambdaBinding<VirtualId>, LambdaInfo = LambdaBinding<VirtualId>,
RecordLayout = Arc<crate::ast::types::RecordLayout>, RecordLayout = Arc<RecordLayout>,
> >
{ {
} }
@@ -237,7 +237,7 @@ impl<P> BoundLike for P where
DefInfo = DefBinding, DefInfo = DefBinding,
AssignInfo = AssignBinding<VirtualId>, AssignInfo = AssignBinding<VirtualId>,
LambdaInfo = LambdaBinding<VirtualId>, LambdaInfo = LambdaBinding<VirtualId>,
RecordLayout = Arc<crate::ast::types::RecordLayout>, RecordLayout = Arc<RecordLayout>,
> >
{ {
} }
@@ -283,7 +283,7 @@ pub type TypedNode = Node<TypedPhase>;
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct NodeMetrics { pub struct NodeMetrics {
pub original: Rc<TypedNode>, pub original: Rc<TypedNode>,
pub purity: crate::ast::types::Purity, pub purity: Purity,
pub is_recursive: bool, pub is_recursive: bool,
} }
@@ -370,7 +370,7 @@ pub enum NodeKind<P: CompilerPhase = SyntaxPhase> {
symbol: Symbol, symbol: Symbol,
binding: P::Binding, binding: P::Binding,
}, },
FieldAccessor(crate::ast::types::Keyword), FieldAccessor(Keyword),
If { If {
cond: Rc<Node<P>>, cond: Rc<Node<P>>,
then_br: Rc<Node<P>>, then_br: Rc<Node<P>>,
@@ -427,7 +427,7 @@ pub enum NodeKind<P: CompilerPhase = SyntaxPhase> {
/// Optimized field access (only created during lowering for `RuntimePhase`). /// Optimized field access (only created during lowering for `RuntimePhase`).
GetField { GetField {
rec: Rc<Node<P>>, rec: Rc<Node<P>>,
field: crate::ast::types::Keyword, field: Keyword,
}, },
/// Expanded macro call, preserving the original call for debugging. /// Expanded macro call, preserving the original call for debugging.
Expansion { Expansion {
+2 -2
View File
@@ -1,7 +1,7 @@
use crate::ast::diagnostics::Diagnostics; use crate::ast::diagnostics::Diagnostics;
use crate::ast::lexer::{Lexer, Token, TokenKind}; use crate::ast::lexer::{Lexer, Token, TokenKind};
use crate::ast::nodes::{Symbol, SyntaxKind, SyntaxNode}; use crate::ast::nodes::{Symbol, SyntaxKind, SyntaxNode};
use crate::ast::types::{Identity, Keyword, NodeIdentity, Value}; use crate::ast::types::{Identity, Keyword, NodeIdentity, SourceLocation, Value};
use std::rc::Rc; use std::rc::Rc;
pub struct Parser<'a> { pub struct Parser<'a> {
@@ -20,7 +20,7 @@ impl<'a> Parser<'a> {
diagnostics.push_error(e, None); diagnostics.push_error(e, None);
Token { Token {
kind: TokenKind::EOF, kind: TokenKind::EOF,
location: crate::ast::types::SourceLocation { line: 1, col: 1 }, location: SourceLocation { line: 1, col: 1 },
} }
} }
}; };
+6 -4
View File
@@ -1,6 +1,8 @@
use crate::ast::environment::Environment; use crate::ast::environment::Environment;
use crate::ast::types::{Purity, Signature, StaticType, Value}; use crate::ast::types::{NativeFunction, Purity, Signature, StaticType, Value};
use std::cell::RefCell;
use std::f64::consts; use std::f64::consts;
use std::rc::Rc;
pub fn register(env: &Environment) { pub fn register(env: &Environment) {
// Constants // Constants
@@ -165,10 +167,10 @@ pub fn register(env: &Environment) {
fastrand::Rng::new() fastrand::Rng::new()
}; };
let prng = std::rc::Rc::new(std::cell::RefCell::new(rng)); let prng = Rc::new(RefCell::new(rng));
Value::Function(std::rc::Rc::new(crate::ast::types::NativeFunction { Value::Function(Rc::new(NativeFunction {
func: std::rc::Rc::new(move |_args| Value::Float(prng.borrow_mut().f64())), func: Rc::new(move |_args| Value::Float(prng.borrow_mut().f64())),
purity: Purity::Impure, purity: Purity::Impure,
})) }))
}, },
+10 -8
View File
@@ -1,4 +1,6 @@
use crate::ast::types::{PipeFn, Value}; use crate::ast::rtl::series::{RingBuffer, ScalarValue, SeriesMember};
use crate::ast::types::{Object, PipeFn, Value};
use crate::ast::vm::VM;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@@ -62,7 +64,7 @@ impl std::fmt::Debug for StreamNode {
} }
} }
impl crate::ast::types::Object for StreamNode { impl Object for StreamNode {
fn type_name(&self) -> &'static str { fn type_name(&self) -> &'static str {
"StreamNode" "StreamNode"
} }
@@ -217,12 +219,12 @@ impl Observer for PipeStream {
} }
/// A specialized observer that pushes incoming signals into a SharedSeries buffer. /// A specialized observer that pushes incoming signals into a SharedSeries buffer.
pub struct SeriesPusher<T: crate::ast::rtl::series::ScalarValue> { pub struct SeriesPusher<T: ScalarValue> {
pub buffer: Rc<RefCell<crate::ast::rtl::series::RingBuffer<T>>>, pub buffer: Rc<RefCell<RingBuffer<T>>>,
pub extractor: fn(Value) -> Option<T>, pub extractor: fn(Value) -> Option<T>,
} }
impl<T: crate::ast::rtl::series::ScalarValue> Observer for SeriesPusher<T> { impl<T: ScalarValue> Observer for SeriesPusher<T> {
fn notify(&mut self, _source_index: usize, _cycle_id: u64, value: Value) { fn notify(&mut self, _source_index: usize, _cycle_id: u64, value: Value) {
if let Some(v) = (self.extractor)(value) { if let Some(v) = (self.extractor)(value) {
self.buffer.borrow_mut().push(v); self.buffer.borrow_mut().push(v);
@@ -232,7 +234,7 @@ impl<T: crate::ast::rtl::series::ScalarValue> Observer for SeriesPusher<T> {
/// A specialized observer that pushes incoming signals into a generic SharedValueSeries buffer. /// A specialized observer that pushes incoming signals into a generic SharedValueSeries buffer.
pub struct ValuePusher { pub struct ValuePusher {
pub buffer: Rc<RefCell<crate::ast::rtl::series::RingBuffer<Value>>>, pub buffer: Rc<RefCell<RingBuffer<Value>>>,
} }
impl Observer for ValuePusher { impl Observer for ValuePusher {
@@ -243,7 +245,7 @@ impl Observer for ValuePusher {
/// A specialized observer that splits a Record into its fields and pushes them into SoA buffers. /// A specialized observer that splits a Record into its fields and pushes them into SoA buffers.
pub struct RecordPusher { pub struct RecordPusher {
pub field_buffers: Vec<Rc<RefCell<dyn crate::ast::rtl::series::SeriesMember>>>, pub field_buffers: Vec<Rc<RefCell<dyn SeriesMember>>>,
} }
impl Observer for RecordPusher { impl Observer for RecordPusher {
@@ -440,7 +442,7 @@ pub fn register(env: &Environment) {
}; };
// 2. Setup isolated VM // 2. Setup isolated VM
let mut ticker_vm = crate::ast::vm::VM::new(globals.clone()); let mut ticker_vm = VM::new(globals.clone());
let my_closure = closure_obj.clone(); let my_closure = closure_obj.clone();
// 3. Create generator // 3. Create generator
+2 -2
View File
@@ -1,4 +1,4 @@
use crate::ast::types::{Keyword, Purity, Signature, StaticType, Value}; use crate::ast::types::{Keyword, Purity, RecordLayout, Signature, StaticType, Value};
use std::any::TypeId; use std::any::TypeId;
use std::collections::HashMap; use std::collections::HashMap;
@@ -148,7 +148,7 @@ impl TypeBuilder {
} }
pub fn build(self) -> StaticType { pub fn build(self) -> StaticType {
StaticType::Record(crate::ast::types::RecordLayout::get_or_create(self.fields)) StaticType::Record(RecordLayout::get_or_create(self.fields))
} }
} }
+19 -19
View File
@@ -1,5 +1,7 @@
use crate::ast::nodes::{Address, AnalyzedNode, ExecNode, IdentifierBinding, NodeKind, StackOffset}; use crate::ast::nodes::{Address, AnalyzedNode, ExecNode, IdentifierBinding, NodeKind, StackOffset};
use crate::ast::types::{Object, Value}; use crate::ast::rtl::series::{RecordSeries, SeriesView};
use crate::ast::rtl::streams::{build_map_stream, build_pipeline_node, StreamNode};
use crate::ast::types::{Object, PipeFn, Value};
use std::any::Any; use std::any::Any;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@@ -386,19 +388,19 @@ impl VM {
Value::Object(obj) => { Value::Object(obj) => {
let any_ptr = obj.as_any(); let any_ptr = obj.as_any();
if let Some(record_series) = if let Some(record_series) =
any_ptr.downcast_ref::<crate::ast::rtl::series::RecordSeries>() any_ptr.downcast_ref::<RecordSeries>()
{ {
if let Some(field_series) = record_series.field(*field) { if let Some(field_series) = record_series.field(*field) {
let view = let view =
crate::ast::rtl::series::SeriesView::new(field_series, *field); SeriesView::new(field_series, *field);
return Ok(Value::Object(std::rc::Rc::new(view))); } else { return Ok(Value::Object(std::rc::Rc::new(view))); } else {
return Err(format!( return Err(format!(
"RecordSeries does not have field :{}", "RecordSeries does not have field :{}",
field.name() field.name()
)); ));
} }
} else if let Some(sn) = obj.as_any().downcast_ref::<crate::ast::rtl::streams::StreamNode>() { } else if let Some(sn) = obj.as_any().downcast_ref::<StreamNode>() {
let mapped = crate::ast::rtl::streams::build_map_stream(sn.inner.clone(), *field); let mapped = build_map_stream(sn.inner.clone(), *field);
return Ok(Value::Object(Rc::new(mapped))); return Ok(Value::Object(Rc::new(mapped)));
} }
Err(format!( Err(format!(
@@ -431,8 +433,6 @@ impl VM {
inputs, inputs,
lambda, lambda,
} => { } => {
use crate::ast::rtl::streams::StreamNode;
let mut obs_streams = Vec::new(); let mut obs_streams = Vec::new();
for input in inputs { for input in inputs {
let val = self.eval_internal(obs, input)?; let val = self.eval_internal(obs, input)?;
@@ -453,9 +453,9 @@ impl VM {
let lambda_val = self.eval_internal(obs, lambda)?; let lambda_val = self.eval_internal(obs, lambda)?;
// Create the persistent execution closure for the PipeStream // Create the persistent execution closure for the PipeStream
let mut pipe_vm = crate::ast::vm::VM::new(self.globals.clone()); let mut pipe_vm = VM::new(self.globals.clone());
let executor: Box<crate::ast::types::PipeFn> = match lambda_val { let executor: Box<PipeFn> = match lambda_val {
Value::Object(obj) => { Value::Object(obj) => {
let my_closure = obj.clone(); let my_closure = obj.clone();
Box::new(move |args: &[Value]| -> Value { Box::new(move |args: &[Value]| -> Value {
@@ -476,7 +476,7 @@ impl VM {
// Delegate to the RTL Factory for specialized buffer instantiation // Delegate to the RTL Factory for specialized buffer instantiation
let node = let node =
crate::ast::rtl::streams::build_pipeline_node(obs_streams, executor, &node.ty.ty); build_pipeline_node(obs_streams, executor, &node.ty.ty);
Ok(Value::Object(node)) Ok(Value::Object(node))
} }
@@ -547,10 +547,10 @@ impl VM {
// Polymorphic Field Access: Allow `.field` on a RecordSeries // Polymorphic Field Access: Allow `.field` on a RecordSeries
if let Some(rs) = obj if let Some(rs) = obj
.as_any() .as_any()
.downcast_ref::<crate::ast::rtl::series::RecordSeries>() .downcast_ref::<RecordSeries>()
{ {
if let Some(field_series) = rs.field(k) { if let Some(field_series) = rs.field(k) {
let view = crate::ast::rtl::series::SeriesView::new( let view = SeriesView::new(
field_series, field_series,
k, k,
); );
@@ -561,8 +561,8 @@ impl VM {
k.name() k.name()
)); ));
} }
} else if let Some(sn) = obj.as_any().downcast_ref::<crate::ast::rtl::streams::StreamNode>() { } else if let Some(sn) = obj.as_any().downcast_ref::<StreamNode>() {
let mapped = crate::ast::rtl::streams::build_map_stream(sn.inner.clone(), k); let mapped = build_map_stream(sn.inner.clone(), k);
return Ok(Value::Object(Rc::new(mapped))); return Ok(Value::Object(Rc::new(mapped)));
} }
return Err(format!( return Err(format!(
@@ -616,10 +616,10 @@ impl VM {
} else if let Value::Object(obj) = rec { } else if let Value::Object(obj) = rec {
if let Some(rs) = obj if let Some(rs) = obj
.as_any() .as_any()
.downcast_ref::<crate::ast::rtl::series::RecordSeries>() .downcast_ref::<RecordSeries>()
{ {
if let Some(field_series) = rs.field(*k) { if let Some(field_series) = rs.field(*k) {
let view = crate::ast::rtl::series::SeriesView::new( let view = SeriesView::new(
field_series, field_series,
*k, *k,
); );
@@ -630,8 +630,8 @@ impl VM {
k.name() k.name()
)) ))
} }
} else if let Some(sn) = obj.as_any().downcast_ref::<crate::ast::rtl::streams::StreamNode>() { } else if let Some(sn) = obj.as_any().downcast_ref::<StreamNode>() {
let mapped = crate::ast::rtl::streams::build_map_stream(sn.inner.clone(), *k); let mapped = build_map_stream(sn.inner.clone(), *k);
Ok(Value::Object(Rc::new(mapped))) Ok(Value::Object(Rc::new(mapped)))
} else { } else {
Err(format!( Err(format!(
+2 -1
View File
@@ -1,3 +1,4 @@
use crate::ast::compiler::TypedNode;
use crate::ast::environment::Environment; use crate::ast::environment::Environment;
use regex::Regex; use regex::Regex;
use std::fs; use std::fs;
@@ -128,7 +129,7 @@ pub fn run_benchmarks(update: bool, filter: Option<&str>) -> Vec<BenchmarkResult
// Helper to measure sum of VM execution times over N executions in one environment // Helper to measure sum of VM execution times over N executions in one environment
let measure_sum = let measure_sum =
|n: u32, node: &crate::ast::compiler::TypedNode| -> Result<Duration, String> { |n: u32, node: &TypedNode| -> Result<Duration, String> {
let env = Environment::new(); let env = Environment::new();
// Link once per sample // Link once per sample