rusche 0.2.4

A lightweight Scheme interpreter embeddable in Rust applications
Documentation
mod common;

use common::EvalToStr;
use rusche::eval::{EvalContext, Evaluator};

fn eval_str(src: &str) -> String {
    Evaluator::with_builtin().eval_to_str(src)
}

#[test]
fn test_car() {
    assert_eq!(eval_str("(car '(1 2))"), "1");
}

#[test]
fn test_cdr() {
    assert_eq!(eval_str("(cdr '(1 2))"), "(2)");
}

#[test]
fn test_define_variable() {
    let e = Evaluator::with_builtin();
    let outer_context = e.context();
    let _ = outer_context.eval_to_str("(define x 1)");
    assert_eq!(outer_context.eval_to_str("x"), "1");
    let _ = outer_context.eval_to_str("(set! x 2)");
    assert_eq!(outer_context.eval_to_str("x"), "2");

    let inner_context = EvalContext::derive_from(&outer_context);

    let _ = inner_context.eval_to_str("(define y 100)");
    assert_eq!(inner_context.eval_to_str("y"), "100");
    let _ = inner_context.eval_to_str("(set! y 200)");
    assert_eq!(inner_context.eval_to_str("y"), "200");

    assert_eq!(inner_context.eval_to_str("x"), "2");
    assert!(outer_context.eval_to_str("y").starts_with("Err:"));
}

#[test]
fn test_define_lambda() {
    let e = Evaluator::with_builtin();
    let _ = e.eval_to_str("(define (do-math x y) (num-subtract (num-multiply x 2) y))");
    assert_eq!(e.eval_to_str("(do-math 50 1)"), "99");
}

#[test]
fn test_eval() {
    assert_eq!(eval_str("(eval '(num-add 1 2))"), "3");
}

#[test]
fn test_if() {
    assert_eq!(eval_str("(if 't 1)"), "1");
    assert_eq!(eval_str("(if 't 1 2)"), "1");

    assert_eq!(eval_str("(if '() 1)"), "()");
    assert_eq!(eval_str("(if '() 1 2)"), "2");
}

#[test]
fn test_lambda() {
    assert_eq!(eval_str("((lambda (x) (num-multiply x 2)) 5)"), "10");
}

#[test]
fn test_set() {
    let e = Evaluator::with_builtin();
    let outer_context = e.context();
    let inner_context = EvalContext::derive_from(&outer_context);

    let _ = outer_context.eval_to_str("(define x 1)");
    assert_eq!(outer_context.eval_to_str("x"), "1");
    let _ = outer_context.eval_to_str("(set! x 2)");
    assert_eq!(outer_context.eval_to_str("x"), "2");

    let _ = inner_context.eval_to_str("(set! x 3)");
    assert_eq!(inner_context.eval_to_str("x"), "3");
    assert_eq!(outer_context.eval_to_str("x"), "3");
}