1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
use ergotree_ir::mir::collection::Collection; use ergotree_ir::mir::constant::TryExtractFromError; use ergotree_ir::mir::constant::TryExtractInto; use ergotree_ir::mir::value::CollKind; use ergotree_ir::mir::value::NativeColl; use ergotree_ir::mir::value::Value; use ergotree_ir::types::stype::SType; use crate::eval::env::Env; use crate::eval::EvalContext; use crate::eval::EvalError; use crate::eval::Evaluable; impl Evaluable for Collection { fn eval(&self, env: &Env, ctx: &mut EvalContext) -> Result<Value, EvalError> { Ok(match self { Collection::BoolConstants(bools) => bools.clone().into(), Collection::Exprs { elem_tpe, items } => { let items_v: Result<Vec<Value>, EvalError> = items.iter().map(|i| i.eval(env, ctx)).collect(); match elem_tpe { SType::SByte => { let bytes: Result<Vec<i8>, TryExtractFromError> = items_v? .into_iter() .map(|i| i.try_extract_into::<i8>()) .collect(); Value::Coll(CollKind::NativeColl(NativeColl::CollByte(bytes?))) } _ => Value::Coll(CollKind::WrappedColl { elem_tpe: elem_tpe.clone(), items: items_v?, }), } } }) } } #[cfg(test)] mod tests { use super::*; use crate::eval::tests::eval_out_wo_ctx; use ergotree_ir::mir::expr::Expr; use proptest::prelude::*; proptest! { #[test] fn eval_byte_coll(bytes in any::<Vec<i8>>()) { let value: Value = bytes.clone().into(); let exprs: Vec<Expr> = bytes.into_iter().map(|b| Expr::Const(b.into())).collect(); let coll: Expr = Collection::new(SType::SByte, exprs).unwrap().into(); let res = eval_out_wo_ctx::<Value>(&coll); prop_assert_eq!(res, value); } #[test] fn eval_bool_coll(bools in any::<Vec<bool>>()) { let exprs: Vec<Expr> = bools.clone().into_iter().map(|b| Expr::Const(b.into())).collect(); let coll: Expr = Collection::new(SType::SBoolean, exprs).unwrap().into(); let res = eval_out_wo_ctx::<Vec<bool>>(&coll); prop_assert_eq!(res, bools); } #[test] fn eval_long_coll(longs in any::<Vec<i64>>()) { let exprs: Vec<Expr> = longs.clone().into_iter().map(|b| Expr::Const(b.into())).collect(); let coll: Expr = Collection::new(SType::SLong, exprs).unwrap().into(); let res = eval_out_wo_ctx::<Vec<i64>>(&coll); prop_assert_eq!(res, longs); } #[test] fn eval_bytes_coll_coll(bb in any::<Vec<Vec<i8>>>()) { let exprs: Vec<Expr> = bb.clone().into_iter().map(|b| Expr::Const(b.into())).collect(); let coll: Expr = Collection::new(SType::SColl(SType::SByte.into()), exprs).unwrap().into(); let res = eval_out_wo_ctx::<Vec<Vec<i8>>>(&coll); prop_assert_eq!(res, bb); } } }