schleifen

A toy interpreter for LOOP programs

git clone https://git.8pit.net/schleifen.git

 1(import test)
 2
 3(include "parser.scm")
 4(include "interpreter.scm")
 5
 6(define (interpret str #!optional (env '()))
 7  (let ((prog (parse-loop-prog str)))
 8    (if prog
 9      (eval-loop-prog env prog)
10      #f)))
11
12(test-group "parser"
13  (test "variable assignment with literal"
14        '((assign (var . "x")
15                  (lit . 5)))
16        (parse-loop-prog "x := 5;"))
17
18  (test "variable assignment with expression"
19        '((assign (var . "y")
20                  (expr (var . "y")
21                        (op . minus)
22                        (var . "y"))))
23        (parse-loop-prog "y:=y-y;"))
24
25  (test "variable assign with variable"
26        '((assign (var . "a") (var . "b")))
27        (parse-loop-prog "a:=b;"))
28
29  (test "loop with variable condition"
30        '((loop (var . "x")
31                ((assign (var . "x") (var . "x")))))
32        (parse-loop-prog "LOOP x DO x:=x; DONE;"))
33
34  (test "loop with loop in body"
35        '((loop (lit . 1)
36                ((loop (lit . 2)
37                       ((assign (var . "x") (lit . 5)))))))
38        (parse-loop-prog "LOOP 1 DO LOOP 2 DO x:=5; DONE; DONE;"))
39
40  (test "sequence of multiple assignments"
41        '((assign (var . "x") (lit . 1))
42          (assign (var . "x") (lit . 2)))
43        (parse-loop-prog "x := 1; x := 2;")))
44
45(test-group "interpreter"
46  (test "variable assignment with literal"
47        '(("a" . 1)) (interpret "a := 1;"))
48
49  (test "variable assignment with variable"
50        '(("y" . 42) ("x" . 42)) (interpret "y := x;" '(("x" . 42))))
51
52  (test "variable assignment with expression"
53        '(("x" . 2)) (interpret "x := 1 + 1;"))
54
55  (test "variable default values"
56        '(("x" . 1)) (interpret "x := y + 1;"))
57
58  (test "loop with literal condition"
59        '(("x" . 3)) (interpret "LOOP 3 DO x := x + 1; DONE;"))
60
61  (test "loop with condition modification"
62        '(("z". 2)) (interpret "LOOP z DO z := z + 1; DONE;" '(("z" . 1))))
63
64  (test "loop with false condition"
65        '() (interpret "LOOP 0 DO x := 42; DONE;")))