1
use nms::interpreter::Interpreter;
2
use scripting::nomiscript::{Fraction, Value};
3

            
4
#[test]
5
1
fn test_eval_defun_sum() {
6
1
    let mut interp = Interpreter::new(false).unwrap();
7
1
    let results = interp
8
1
        .eval("(defun sum (a b c) \"Sums A, B, C\" (+ a b c))\n(sum 1 2 3)")
9
1
        .unwrap();
10
1
    assert_eq!(results, vec![Value::Number(Fraction::from_integer(6))]);
11
1
}
12

            
13
#[test]
14
1
fn test_eval_defun_add() {
15
1
    let mut interp = Interpreter::new(false).unwrap();
16
1
    let results = interp
17
1
        .eval("(defun add (a b) (+ a b))\n(add 10 20)")
18
1
        .unwrap();
19
1
    assert_eq!(results, vec![Value::Number(Fraction::from_integer(30))]);
20
1
}
21

            
22
#[test]
23
1
fn test_eval_defun_only() {
24
1
    let mut interp = Interpreter::new(false).unwrap();
25
1
    let results = interp.eval("(defun foo (x) (+ x 1))").unwrap();
26
1
    assert_eq!(results, vec![Value::Symbol("FOO".to_string())]);
27
1
}
28

            
29
#[test]
30
1
fn test_eval_defun_arity_error() {
31
1
    let mut interp = Interpreter::new(false).unwrap();
32
1
    let result = interp.eval("(defun add (a b) (+ a b))\n(add 1)");
33
1
    assert!(result.is_err());
34
1
}
35

            
36
#[test]
37
1
fn test_eval_defun_persistence() {
38
1
    let mut interp = Interpreter::new(false).unwrap();
39
1
    interp.eval("(defun add (a b) (+ a b))").unwrap();
40
1
    let results = interp.eval("(add 3 4)").unwrap();
41
1
    assert_eq!(results, vec![Value::Number(Fraction::from_integer(7))]);
42
1
}
43

            
44
#[test]
45
1
fn test_eval_funcall_native() {
46
1
    let mut interp = Interpreter::new(false).unwrap();
47
1
    let results = interp.eval("(funcall + 1 2 3)").unwrap();
48
1
    assert_eq!(results, vec![Value::Number(Fraction::from_integer(6))]);
49
1
}
50

            
51
#[test]
52
1
fn test_eval_funcall_user() {
53
1
    let mut interp = Interpreter::new(false).unwrap();
54
1
    let results = interp
55
1
        .eval("(defun add (a b) (+ a b))\n(funcall add 10 20)")
56
1
        .unwrap();
57
1
    assert_eq!(results, vec![Value::Number(Fraction::from_integer(30))]);
58
1
}
59

            
60
#[test]
61
1
fn test_eval_apply_quoted_list() {
62
1
    let mut interp = Interpreter::new(false).unwrap();
63
1
    let results = interp.eval("(apply + '(1 2 3))").unwrap();
64
1
    assert_eq!(results, vec![Value::Number(Fraction::from_integer(6))]);
65
1
}
66

            
67
#[test]
68
1
fn test_eval_apply_mixed_args() {
69
1
    let mut interp = Interpreter::new(false).unwrap();
70
1
    let results = interp.eval("(apply + 1 2 '(3 4))").unwrap();
71
1
    assert_eq!(results, vec![Value::Number(Fraction::from_integer(10))]);
72
1
}
73

            
74
#[test]
75
1
fn test_eval_compile() {
76
1
    let mut interp = Interpreter::new(false).unwrap();
77
1
    let results = interp
78
1
        .eval("(defun add (a b) (+ a b))\n(compile 'add)")
79
1
        .unwrap();
80
1
    assert_eq!(results, vec![Value::Symbol("ADD".to_string())]);
81
1
}
82

            
83
#[test]
84
1
fn test_eval_eval() {
85
1
    let mut interp = Interpreter::new(false).unwrap();
86
1
    let results = interp.eval("(eval '(+ 1 2))").unwrap();
87
1
    assert_eq!(results, vec![Value::Number(Fraction::from_integer(3))]);
88
1
}
89

            
90
#[test]
91
1
fn test_eval_eval_defun() {
92
1
    let mut interp = Interpreter::new(false).unwrap();
93
1
    let results = interp.eval("(eval '(defun x (a) (+ 1 a)))\n(x 5)").unwrap();
94
1
    assert_eq!(results, vec![Value::Number(Fraction::from_integer(6))]);
95
1
}
96

            
97
#[test]
98
1
fn test_eval_eval_self_evaluating() {
99
1
    let mut interp = Interpreter::new(false).unwrap();
100
1
    assert_eq!(
101
1
        interp.eval("(eval 42)").unwrap(),
102
1
        vec![Value::Number(Fraction::from_integer(42))]
103
    );
104
1
    assert_eq!(
105
1
        interp.eval("(eval \"hello\")").unwrap(),
106
1
        vec![Value::String("hello".to_string())]
107
    );
108
1
    assert_eq!(interp.eval("(eval nil)").unwrap(), vec![Value::Nil]);
109
1
}
110

            
111
#[test]
112
1
fn test_eval_eval_symbol() {
113
1
    let mut interp = Interpreter::new(false).unwrap();
114
1
    let results = interp.eval("(eval 'revision)").unwrap();
115
1
    match &results[0] {
116
7
        Value::String(s) => assert!(s.chars().all(|c| c.is_ascii_hexdigit())),
117
        _ => panic!("expected string, got {:?}", results[0]),
118
    }
119
1
}
120

            
121
#[test]
122
1
fn test_eval_lambda_literal() {
123
1
    let mut interp = Interpreter::new(false).unwrap();
124
1
    let results = interp.eval("(lambda (x) (* x 2))").unwrap();
125
1
    assert_eq!(
126
        results,
127
1
        vec![Value::String("(LAMBDA (X) (* X 2))".to_string())]
128
    );
129
1
}
130

            
131
#[test]
132
1
fn test_eval_defun_then_call() {
133
1
    let mut interp = Interpreter::new(false).unwrap();
134
1
    let results = interp
135
1
        .eval("(defun double (x) (* x 2)) (double 5)")
136
1
        .unwrap();
137
1
    assert_eq!(results, vec![Value::Number(Fraction::from_integer(10))]);
138
1
}
139

            
140
#[test]
141
1
fn test_eval_eval_defun_dynamic() {
142
1
    let mut interp = Interpreter::new(false).unwrap();
143
1
    let results = interp
144
1
        .eval("(eval '(defun sum (a) (+ a 1))) (sum 5)")
145
1
        .unwrap();
146
1
    assert_eq!(results, vec![Value::Number(Fraction::from_integer(6))]);
147
1
}
148

            
149
#[test]
150
1
fn test_eval_funcall_lambda() {
151
1
    let mut interp = Interpreter::new(false).unwrap();
152
1
    let results = interp.eval("(funcall (lambda (x y) (+ x y)) 3 4)").unwrap();
153
1
    assert_eq!(results, vec![Value::Number(Fraction::from_integer(7))]);
154
1
}
155

            
156
#[test]
157
1
fn test_eval_function_form() {
158
1
    let mut interp = Interpreter::new(false).unwrap();
159
1
    let results = interp
160
1
        .eval("(defun f (x) (* x 2)) (funcall (function f) 5)")
161
1
        .unwrap();
162
1
    assert_eq!(results, vec![Value::Number(Fraction::from_integer(10))]);
163
1
}
164

            
165
#[test]
166
1
fn test_bare_operator_error() {
167
1
    let mut interp = Interpreter::new(false).unwrap();
168
1
    let err = interp.eval("+").unwrap_err();
169
1
    assert!(
170
1
        err.to_string().contains("is a function"),
171
        "expected function error, got: {err}"
172
    );
173
1
}
174

            
175
#[test]
176
1
fn test_bare_special_form_error() {
177
1
    let mut interp = Interpreter::new(false).unwrap();
178
1
    let err = interp.eval("quote").unwrap_err();
179
1
    assert!(
180
1
        err.to_string().contains("is a special form"),
181
        "expected special form error, got: {err}"
182
    );
183
1
}
184

            
185
#[test]
186
1
fn test_bare_native_function_error() {
187
1
    let mut interp = Interpreter::new(false).unwrap();
188
1
    let err = interp.eval("debug").unwrap_err();
189
1
    assert!(
190
1
        err.to_string().contains("is a function"),
191
        "expected function error, got: {err}"
192
    );
193
1
}
194

            
195
#[test]
196
1
fn test_labels_simple() {
197
1
    let mut interp = Interpreter::new(false).unwrap();
198
1
    let results = interp
199
1
        .eval("(labels ((double (x) (* x 2))) (double 5))")
200
1
        .unwrap();
201
1
    assert_eq!(results, vec![Value::Number(Fraction::from_integer(10))]);
202
1
}
203

            
204
#[test]
205
1
fn test_labels_factorial() {
206
1
    let mut interp = Interpreter::new(false).unwrap();
207
1
    let results = interp
208
1
        .eval(
209
1
            "(defun fact (n)
210
1
               (labels ((go (i acc)
211
1
                          (if (<= i 1) acc (go (- i 1) (* acc i)))))
212
1
                 (go n 1)))
213
1
             (fact 5)",
214
        )
