sim-nest 0.1.5

The SIM constellation umbrella facade: one crate that re-exports the runtime kernel, codecs, number domains, and libraries behind features.
Documentation
use sim_kernel::{Expr, NumberLiteral, QuoteMode, Symbol, config_list_impl_capability};

use super::support::{call_expr, eval_cx};

fn number(text: &str) -> Expr {
    Expr::Number(NumberLiteral {
        domain: Symbol::qualified("numbers", "f64"),
        canonical: text.to_owned(),
    })
}

#[cfg(feature = "list-lazy")]
#[test]
fn list_impl_can_switch_to_lazy_backend() {
    let mut cx = eval_cx();
    cx.grant(config_list_impl_capability());

    let switched = cx
        .eval_expr(call_expr(
            Symbol::new("list-impl"),
            vec![Expr::Quote {
                mode: QuoteMode::Quote,
                expr: Box::new(Expr::Symbol(Symbol::new("lazy"))),
            }],
        ))
        .unwrap();
    assert_eq!(
        switched.object().as_expr(&mut cx).unwrap(),
        Expr::Symbol(Symbol::new("lazy"))
    );

    let len = cx
        .eval_expr(call_expr(
            Symbol::new("len"),
            vec![call_expr(
                Symbol::new("list"),
                vec![number("1"), number("2"), number("3")],
            )],
        ))
        .unwrap();
    assert_eq!(
        len.object().as_expr(&mut cx).unwrap(),
        Expr::Symbol(Symbol::new("unknown"))
    );

    let nth = cx
        .eval_expr(call_expr(
            Symbol::new("nth"),
            vec![
                call_expr(
                    Symbol::new("list"),
                    vec![number("7"), number("8"), number("9")],
                ),
                number("2"),
            ],
        ))
        .unwrap();
    assert_eq!(nth.object().as_expr(&mut cx).unwrap(), number("9"));

    let len_gte = cx
        .eval_expr(call_expr(
            Symbol::new("len>="),
            vec![
                call_expr(
                    Symbol::new("list"),
                    vec![number("7"), number("8"), number("9")],
                ),
                number("2"),
            ],
        ))
        .unwrap();
    assert_eq!(len_gte.object().as_expr(&mut cx).unwrap(), Expr::Bool(true));

    let take = cx
        .eval_expr(call_expr(
            Symbol::new("take"),
            vec![
                call_expr(
                    Symbol::new("list"),
                    vec![number("7"), number("8"), number("9")],
                ),
                number("2"),
            ],
        ))
        .unwrap();
    assert_eq!(
        take.object().as_expr(&mut cx).unwrap(),
        Expr::List(vec![number("7"), number("8")])
    );
}

#[cfg(feature = "list-lazy")]
#[test]
fn list_impl_can_switch_to_iter_backend() {
    let mut cx = eval_cx();
    cx.grant(config_list_impl_capability());

    let switched = cx
        .eval_expr(call_expr(
            Symbol::new("list-impl"),
            vec![Expr::Quote {
                mode: QuoteMode::Quote,
                expr: Box::new(Expr::Symbol(Symbol::new("iter"))),
            }],
        ))
        .unwrap();
    assert_eq!(
        switched.object().as_expr(&mut cx).unwrap(),
        Expr::Symbol(Symbol::new("iter"))
    );

    let head = cx
        .eval_expr(call_expr(
            Symbol::new("car"),
            vec![call_expr(
                Symbol::new("cons"),
                vec![
                    number("5"),
                    call_expr(Symbol::new("list"), vec![number("6"), number("7")]),
                ],
            )],
        ))
        .unwrap();
    assert_eq!(head.object().as_expr(&mut cx).unwrap(), number("5"));

    let third = cx
        .eval_expr(call_expr(
            Symbol::new("nth"),
            vec![
                call_expr(
                    Symbol::new("cons"),
                    vec![
                        number("5"),
                        call_expr(Symbol::new("list"), vec![number("6"), number("7")]),
                    ],
                ),
                number("2"),
            ],
        ))
        .unwrap();
    assert_eq!(third.object().as_expr(&mut cx).unwrap(), number("7"));
}