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,
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<crate::ast::types::Identity>,
lambda_stack: Vec<Identity>,
/// 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.
recursive_identities: HashSet<crate::ast::types::Identity>,
recursive_identities: HashSet<Identity>,
}
impl<'a> Analyzer<'a> {
+5 -5
View File
@@ -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(),
+13 -11
View File
@@ -642,10 +642,12 @@ impl<E: MacroEvaluator> MacroExpander<E> {
#[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(),
+2 -2
View File
@@ -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<Address<crate::ast::nodes::VirtualId>> {
fn extract_def_addr(pattern: &AnalyzedNode) -> Option<Address<VirtualId>> {
if let NodeKind::Identifier {
binding: IdentifierBinding::Declaration { addr, .. },
..
+10 -9
View File
@@ -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<crate::ast::nodes::BoundPhase>,
node: &Node<BoundPhase>,
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()
}
+27 -27
View File
@@ -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<RefCell<Vec<Purity>>>,
pub root_values: Rc<RefCell<Vec<Value>>>,
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 function_registry: Rc<RefCell<GlobalFunctionRegistry>>,
pub typed_function_registry: Rc<RefCell<GlobalAnalyzedRegistry>>,
@@ -93,7 +93,7 @@ struct 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 {
self.analyzed_registry.borrow().get(&idx).cloned()
} else {
@@ -103,7 +103,7 @@ impl FunctionRegistry for EnvFunctionRegistry {
}
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_types: Rc<RefCell<Vec<StaticType>>>,
root_values: Rc<RefCell<Vec<Value>>>,
@@ -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<crate::ast::types::NativeFunction>,
func: Rc<NativeFunction>,
) {
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<crate::ast::types::NativeFunction> {
pub fn instantiate(&self, node: ExecNode) -> Rc<NativeFunction> {
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<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,
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::<crate::ast::vm::Closure>()
.downcast_ref::<Closure>()
.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<Node<crate::ast::nodes::AnalyzedPhase>>,
move |func_template: Rc<Node<AnalyzedPhase>>,
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::<crate::ast::vm::Closure>()
&& let Some(_closure) = obj.as_any().downcast_ref::<Closure>()
{
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::fmt::Debug;
use std::rc::Rc;
@@ -176,7 +176,7 @@ impl CompilerPhase for BoundPhase {
type DefInfo = DefBinding;
type AssignInfo = AssignBinding<VirtualId>;
type LambdaInfo = LambdaBinding<VirtualId>;
type RecordLayout = Arc<crate::ast::types::RecordLayout>;
type RecordLayout = Arc<RecordLayout>;
}
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -188,7 +188,7 @@ impl CompilerPhase for TypedPhase {
type DefInfo = DefBinding;
type AssignInfo = AssignBinding<VirtualId>;
type LambdaInfo = LambdaBinding<VirtualId>;
type RecordLayout = Arc<crate::ast::types::RecordLayout>;
type RecordLayout = Arc<RecordLayout>;
}
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -200,7 +200,7 @@ impl CompilerPhase for AnalyzedPhase {
type DefInfo = DefBinding;
type AssignInfo = AssignBinding<VirtualId>;
type LambdaInfo = LambdaBinding<VirtualId>;
type RecordLayout = Arc<crate::ast::types::RecordLayout>;
type RecordLayout = Arc<RecordLayout>;
}
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -212,7 +212,7 @@ impl CompilerPhase for RuntimePhase {
type DefInfo = DefBinding;
type AssignInfo = AssignBinding<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
@@ -225,7 +225,7 @@ pub trait BoundLike:
DefInfo = DefBinding,
AssignInfo = AssignBinding<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,
AssignInfo = AssignBinding<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)]
pub struct NodeMetrics {
pub original: Rc<TypedNode>,
pub purity: crate::ast::types::Purity,
pub purity: Purity,
pub is_recursive: bool,
}
@@ -370,7 +370,7 @@ pub enum NodeKind<P: CompilerPhase = SyntaxPhase> {
symbol: Symbol,
binding: P::Binding,
},
FieldAccessor(crate::ast::types::Keyword),
FieldAccessor(Keyword),
If {
cond: 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`).
GetField {
rec: Rc<Node<P>>,
field: crate::ast::types::Keyword,
field: Keyword,
},
/// Expanded macro call, preserving the original call for debugging.
Expansion {
+2 -2
View File
@@ -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 },
}
}
};
+6 -4
View File
@@ -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,
}))
},
+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::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<T: crate::ast::rtl::series::ScalarValue> {
pub buffer: Rc<RefCell<crate::ast::rtl::series::RingBuffer<T>>>,
pub struct SeriesPusher<T: ScalarValue> {
pub buffer: Rc<RefCell<RingBuffer<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) {
if let Some(v) = (self.extractor)(value) {
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.
pub struct ValuePusher {
pub buffer: Rc<RefCell<crate::ast::rtl::series::RingBuffer<Value>>>,
pub buffer: Rc<RefCell<RingBuffer<Value>>>,
}
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<Rc<RefCell<dyn crate::ast::rtl::series::SeriesMember>>>,
pub field_buffers: Vec<Rc<RefCell<dyn SeriesMember>>>,
}
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
+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::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))
}
}
+18 -18
View File
@@ -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::<crate::ast::rtl::series::RecordSeries>()
any_ptr.downcast_ref::<RecordSeries>()
{
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::<crate::ast::rtl::streams::StreamNode>() {
let mapped = crate::ast::rtl::streams::build_map_stream(sn.inner.clone(), *field);
} else if let Some(sn) = obj.as_any().downcast_ref::<StreamNode>() {
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 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) => {
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::<crate::ast::rtl::series::RecordSeries>()
.downcast_ref::<RecordSeries>()
{
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::<crate::ast::rtl::streams::StreamNode>() {
let mapped = crate::ast::rtl::streams::build_map_stream(sn.inner.clone(), k);
} else if let Some(sn) = obj.as_any().downcast_ref::<StreamNode>() {
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::<crate::ast::rtl::series::RecordSeries>()
.downcast_ref::<RecordSeries>()
{
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::<crate::ast::rtl::streams::StreamNode>() {
let mapped = crate::ast::rtl::streams::build_map_stream(sn.inner.clone(), *k);
} else if let Some(sn) = obj.as_any().downcast_ref::<StreamNode>() {
let mapped = build_map_stream(sn.inner.clone(), *k);
Ok(Value::Object(Rc::new(mapped)))
} else {
Err(format!(
+2 -1
View File
@@ -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<BenchmarkResult
// Helper to measure sum of VM execution times over N executions in one environment
let measure_sum =
|n: u32, node: &crate::ast::compiler::TypedNode| -> Result<Duration, String> {
|n: u32, node: &TypedNode| -> Result<Duration, String> {
let env = Environment::new();
// Link once per sample