215
1
        .unwrap();
216
1
    assert_eq!(results, vec![Value::Number(Fraction::from_integer(120))]);
217
1
}
218

            
219
#[test]
220
1
fn test_labels_mutual_recursion() {
221
1
    let mut interp = Interpreter::new(false).unwrap();
222
1
    let results = interp
223
1
        .eval(
224
1
            "(labels ((is-even (n) (if (= n 0) t (is-odd (- n 1))))
225
1
                      (is-odd (n) (if (= n 0) nil (is-even (- n 1)))))
226
1
               (is-even 4))",
227
        )
228
1
        .unwrap();
229
1
    assert_eq!(results, vec![Value::Bool(true)]);
230
1
}
231

            
232
#[test]
233
1
fn test_labels_no_body_error() {
234
1
    let mut interp = Interpreter::new(false).unwrap();
235
1
    let err = interp.eval("(labels ((f (x) x)))").unwrap_err();
236
1
    assert!(
237
1
        err.to_string().contains("LABELS requires"),
238
        "expected labels error, got: {err}"
239
    );
240
1
}
241

            
242
#[test]
243
1
fn test_labels_scope() {
244
1
    let mut interp = Interpreter::new(false).unwrap();
245
1
    interp
246
1
        .eval("(labels ((local-fn (x) (+ x 1))) (local-fn 5))")
247
1
        .unwrap();
248
1
    let err = interp.eval("(local-fn 5)").unwrap_err();
249
1
    assert!(
250
1
        err.to_string().contains("undefined")
251
1
            || err.to_string().contains("Undefined")
252
            || err.to_string().contains("not defined"),
253
        "expected undefined error, got: {err}"
254
    );
255
1
}
256

            
257
#[test]
258
1
fn test_1_plus() {
259
1
    let mut interp = Interpreter::new(false).unwrap();
260
1
    let results = interp.eval("(1+ 5)").unwrap();
261
1
    assert_eq!(results, vec![Value::Number(Fraction::from_integer(6))]);
262
1
}
263

            
264
#[test]
265
1
fn test_1_minus() {
266
1
    let mut interp = Interpreter::new(false).unwrap();
267
1
    let results = interp.eval("(1- 5)").unwrap();
268
1
    assert_eq!(results, vec![Value::Number(Fraction::from_integer(4))]);
269
1
}