use tensorlogic_compiler::{compile, execute, VmEnv, VmValue};
use tensorlogic_ir::{from_binary, to_binary, MatchPattern, TLExpr};
fn run(expr: &TLExpr) -> VmValue {
let program = compile(expr).expect("compile failed");
execute(&program, &VmEnv::new()).expect("execute failed")
}
#[test]
fn symbol_arm_matches_first() {
let scrutinee = TLExpr::SymbolLiteral("ok".into());
let arms = vec![
(
MatchPattern::ConstSymbol("ok".into()),
TLExpr::Constant(1.0),
),
(MatchPattern::Wildcard, TLExpr::Constant(0.0)),
];
let expr = TLExpr::match_expr(scrutinee, arms);
assert_eq!(run(&expr), VmValue::Num(1.0));
}
#[test]
fn symbol_arm_falls_through_to_wildcard() {
let scrutinee = TLExpr::SymbolLiteral("err".into());
let arms = vec![
(
MatchPattern::ConstSymbol("ok".into()),
TLExpr::Constant(1.0),
),
(MatchPattern::Wildcard, TLExpr::Constant(0.0)),
];
let expr = TLExpr::match_expr(scrutinee, arms);
assert_eq!(run(&expr), VmValue::Num(0.0));
}
#[test]
fn number_arm_matches() {
let scrutinee = TLExpr::Constant(42.0);
let arms = vec![
(MatchPattern::ConstNumber(42.0), TLExpr::Constant(7.0)),
(MatchPattern::Wildcard, TLExpr::Constant(-1.0)),
];
let expr = TLExpr::match_expr(scrutinee, arms);
assert_eq!(run(&expr), VmValue::Num(7.0));
}
#[test]
fn number_arm_falls_through_to_wildcard() {
let scrutinee = TLExpr::Constant(5.0);
let arms = vec![
(MatchPattern::ConstNumber(42.0), TLExpr::Constant(7.0)),
(MatchPattern::Wildcard, TLExpr::Constant(-1.0)),
];
let expr = TLExpr::match_expr(scrutinee, arms);
assert_eq!(run(&expr), VmValue::Num(-1.0));
}
#[test]
fn three_arm_cascade_matches_second() {
let scrutinee = TLExpr::SymbolLiteral("b".into());
let arms = vec![
(MatchPattern::ConstSymbol("a".into()), TLExpr::Constant(1.0)),
(MatchPattern::ConstSymbol("b".into()), TLExpr::Constant(2.0)),
(MatchPattern::Wildcard, TLExpr::Constant(3.0)),
];
let expr = TLExpr::match_expr(scrutinee, arms);
assert_eq!(run(&expr), VmValue::Num(2.0));
}
#[test]
fn wildcard_only_arm_always_returns_body() {
let scrutinee = TLExpr::SymbolLiteral("anything".into());
let arms = vec![(MatchPattern::Wildcard, TLExpr::Constant(99.0))];
let expr = TLExpr::match_expr(scrutinee, arms);
assert_eq!(run(&expr), VmValue::Num(99.0));
}
#[test]
fn match_expr_binary_serde_and_execute() {
let scrutinee = TLExpr::SymbolLiteral("ping".into());
let arms = vec![
(
MatchPattern::ConstSymbol("ping".into()),
TLExpr::Constant(1.0),
),
(MatchPattern::Wildcard, TLExpr::Constant(0.0)),
];
let original = TLExpr::match_expr(scrutinee, arms);
let bytes = to_binary(&original);
let restored = from_binary(&bytes).expect("binary deserialization failed");
assert_eq!(original, restored);
assert_eq!(run(&restored), VmValue::Num(1.0));
}