Update benchmarks and adjust tests
This commit updates benchmark values in several example files to reflect minor performance variations. It also includes adjustments to integration and unit tests to align with recent changes in the type checking and VM logic, specifically concerning closures and TCO handling.
This commit is contained in:
@@ -232,7 +232,7 @@ mod tests {
|
||||
|
||||
// Mock Registry
|
||||
struct MockRegistry {
|
||||
functions: HashMap<Address, TypedNode>,
|
||||
functions: HashMap<Address, BoundNode>,
|
||||
}
|
||||
|
||||
impl MockRegistry {
|
||||
@@ -240,13 +240,13 @@ mod tests {
|
||||
Self { functions: HashMap::new() }
|
||||
}
|
||||
|
||||
fn register(&mut self, addr: Address, node: TypedNode) {
|
||||
fn register(&mut self, addr: Address, node: BoundNode) {
|
||||
self.functions.insert(addr, node);
|
||||
}
|
||||
}
|
||||
|
||||
impl FunctionRegistry for MockRegistry {
|
||||
fn resolve(&self, addr: Address) -> Option<TypedNode> {
|
||||
fn resolve(&self, addr: Address) -> Option<BoundNode> {
|
||||
self.functions.get(&addr).cloned()
|
||||
}
|
||||
}
|
||||
@@ -259,19 +259,19 @@ mod tests {
|
||||
let name = Symbol::from("test_func");
|
||||
|
||||
// Def: (fn [x] x) -- generic identity
|
||||
let func_node = TypedNode {
|
||||
let func_node = BoundNode {
|
||||
identity: make_identity(),
|
||||
kind: BoundKind::Lambda {
|
||||
param_count: 1,
|
||||
upvalues: vec![],
|
||||
body: Rc::new(TypedNode { identity: make_identity(), kind: BoundKind::Nop, ty: StaticType::Void })
|
||||
body: Rc::new(BoundNode { identity: make_identity(), kind: BoundKind::Nop, ty: () })
|
||||
},
|
||||
ty: StaticType::Void
|
||||
ty: ()
|
||||
};
|
||||
registry.register(addr, func_node);
|
||||
|
||||
// Setup Compiler Mock
|
||||
let compiler: CompileFunc = Rc::new(|_node: TypedNode, _args: &[StaticType]| -> Result<(Value, StaticType), String> {
|
||||
let compiler: CompileFunc = Rc::new(|_node: BoundNode, _args: &[StaticType]| -> Result<(Value, StaticType), String> {
|
||||
// Return a specialized "compiled" value
|
||||
Ok((Value::Int(12345), StaticType::Int))
|
||||
});
|
||||
|
||||
@@ -288,42 +288,54 @@ mod tests {
|
||||
env.compile(source).unwrap()
|
||||
}
|
||||
|
||||
fn get_ret_type(node: &TypedNode) -> StaticType {
|
||||
if let StaticType::Function(sig) = &node.ty {
|
||||
sig.ret.clone()
|
||||
} else {
|
||||
node.ty.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inference_constants() {
|
||||
assert_eq!(check_source("10").ty, StaticType::Int);
|
||||
assert_eq!(check_source("10.5").ty, StaticType::Float);
|
||||
assert_eq!(check_source("true").ty, StaticType::Bool);
|
||||
assert_eq!(check_source("\"hello\"").ty, StaticType::Text);
|
||||
assert_eq!(get_ret_type(&check_source("10")), StaticType::Int);
|
||||
assert_eq!(get_ret_type(&check_source("10.5")), StaticType::Float);
|
||||
assert_eq!(get_ret_type(&check_source("true")), StaticType::Bool);
|
||||
assert_eq!(get_ret_type(&check_source("\"hello\"")), StaticType::Text);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inference_variable_propagation() {
|
||||
// (do (def x 10) x) -> The last 'x' must be Int
|
||||
let typed = check_source("(do (def x 10) x)");
|
||||
if let BoundKind::Block { exprs } = typed.kind {
|
||||
let last_expr = exprs.last().unwrap();
|
||||
assert_eq!(last_expr.ty, StaticType::Int, "Variable 'x' should be inferred as Int");
|
||||
} else { panic!("Expected block"); }
|
||||
// Outer is Lambda, Body is Block
|
||||
if let BoundKind::Lambda { body, .. } = &typed.kind {
|
||||
if let BoundKind::Block { exprs } = &body.kind {
|
||||
let last_expr = exprs.last().unwrap();
|
||||
assert_eq!(last_expr.ty, StaticType::Int, "Variable 'x' should be inferred as Int");
|
||||
} else { panic!("Expected block in lambda body"); }
|
||||
} else { panic!("Expected Lambda wrapper"); }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inference_block_type() {
|
||||
// Block type = last expression type
|
||||
assert_eq!(check_source("(do 1 2.5)").ty, StaticType::Float);
|
||||
assert_eq!(check_source("(do 1.5 \"test\")").ty, StaticType::Text);
|
||||
assert_eq!(get_ret_type(&check_source("(do 1 2.5)")), StaticType::Float);
|
||||
assert_eq!(get_ret_type(&check_source("(do 1.5 \"test\")")), StaticType::Text);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inference_lambda_return() {
|
||||
// (fn [a] 10) -> fn(any) -> Int
|
||||
// Since it's already a Lambda, it's NOT wrapped further.
|
||||
let typed = check_source("(fn [a] 10)");
|
||||
if let StaticType::Function(sig) = typed.ty {
|
||||
if let StaticType::Function(sig) = &typed.ty {
|
||||
assert_eq!(sig.ret, StaticType::Int);
|
||||
} else { panic!("Expected function type, got {:?}", typed.ty); }
|
||||
|
||||
// Nested: (fn [] (do 1 2.5)) -> fn() -> Float
|
||||
let typed_nested = check_source("(fn [] (do 1 2.5))");
|
||||
if let StaticType::Function(sig) = typed_nested.ty {
|
||||
if let StaticType::Function(sig) = &typed_nested.ty {
|
||||
assert_eq!(sig.ret, StaticType::Float);
|
||||
} else { panic!("Expected function type"); }
|
||||
}
|
||||
@@ -332,29 +344,31 @@ mod tests {
|
||||
fn test_inference_assignment_updates_type() {
|
||||
// (do (def x 10) (assign x 20.5) x) -> x becomes Float after assignment
|
||||
let typed = check_source("(do (def x 10) (assign x 20.5) x)");
|
||||
if let BoundKind::Block { exprs } = typed.kind {
|
||||
let last_expr = exprs.last().unwrap();
|
||||
assert_eq!(last_expr.ty, StaticType::Float, "Variable 'x' should be specialized to Float after assignment");
|
||||
} else { panic!("Expected block"); }
|
||||
if let BoundKind::Lambda { body, .. } = &typed.kind {
|
||||
if let BoundKind::Block { exprs } = &body.kind {
|
||||
let last_expr = exprs.last().unwrap();
|
||||
assert_eq!(last_expr.ty, StaticType::Float, "Variable 'x' should be specialized to Float after assignment");
|
||||
} else { panic!("Expected block"); }
|
||||
} else { panic!("Expected Lambda"); }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_operator_overloading_inference() {
|
||||
assert_eq!(check_source("(+ 1 2)").ty, StaticType::Int);
|
||||
assert_eq!(check_source("(+ 1.0 2.0)").ty, StaticType::Float);
|
||||
assert_eq!(check_source("(+ \"a\" \"b\")").ty, StaticType::Text);
|
||||
assert_eq!(check_source("(/ 1 2)").ty, StaticType::Float);
|
||||
assert_eq!(get_ret_type(&check_source("(+ 1 2)")), StaticType::Int);
|
||||
assert_eq!(get_ret_type(&check_source("(+ 1.0 2.0)")), StaticType::Float);
|
||||
assert_eq!(get_ret_type(&check_source("(+ \"a\" \"b\")")), StaticType::Text);
|
||||
assert_eq!(get_ret_type(&check_source("(/ 1 2)")), StaticType::Float);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_datetime_inference() {
|
||||
// date("2023-01-01") -> DateTime
|
||||
assert_eq!(check_source("(date \"2023-01-01\")").ty, StaticType::DateTime);
|
||||
assert_eq!(get_ret_type(&check_source("(date \"2023-01-01\")")), StaticType::DateTime);
|
||||
// DateTime + Int -> DateTime
|
||||
assert_eq!(check_source("(+ (date \"2023-01-01\") 86400000)").ty, StaticType::DateTime);
|
||||
assert_eq!(get_ret_type(&check_source("(+ (date \"2023-01-01\") 86400000)")), StaticType::DateTime);
|
||||
// DateTime - DateTime -> Int (Duration)
|
||||
assert_eq!(check_source("(- (date \"2023-01-02\") (date \"2023-01-01\"))").ty, StaticType::Int);
|
||||
assert_eq!(get_ret_type(&check_source("(- (date \"2023-01-02\") (date \"2023-01-01\"))")), StaticType::Int);
|
||||
// DateTime comparison -> Bool
|
||||
assert_eq!(check_source("(> (date \"2023-01-02\") (date \"2023-01-01\"))").ty, StaticType::Bool);
|
||||
assert_eq!(get_ret_type(&check_source("(> (date \"2023-01-02\") (date \"2023-01-01\"))")), StaticType::Bool);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user