scheme4r 0.2.3

Scheme interpreter for rust
Documentation
use scheme4r::{eval, interpreter, Environment, Value};

#[test]
fn arithmetic_and_nested_calls_work() {
    let value = eval("(+ 1 2 (* 3 4))").unwrap();
    assert!(matches!(value, Value::Number(15)));
}

#[test]
fn define_and_lambda_support_recursion() {
    let value = eval(
        "\
        (define (fact n)
          (if (= n 0)
              1
              (* n (fact (- n 1)))))
        (fact 6)
        ",
    )
    .unwrap();

    assert!(matches!(value, Value::Number(720)));
}

#[test]
fn quote_and_list_primitives_work() {
    let value = eval("(car '(1 2 3))").unwrap();
    assert!(matches!(value, Value::Number(1)));

    let list = eval("(cdr '(1 2 3))").unwrap();
    assert_eq!(format!("{list}"), "(2 3)");
}

#[test]
fn closures_capture_environment() {
    let value = eval(
        "\
        (define make-adder
          (lambda (x)
            (lambda (y) (+ x y))))
        (define add5 (make-adder 5))
        (add5 9)
        ",
    )
    .unwrap();

    assert!(matches!(value, Value::Number(14)));
}

#[test]
fn interpreter_reuses_injected_environment() {
    let env = Environment::standard();
    interpreter("(define counter 40)", env.clone()).unwrap();
    let value = interpreter("(begin (set! counter (+ counter 2)) counter)", env).unwrap();
    assert!(matches!(value, Value::Number(42)));
}

#[test]
fn equal_checks_structure() {
    let value = eval("(equal? '(1 (2 3)) '(1 (2 3)))").unwrap();
    assert!(matches!(value, Value::Boolean(true)));
}