Files
hakorune/tests/grammar_add_rules.rs

67 lines
2.5 KiB
Rust
Raw Normal View History

use nyash_rust::grammar::engine;
use nyash_rust::box_trait::{StringBox, IntegerBox, BoolBox, VoidBox, NyashBox};
fn classify_value(b: &dyn NyashBox) -> &'static str {
if nyash_rust::runtime::semantics::coerce_to_string(b).is_some() {
"String"
} else if nyash_rust::runtime::semantics::coerce_to_i64(b).is_some() {
// coerce_to_i64 succeeds for integers and some numeric-like boxes
// For this snapshot, we only feed IntegerBox so "Integer" is fine
"Integer"
} else if b.as_any().downcast_ref::<BoolBox>().is_some() {
"Bool"
} else {
"Other"
}
}
fn actual_add_result(left: &dyn NyashBox, right: &dyn NyashBox) -> &'static str {
// Mirror current interpreter semantics succinctly:
// 1) If either is string-like => String
if nyash_rust::runtime::semantics::coerce_to_string(left).is_some()
|| nyash_rust::runtime::semantics::coerce_to_string(right).is_some() {
return "String";
}
// 2) If both are i64-coercible => Integer
if nyash_rust::runtime::semantics::coerce_to_i64(left).is_some()
&& nyash_rust::runtime::semantics::coerce_to_i64(right).is_some() {
return "Integer";
}
// 3) Otherwise errorここでは Error として表現)
"Error"
}
#[test]
fn snapshot_add_rules_align_with_current_semantics() {
let eng = engine::get();
// Prepare sample operands for each class
let s = StringBox::new("a".to_string());
let i = IntegerBox::new(1);
let b = BoolBox::new(true);
let v = VoidBox::new();
let vals: Vec<(&str, Box<dyn NyashBox>)> = vec![
("String", Box::new(s)),
("Integer", Box::new(i)),
("Bool", Box::new(b)),
("Other", Box::new(v)),
];
for (li, l) in &vals {
for (ri, r) in &vals {
let lty = classify_value(l.as_ref());
let rty = classify_value(r.as_ref());
let actual = actual_add_result(l.as_ref(), r.as_ref());
let expect = eng.decide_add_result(lty, rty).map(|(res, _)| res);
if let Some(res) = expect {
if actual == "Error" {
panic!("grammar provides rule for {}+{} but actual semantics error", li, ri);
} else {
assert_eq!(res, actual, "grammar expect {} + {} => {}, but actual => {}", li, ri, res, actual);
}
} else {
assert_eq!(actual, "Error", "grammar has no rule for {}+{}, but actual => {}", li, ri, actual);
}
}
}
}