Lines
98.32 %
Functions
100 %
Branches
use nms::interpreter::Interpreter;
use scripting::nomiscript::{Fraction, Value};
// LIST
#[test]
fn test_eval_list_empty() {
let mut interp = Interpreter::new(false).unwrap();
let results = interp.eval("(list)").unwrap();
assert_eq!(results, vec![Value::String("()".to_string())]);
}
fn test_eval_list_numbers() {
let results = interp.eval("(list 1 2 3)").unwrap();
assert_eq!(results, vec![Value::String("(1 2 3)".to_string())]);
fn test_eval_list_mixed() {
let results = interp.eval(r#"(list 1 "hello" #t)"#).unwrap();
assert_eq!(results, vec![Value::String("(1 hello #T)".to_string())]);
// CONS
fn test_eval_cons_onto_list() {
let results = interp.eval("(cons 1 (list 2 3))").unwrap();
fn test_eval_cons_onto_nil() {
let results = interp.eval("(cons 1 nil)").unwrap();
assert_eq!(results, vec![Value::String("(1)".to_string())]);
fn test_eval_cons_arity_error() {
assert!(interp.eval("(cons 1)").is_err());
assert!(interp.eval("(cons 1 2 3)").is_err());
// QUOTE
fn test_eval_quote_number() {
let results = interp.eval("(quote 42)").unwrap();
assert_eq!(results, vec![Value::Number(Fraction::from_integer(42))]);
fn test_eval_quote_reader_sugar() {
let results = interp.eval("'42").unwrap();
fn test_eval_quote_string() {
let results = interp.eval("(quote \"hello\")").unwrap();
assert_eq!(results, vec![Value::String("hello".to_string())]);
// DESCRIBE
fn test_eval_describe_function() {
let results = interp
.eval(r#"(defun sum (a b) "Adds two numbers" (+ a b)) (describe sum)"#)
.unwrap();
match &results[0] {
Value::String(s) => {
assert!(s.contains("SUM is a function"), "got: {s}");
assert!(s.contains("Lambda:"), "got: {s}");
assert!(s.contains("Adds two numbers"), "got: {s}");
_ => panic!("expected string, got {:?}", results[0]),
fn test_eval_describe_variable() {
.eval(r#"(defvar *x* 42 "The answer") (describe *x*)"#)
assert!(s.contains("*X* is a variable"), "got: {s}");
assert!(s.contains("Value: 42"), "got: {s}");
assert!(s.contains("The answer"), "got: {s}");
// Nested calls
fn test_nested_comparison_with_subtraction() {
assert_eq!(
interp.eval("(= 1 (- 3 2))").unwrap(),
vec![Value::Bool(true)]
);
fn test_nested_addition_with_multiplication() {
interp.eval("(+ 1 (* 2 3))").unwrap(),
vec![Value::Number(Fraction::from_integer(7))]
fn test_nested_subtraction_multiple_args() {
interp.eval("(- 10 (+ 1 2) (- 5 2))").unwrap(),
vec![Value::Number(Fraction::from_integer(4))]
fn test_nested_addition_both_sides() {
interp.eval("(+ (+ 1 2) (+ 3 4))").unwrap(),
vec![Value::Number(Fraction::from_integer(10))]
fn test_deeply_nested_addition() {
interp.eval("(+ 1 (+ 2 (+ 3 4)))").unwrap(),
fn test_nested_calls_with_defun() {
interp
.eval("(defun double (x) (* x 2)) (+ (double 3) (double 4))")
.unwrap(),
vec![Value::Number(Fraction::from_integer(14))]
fn test_nested_equal_with_arithmetic() {
interp.eval("(equal (+ 1 1) (- 4 2))").unwrap(),
fn test_nested_funcall_with_arithmetic() {
interp.eval("(funcall + (- 10 3) (* 2 3))").unwrap(),
vec![Value::Number(Fraction::from_integer(13))]