Refactor: Simplify type checking context
The type checker's fallback logic for non-lambda nodes was unnecessarily complex. This commit simplifies it by directly checking the node within a new, basic type context. Additionally, the environment now explicitly wraps non-lambda AST nodes in a lambda before type checking, ensuring consistent handling. This aligns the type checking process for all top-level expressions.
This commit is contained in:
@@ -141,22 +141,8 @@ impl TypeChecker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// Fallback: Wrap in implicit lambda
|
let mut root_ctx = TypeContext::new(0, vec![], &self.global_types, None);
|
||||||
let virtual_lambda = BoundNode {
|
self.check_node(node, &mut root_ctx, diag)
|
||||||
identity: node.identity.clone(),
|
|
||||||
kind: BoundKind::Lambda {
|
|
||||||
params: Rc::new(Node {
|
|
||||||
identity: node.identity.clone(),
|
|
||||||
kind: BoundKind::Tuple { elements: vec![] },
|
|
||||||
ty: (),
|
|
||||||
}),
|
|
||||||
upvalues: vec![],
|
|
||||||
body: Rc::new(node.clone()),
|
|
||||||
positional_count: Some(0),
|
|
||||||
},
|
|
||||||
ty: (),
|
|
||||||
};
|
|
||||||
self.check(&virtual_lambda, &[], diag)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+38
-2
@@ -428,7 +428,25 @@ impl Environment {
|
|||||||
LambdaCollector::collect(&bound_ast, &mut self.function_registry.borrow_mut());
|
LambdaCollector::collect(&bound_ast, &mut self.function_registry.borrow_mut());
|
||||||
|
|
||||||
let checker = TypeChecker::new(self.global_types.clone());
|
let checker = TypeChecker::new(self.global_types.clone());
|
||||||
let typed_ast = checker.check(&bound_ast, &[], &mut diagnostics);
|
let wrapped_ast = if let crate::ast::compiler::bound_nodes::BoundKind::Lambda { .. } = bound_ast.kind {
|
||||||
|
bound_ast
|
||||||
|
} else {
|
||||||
|
crate::ast::compiler::bound_nodes::BoundNode {
|
||||||
|
identity: bound_ast.identity.clone(),
|
||||||
|
kind: crate::ast::compiler::bound_nodes::BoundKind::Lambda {
|
||||||
|
params: std::rc::Rc::new(crate::ast::nodes::Node {
|
||||||
|
identity: bound_ast.identity.clone(),
|
||||||
|
kind: crate::ast::compiler::bound_nodes::BoundKind::Tuple { elements: vec![] },
|
||||||
|
ty: (),
|
||||||
|
}),
|
||||||
|
upvalues: vec![],
|
||||||
|
body: std::rc::Rc::new(bound_ast),
|
||||||
|
positional_count: Some(0),
|
||||||
|
},
|
||||||
|
ty: (),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let typed_ast = checker.check(&wrapped_ast, &[], &mut diagnostics);
|
||||||
|
|
||||||
if diagnostics.has_errors() {
|
if diagnostics.has_errors() {
|
||||||
return Err(diagnostics
|
return Err(diagnostics
|
||||||
@@ -556,7 +574,25 @@ impl Environment {
|
|||||||
LambdaCollector::collect(&bound_ast, &mut self.function_registry.borrow_mut());
|
LambdaCollector::collect(&bound_ast, &mut self.function_registry.borrow_mut());
|
||||||
|
|
||||||
let checker = TypeChecker::new(self.global_types.clone());
|
let checker = TypeChecker::new(self.global_types.clone());
|
||||||
let typed_ast = checker.check(&bound_ast, &[], &mut diagnostics);
|
let wrapped_ast = if let crate::ast::compiler::bound_nodes::BoundKind::Lambda { .. } = bound_ast.kind {
|
||||||
|
bound_ast
|
||||||
|
} else {
|
||||||
|
crate::ast::compiler::bound_nodes::BoundNode {
|
||||||
|
identity: bound_ast.identity.clone(),
|
||||||
|
kind: crate::ast::compiler::bound_nodes::BoundKind::Lambda {
|
||||||
|
params: std::rc::Rc::new(crate::ast::nodes::Node {
|
||||||
|
identity: bound_ast.identity.clone(),
|
||||||
|
kind: crate::ast::compiler::bound_nodes::BoundKind::Tuple { elements: vec![] },
|
||||||
|
ty: (),
|
||||||
|
}),
|
||||||
|
upvalues: vec![],
|
||||||
|
body: std::rc::Rc::new(bound_ast),
|
||||||
|
positional_count: Some(0),
|
||||||
|
},
|
||||||
|
ty: (),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let typed_ast = checker.check(&wrapped_ast, &[], &mut diagnostics);
|
||||||
|
|
||||||
CompilationResult {
|
CompilationResult {
|
||||||
ast: Some(typed_ast),
|
ast: Some(typed_ast),
|
||||||
|
|||||||
+19
-13
@@ -447,22 +447,28 @@ impl VM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let lambda_val = self.eval_internal(obs, lambda)?;
|
let lambda_val = self.eval_internal(obs, lambda)?;
|
||||||
let lambda_obj = if let Value::Object(obj) = lambda_val {
|
|
||||||
obj
|
|
||||||
} else {
|
|
||||||
return Err("Pipe lambda must be a function/closure".to_string());
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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 = crate::ast::vm::VM::new(self.globals.clone());
|
||||||
let my_closure = lambda_obj.clone();
|
|
||||||
let executor: Box<crate::ast::types::PipeFn> =
|
let executor: Box<crate::ast::types::PipeFn> = match lambda_val {
|
||||||
Box::new(move |args: &[Value]| -> Value {
|
Value::Object(obj) => {
|
||||||
match pipe_vm.run_with_args(my_closure.clone(), args) {
|
let my_closure = obj.clone();
|
||||||
Ok(res) => res,
|
Box::new(move |args: &[Value]| -> Value {
|
||||||
Err(e) => panic!("Pipeline lambda execution failed: {}", e),
|
match pipe_vm.run_with_args(my_closure.clone(), args) {
|
||||||
}
|
Ok(res) => res,
|
||||||
});
|
Err(e) => panic!("Pipeline lambda execution failed: {}", e),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Value::Function(func) => {
|
||||||
|
let my_func = func.clone();
|
||||||
|
Box::new(move |args: &[Value]| -> Value {
|
||||||
|
(my_func.func)(args)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_ => return Err("Pipe lambda must be a function/closure".to_string()),
|
||||||
|
};
|
||||||
|
|
||||||
// Delegate to the RTL Factory for specialized buffer instantiation
|
// Delegate to the RTL Factory for specialized buffer instantiation
|
||||||
let node =
|
let node =
|
||||||
|
|||||||
Reference in New Issue
Block a user