From 007446a1671c13d6a8581f6a6e47808e4886d517 Mon Sep 17 00:00:00 2001 From: Brummel Date: Sun, 22 Mar 2026 18:30:56 +0100 Subject: [PATCH] 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` 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. --- src/ast/compiler/analyzer.rs | 8 ++--- src/ast/compiler/binder.rs | 10 +++--- src/ast/compiler/macros.rs | 24 +++++++------ src/ast/compiler/optimizer/engine.rs | 4 +-- src/ast/compiler/type_checker.rs | 19 +++++----- src/ast/environment.rs | 54 ++++++++++++++-------------- src/ast/nodes.rs | 20 +++++------ src/ast/parser.rs | 4 +-- src/ast/rtl/math.rs | 10 +++--- src/ast/rtl/streams.rs | 18 +++++----- src/ast/rtl/type_registry.rs | 4 +-- src/ast/vm.rs | 38 ++++++++++---------- src/utils/tester.rs | 3 +- 13 files changed, 112 insertions(+), 104 deletions(-) diff --git a/src/ast/compiler/analyzer.rs b/src/ast/compiler/analyzer.rs index d05f574..89a5ad0 100644 --- a/src/ast/compiler/analyzer.rs +++ b/src/ast/compiler/analyzer.rs @@ -2,18 +2,18 @@ use crate::ast::nodes::{ Address, AnalyzedNode, GlobalIdx, IdentifierBinding, Node, NodeKind, NodeMetrics, TypedNode, TypedPhase, }; -use crate::ast::types::Purity; +use crate::ast::types::{Identity, Purity}; use std::collections::{HashMap, HashSet}; use std::rc::Rc; pub struct Analyzer<'a> { root_purity: &'a [Purity], /// Stack of currently visiting lambdas to detect direct recursion. - lambda_stack: Vec, + lambda_stack: Vec, /// Map of global index to its Lambda identity if known. - globals_to_lambdas: HashMap, + globals_to_lambdas: HashMap, /// Set of identities that were found to be recursive. - recursive_identities: HashSet, + recursive_identities: HashSet, } impl<'a> Analyzer<'a> { diff --git a/src/ast/compiler/binder.rs b/src/ast/compiler/binder.rs index 5e54425..f6e7b0b 100644 --- a/src/ast/compiler/binder.rs +++ b/src/ast/compiler/binder.rs @@ -4,7 +4,7 @@ use crate::ast::nodes::{ UpvalueIdx, VirtualId, }; 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::rc::Rc; @@ -139,7 +139,7 @@ impl Binder { fixed_scope_idx, }; binder.functions.push(FunctionCompiler::new( - crate::ast::types::NodeIdentity::new(crate::ast::types::SourceLocation { + NodeIdentity::new(SourceLocation { line: 0, col: 0, }), @@ -488,10 +488,10 @@ impl Binder { let key_node = self.bind(k, 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 { - layout_fields.push((*kw, crate::ast::types::StaticType::Any)); + layout_fields.push((*kw, StaticType::Any)); } else { diag.push_error( format!( @@ -504,7 +504,7 @@ impl Binder { 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( node.identity.clone(), diff --git a/src/ast/compiler/macros.rs b/src/ast/compiler/macros.rs index 7ddfeb8..9c1f985 100644 --- a/src/ast/compiler/macros.rs +++ b/src/ast/compiler/macros.rs @@ -642,10 +642,12 @@ impl MacroExpander { #[cfg(test)] mod tests { use super::*; - use crate::ast::nodes::Address; + use crate::ast::compiler::binder::{CompilerScope, LocalInfo}; use crate::ast::compiler::Binder; + use crate::ast::diagnostics::Diagnostics; + use crate::ast::nodes::{Address, VirtualId}; use crate::ast::parser::Parser; - use crate::ast::types::{Object, Value}; + use crate::ast::types::{NodeIdentity, Object, Purity, SourceLocation, StaticType, Value}; struct SimpleEvaluator; impl MacroEvaluator for SimpleEvaluator { @@ -787,19 +789,19 @@ mod tests { let mut locals = HashMap::new(); locals.insert( Symbol::from("*"), - crate::ast::compiler::binder::LocalInfo { - addr: Address::Local(crate::ast::nodes::VirtualId(0)), - identity: crate::ast::types::NodeIdentity::new(crate::ast::types::SourceLocation { + LocalInfo { + addr: Address::Local(VirtualId(0)), + identity: NodeIdentity::new(SourceLocation { line: 0, col: 0, }), - _ty: crate::ast::types::StaticType::Any, - purity: crate::ast::types::Purity::Pure, + _ty: StaticType::Any, + 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) let result = Binder::bind_root(initial_scopes, 1, 0, &expanded, &mut diag); assert!( @@ -824,7 +826,7 @@ mod tests { let mut expander = MacroExpander::new(MacroRegistry::new(), SimpleEvaluator); 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); assert!(result.is_ok(), "Hygiene failed: {:?}", result.err()); } @@ -844,7 +846,7 @@ mod tests { let mut expander = MacroExpander::new(MacroRegistry::new(), SimpleEvaluator); 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); assert!( result.is_ok(), diff --git a/src/ast/compiler/optimizer/engine.rs b/src/ast/compiler/optimizer/engine.rs index ede9262..99d6990 100644 --- a/src/ast/compiler/optimizer/engine.rs +++ b/src/ast/compiler/optimizer/engine.rs @@ -1,6 +1,6 @@ use crate::ast::nodes::{ Address, AnalyzedNode, AssignBinding, GlobalAnalyzedRegistry, - IdentifierBinding, LambdaBinding, Node, NodeKind, UpvalueIdx, + IdentifierBinding, LambdaBinding, Node, NodeKind, UpvalueIdx, VirtualId, }; use crate::ast::types::{Purity, Value}; 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). - fn extract_def_addr(pattern: &AnalyzedNode) -> Option> { + fn extract_def_addr(pattern: &AnalyzedNode) -> Option> { if let NodeKind::Identifier { binding: IdentifierBinding::Declaration { addr, .. }, .. diff --git a/src/ast/compiler/type_checker.rs b/src/ast/compiler/type_checker.rs index 17a992d..1aa6361 100644 --- a/src/ast/compiler/type_checker.rs +++ b/src/ast/compiler/type_checker.rs @@ -1,9 +1,9 @@ use crate::ast::nodes::{ - Address, AssignBinding, BoundLike, DefBinding, IdentifierBinding, LambdaBinding, Node, - NodeKind, TypedNode, TypedPhase, VirtualId, + Address, AssignBinding, BoundLike, BoundPhase, DefBinding, IdentifierBinding, LambdaBinding, + Node, NodeKind, TypedNode, TypedPhase, VirtualId, }; use crate::ast::diagnostics::Diagnostics; -use crate::ast::types::StaticType; +use crate::ast::types::{Keyword, RecordLayout, Signature, StaticType}; use std::collections::HashMap; use std::rc::Rc; @@ -84,7 +84,7 @@ impl TypeChecker { pub fn check( &self, - node: &Node, + node: &Node, arg_types: &[StaticType], diag: &mut Diagnostics, ) -> TypedNode { @@ -134,7 +134,7 @@ impl TypeChecker { let ret_ty = body_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, ret: ret_ty, })); @@ -319,7 +319,7 @@ impl TypeChecker { StaticType::Record(layout) => layout .fields .get(i) - .map(|(_, ty): &(crate::ast::types::Keyword, StaticType)| ty.clone()) + .map(|(_, ty): &(Keyword, StaticType)| ty.clone()) .unwrap_or(StaticType::Any), StaticType::Error => StaticType::Error, _ => StaticType::Any, @@ -627,7 +627,7 @@ impl TypeChecker { let body_typed = self.check_node(body, &mut lambda_ctx, diag); 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(), ret: ret_ty, })); @@ -780,7 +780,7 @@ impl TypeChecker { 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 { fields: typed_fields, @@ -841,10 +841,11 @@ impl TypeChecker { #[cfg(test)] mod tests { use super::*; + use crate::ast::environment::Environment; use crate::ast::types::StaticType; fn check_source(source: &str) -> TypedNode { - let env = crate::ast::environment::Environment::new(); + let env = Environment::new(); env.compile(source).into_result().unwrap() } diff --git a/src/ast/environment.rs b/src/ast/environment.rs index 1f22380..a5afb43 100644 --- a/src/ast/environment.rs +++ b/src/ast/environment.rs @@ -1,9 +1,9 @@ use crate::ast::compiler::analyzer::Analyzer; -use crate::ast::compiler::binder::Binder; -use crate::ast::compiler::{TypeChecker, TypedNode}; -use crate::ast::nodes::{Symbol, SyntaxKind, SyntaxNode}; +use crate::ast::compiler::binder::{Binder, CompilerScope, LocalInfo}; +use crate::ast::compiler::{CapturePass, TypeChecker, TypedNode}; +use crate::ast::nodes::{AnalyzedPhase, Symbol, SyntaxKind, SyntaxNode}; use crate::ast::parser::Parser; -use crate::ast::vm::{TracingObserver, VM}; +use crate::ast::vm::{Closure, TracingObserver, VM}; use std::cell::RefCell; use std::collections::{HashMap, HashSet}; 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::optimizer::Optimizer; use crate::ast::compiler::specializer::{FunctionRegistry, MonoCache, Specializer}; -use crate::ast::rtl::intrinsics; +use crate::ast::rtl::{self, intrinsics}; use crate::ast::types::{ - NodeIdentity, Object, Purity, SourceLocation, StaticType, Value, + NativeFunction, NodeIdentity, Object, Purity, SourceLocation, StaticType, Value, }; use crate::ast::diagnostics::{DiagnosticLevel, Diagnostics}; @@ -75,7 +75,7 @@ pub struct Environment { pub root_purity: Rc>>, pub root_values: Rc>>, pub fixed_scope_idx: i32, - pub root_scopes: Rc>>, + pub root_scopes: Rc>>, pub root_slot_count: Rc>, pub function_registry: Rc>, pub typed_function_registry: Rc>, @@ -93,7 +93,7 @@ struct EnvFunctionRegistry { } impl FunctionRegistry for EnvFunctionRegistry { - fn resolve(&self, addr: Address) -> Option>> { + fn resolve(&self, addr: Address) -> Option>> { if let Address::Global(idx) = addr { self.analyzed_registry.borrow().get(&idx).cloned() } else { @@ -103,7 +103,7 @@ impl FunctionRegistry for EnvFunctionRegistry { } struct RuntimeMacroEvaluator { - root_scopes: Rc>>, + root_scopes: Rc>>, root_slot_count: Rc>, root_types: Rc>>, root_values: Rc>>, @@ -128,7 +128,7 @@ impl MacroEvaluator for RuntimeMacroEvaluator { 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 = 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 typed_ast = checker.check(&bound_ast, &[], &mut diag); @@ -161,7 +161,7 @@ impl Environment { root_purity: Rc::new(RefCell::new(Vec::new())), root_values: Rc::new(RefCell::new(Vec::new())), 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)), 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())), loaded_modules: Rc::new(RefCell::new(HashSet::new())), }; - crate::ast::rtl::register(&env); + rtl::register(&env); let mut env = env; env.fixed_scope_idx = 0; // 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) if let Ok(cwd) = std::env::current_dir() { @@ -401,7 +401,7 @@ impl Environment { let slot = VirtualId(*slot_count); current_scope.locals.insert( sym.clone(), - crate::ast::compiler::binder::LocalInfo { + LocalInfo { addr: Address::Local(slot), identity: node.identity.clone(), _ty: StaticType::Any, @@ -462,7 +462,7 @@ impl Environment { *self.root_scopes.borrow_mut() = final_scopes; *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 { @@ -520,7 +520,7 @@ impl Environment { &self, name: &str, ty: StaticType, - func: Rc, + func: Rc, ) { let mut types = self.root_types.borrow_mut(); let mut values = self.root_values.borrow_mut(); @@ -535,7 +535,7 @@ impl Environment { let global_idx = GlobalIdx(*slot_count); root_scopes[0].locals.insert( Symbol::from(name), - crate::ast::compiler::binder::LocalInfo { + LocalInfo { addr: Address::Global(global_idx), identity, _ty: ty.clone(), @@ -559,7 +559,7 @@ impl Environment { self.register_native( name, ty, - Rc::new(crate::ast::types::NativeFunction { + Rc::new(NativeFunction { func: Rc::new(func), purity: purity_level, }), @@ -580,7 +580,7 @@ impl Environment { let global_idx = GlobalIdx(*slot_count); root_scopes[0].locals.insert( Symbol::from(name), - crate::ast::compiler::binder::LocalInfo { + LocalInfo { addr: Address::Global(global_idx), identity, _ty: ty.clone(), @@ -650,7 +650,7 @@ impl Environment { Lowering::lower(optimized) } - pub fn instantiate(&self, node: ExecNode) -> Rc { + pub fn instantiate(&self, node: ExecNode) -> Rc { let root_values = self.root_values.clone(); if let NodeKind::Lambda { params, @@ -659,7 +659,7 @@ impl Environment { } = &node.kind && info.upvalues.is_empty() { - let closure = Rc::new(crate::ast::vm::Closure::new( + let closure = Rc::new(Closure::new( params.clone(), body.ty.original.clone(), body.clone(), @@ -667,9 +667,9 @@ impl Environment { info.positional_count, node.ty.stack_size, )); - let closure_obj: Rc = closure; + let closure_obj: Rc = closure; - return Rc::new(crate::ast::types::NativeFunction { + return Rc::new(NativeFunction { purity: Purity::Impure, func: Rc::new(move |args| { let mut vm = VM::new(root_values.clone()); @@ -682,7 +682,7 @@ impl Environment { } let exec_node = Rc::new(node); - Rc::new(crate::ast::types::NativeFunction { + Rc::new(NativeFunction { purity: Purity::Impure, func: Rc::new(move |args| { let mut vm = VM::new(root_values.clone()); @@ -694,7 +694,7 @@ impl Environment { if let Value::Object(obj) = &res && obj .as_any() - .downcast_ref::() + .downcast_ref::() .is_some() { match vm.run_with_args(obj.clone(), args) { @@ -722,7 +722,7 @@ impl Environment { let optimization = self.optimization; let compiler = Rc::new( - move |func_template: Rc>, + move |func_template: Rc>, arg_types: &[StaticType]| -> Result<(Value, StaticType), String> { let mut diag = Diagnostics::new(); @@ -837,7 +837,7 @@ impl Environment { // All Myc scripts are wrapped in a parameterless lambda for consistency. let mut final_result = result; if let Ok(Value::Object(obj)) = &final_result - && let Some(_closure) = obj.as_any().downcast_ref::() + && let Some(_closure) = obj.as_any().downcast_ref::() { final_result = vm.run_with_args_observed(&mut observer, obj.clone(), &[]); } diff --git a/src/ast/nodes.rs b/src/ast/nodes.rs index a7ce0f5..f054d33 100644 --- a/src/ast/nodes.rs +++ b/src/ast/nodes.rs @@ -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::fmt::Debug; use std::rc::Rc; @@ -176,7 +176,7 @@ impl CompilerPhase for BoundPhase { type DefInfo = DefBinding; type AssignInfo = AssignBinding; type LambdaInfo = LambdaBinding; - type RecordLayout = Arc; + type RecordLayout = Arc; } #[derive(Debug, Clone, PartialEq, Eq)] @@ -188,7 +188,7 @@ impl CompilerPhase for TypedPhase { type DefInfo = DefBinding; type AssignInfo = AssignBinding; type LambdaInfo = LambdaBinding; - type RecordLayout = Arc; + type RecordLayout = Arc; } #[derive(Debug, Clone, PartialEq, Eq)] @@ -200,7 +200,7 @@ impl CompilerPhase for AnalyzedPhase { type DefInfo = DefBinding; type AssignInfo = AssignBinding; type LambdaInfo = LambdaBinding; - type RecordLayout = Arc; + type RecordLayout = Arc; } #[derive(Debug, Clone, PartialEq, Eq)] @@ -212,7 +212,7 @@ impl CompilerPhase for RuntimePhase { type DefInfo = DefBinding; type AssignInfo = AssignBinding; type LambdaInfo = LambdaBinding; - type RecordLayout = Arc; + type RecordLayout = Arc; } /// Convenience alias for all post-binding phases that share the same @@ -225,7 +225,7 @@ pub trait BoundLike: DefInfo = DefBinding, AssignInfo = AssignBinding, LambdaInfo = LambdaBinding, - RecordLayout = Arc, + RecordLayout = Arc, > { } @@ -237,7 +237,7 @@ impl

BoundLike for P where DefInfo = DefBinding, AssignInfo = AssignBinding, LambdaInfo = LambdaBinding, - RecordLayout = Arc, + RecordLayout = Arc, > { } @@ -283,7 +283,7 @@ pub type TypedNode = Node; #[derive(Debug, Clone, PartialEq)] pub struct NodeMetrics { pub original: Rc, - pub purity: crate::ast::types::Purity, + pub purity: Purity, pub is_recursive: bool, } @@ -370,7 +370,7 @@ pub enum NodeKind { symbol: Symbol, binding: P::Binding, }, - FieldAccessor(crate::ast::types::Keyword), + FieldAccessor(Keyword), If { cond: Rc>, then_br: Rc>, @@ -427,7 +427,7 @@ pub enum NodeKind { /// Optimized field access (only created during lowering for `RuntimePhase`). GetField { rec: Rc>, - field: crate::ast::types::Keyword, + field: Keyword, }, /// Expanded macro call, preserving the original call for debugging. Expansion { diff --git a/src/ast/parser.rs b/src/ast/parser.rs index 0d844b8..3adedfe 100644 --- a/src/ast/parser.rs +++ b/src/ast/parser.rs @@ -1,7 +1,7 @@ use crate::ast::diagnostics::Diagnostics; use crate::ast::lexer::{Lexer, Token, TokenKind}; 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; pub struct Parser<'a> { @@ -20,7 +20,7 @@ impl<'a> Parser<'a> { diagnostics.push_error(e, None); Token { kind: TokenKind::EOF, - location: crate::ast::types::SourceLocation { line: 1, col: 1 }, + location: SourceLocation { line: 1, col: 1 }, } } }; diff --git a/src/ast/rtl/math.rs b/src/ast/rtl/math.rs index 0250b43..977c7c8 100644 --- a/src/ast/rtl/math.rs +++ b/src/ast/rtl/math.rs @@ -1,6 +1,8 @@ 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::rc::Rc; pub fn register(env: &Environment) { // Constants @@ -165,10 +167,10 @@ pub fn register(env: &Environment) { 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 { - func: std::rc::Rc::new(move |_args| Value::Float(prng.borrow_mut().f64())), + Value::Function(Rc::new(NativeFunction { + func: Rc::new(move |_args| Value::Float(prng.borrow_mut().f64())), purity: Purity::Impure, })) }, diff --git a/src/ast/rtl/streams.rs b/src/ast/rtl/streams.rs index de9775d..c10d399 100644 --- a/src/ast/rtl/streams.rs +++ b/src/ast/rtl/streams.rs @@ -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::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 { "StreamNode" } @@ -217,12 +219,12 @@ impl Observer for PipeStream { } /// A specialized observer that pushes incoming signals into a SharedSeries buffer. -pub struct SeriesPusher { - pub buffer: Rc>>, +pub struct SeriesPusher { + pub buffer: Rc>>, pub extractor: fn(Value) -> Option, } -impl Observer for SeriesPusher { +impl Observer for SeriesPusher { fn notify(&mut self, _source_index: usize, _cycle_id: u64, value: Value) { if let Some(v) = (self.extractor)(value) { self.buffer.borrow_mut().push(v); @@ -232,7 +234,7 @@ impl Observer for SeriesPusher { /// A specialized observer that pushes incoming signals into a generic SharedValueSeries buffer. pub struct ValuePusher { - pub buffer: Rc>>, + pub buffer: Rc>>, } 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. pub struct RecordPusher { - pub field_buffers: Vec>>, + pub field_buffers: Vec>>, } impl Observer for RecordPusher { @@ -440,7 +442,7 @@ pub fn register(env: &Environment) { }; // 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(); // 3. Create generator diff --git a/src/ast/rtl/type_registry.rs b/src/ast/rtl/type_registry.rs index 5e67f66..be3f085 100644 --- a/src/ast/rtl/type_registry.rs +++ b/src/ast/rtl/type_registry.rs @@ -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::collections::HashMap; @@ -148,7 +148,7 @@ impl TypeBuilder { } pub fn build(self) -> StaticType { - StaticType::Record(crate::ast::types::RecordLayout::get_or_create(self.fields)) + StaticType::Record(RecordLayout::get_or_create(self.fields)) } } diff --git a/src/ast/vm.rs b/src/ast/vm.rs index 8e6f5f7..ab024ea 100644 --- a/src/ast/vm.rs +++ b/src/ast/vm.rs @@ -1,5 +1,7 @@ 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::cell::RefCell; use std::rc::Rc; @@ -386,19 +388,19 @@ impl VM { Value::Object(obj) => { let any_ptr = obj.as_any(); if let Some(record_series) = - any_ptr.downcast_ref::() + any_ptr.downcast_ref::() { if let Some(field_series) = record_series.field(*field) { 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 Err(format!( "RecordSeries does not have field :{}", field.name() )); } - } else if let Some(sn) = obj.as_any().downcast_ref::() { - let mapped = crate::ast::rtl::streams::build_map_stream(sn.inner.clone(), *field); + } else if let Some(sn) = obj.as_any().downcast_ref::() { + let mapped = build_map_stream(sn.inner.clone(), *field); return Ok(Value::Object(Rc::new(mapped))); } Err(format!( @@ -431,8 +433,6 @@ impl VM { inputs, lambda, } => { - use crate::ast::rtl::streams::StreamNode; - let mut obs_streams = Vec::new(); for input in inputs { let val = self.eval_internal(obs, input)?; @@ -453,9 +453,9 @@ impl VM { let lambda_val = self.eval_internal(obs, lambda)?; // Create the persistent execution closure for the PipeStream - let mut pipe_vm = crate::ast::vm::VM::new(self.globals.clone()); - - let executor: Box = match lambda_val { + let mut pipe_vm = VM::new(self.globals.clone()); + + let executor: Box = match lambda_val { Value::Object(obj) => { let my_closure = obj.clone(); Box::new(move |args: &[Value]| -> Value { @@ -476,7 +476,7 @@ impl VM { // Delegate to the RTL Factory for specialized buffer instantiation 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)) } @@ -547,10 +547,10 @@ impl VM { // Polymorphic Field Access: Allow `.field` on a RecordSeries if let Some(rs) = obj .as_any() - .downcast_ref::() + .downcast_ref::() { if let Some(field_series) = rs.field(k) { - let view = crate::ast::rtl::series::SeriesView::new( + let view = SeriesView::new( field_series, k, ); @@ -561,8 +561,8 @@ impl VM { k.name() )); } - } else if let Some(sn) = obj.as_any().downcast_ref::() { - let mapped = crate::ast::rtl::streams::build_map_stream(sn.inner.clone(), k); + } else if let Some(sn) = obj.as_any().downcast_ref::() { + let mapped = build_map_stream(sn.inner.clone(), k); return Ok(Value::Object(Rc::new(mapped))); } return Err(format!( @@ -616,10 +616,10 @@ impl VM { } else if let Value::Object(obj) = rec { if let Some(rs) = obj .as_any() - .downcast_ref::() + .downcast_ref::() { if let Some(field_series) = rs.field(*k) { - let view = crate::ast::rtl::series::SeriesView::new( + let view = SeriesView::new( field_series, *k, ); @@ -630,8 +630,8 @@ impl VM { k.name() )) } - } else if let Some(sn) = obj.as_any().downcast_ref::() { - let mapped = crate::ast::rtl::streams::build_map_stream(sn.inner.clone(), *k); + } else if let Some(sn) = obj.as_any().downcast_ref::() { + let mapped = build_map_stream(sn.inner.clone(), *k); Ok(Value::Object(Rc::new(mapped))) } else { Err(format!( diff --git a/src/utils/tester.rs b/src/utils/tester.rs index 06bce00..201ea1e 100644 --- a/src/utils/tester.rs +++ b/src/utils/tester.rs @@ -1,3 +1,4 @@ +use crate::ast::compiler::TypedNode; use crate::ast::environment::Environment; use regex::Regex; use std::fs; @@ -128,7 +129,7 @@ pub fn run_benchmarks(update: bool, filter: Option<&str>) -> Vec Result { + |n: u32, node: &TypedNode| -> Result { let env = Environment::new(); // Link once per sample