-
Notifications
You must be signed in to change notification settings - Fork 4
/
eval.mx
77 lines (58 loc) · 1.81 KB
/
eval.mx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
;;;
;;; Section 1.6 - A Universal LISP Function
;;;
(use LISP1.5.mexpr)
;; NB: Before loading this file, you also need to have LISP1.5
;; enviornment so that special forms (COND, QUOTE, DEFINE) are
;; recognized.
#!m-expr
# Primitives (Axioms):
# car, cdr, cons, eq, atom (and cond and quote, implicitly)
# Convenience functions
null[x] = [eq[x;NIL] -> T; T -> F]
caar[x] = car[car[x]]
cadr[x] = car[cdr[x]]
cdar[x] = cdr[car[x]]
caddr[x] = cadr[cdr[x]]
cadar[x] = cadr[car[x]]
equal[x;y] =
[atom[x] -> [atom[y] -> eq[x;y]; T -> F];
equal[car[x]; car[y]] -> equal[cdr[x]; cdr[y]];
T -> F]
subst[x;y;z] =
[equal[y;z] -> x;
atom[z] -> z;
T -> cons[subst[x;y;car[z]];subst[x;y;cdr[z]]]]
append[x;y] =
[null[x] -> y;
T -> cons[car[x];append[cdr[x];y]]]
# Building blocks
pairlis[x;y;a] =
[null[x] -> a;
T -> cons[cons[car[x];car[y]]; pairlis[cdr[x];cdr[y];a]]]
assoc[x;a] =
[equal[caar[a];x] -> car[a];
T -> assoc[x;cdr[a]]]
# Evaluator
apply[fn;x;a] =
[atom[fn] -> [eq[fn;CAR] -> caar[x];
eq[fn;CDR] -> cdar[x];
eq[fn;CONS] -> cons[car[x];cadr[x]];
eq[fn;ATOM] -> atom[car[x]];
eq[fn;EQ] -> eq[car[x];cadr[x]];
T -> apply[eval[fn;a];x;a]];
eq[car[fn];LAMBDA] -> eval[caddr[fn];pairlis[cadr[fn];x;a]];
eq[car[fn];LABEL] -> apply[caddr[fn];x;cons[cons[cadr[fn];caddr[fn]];a]]]
eval[e;a] =
[atom[e] -> cdr[assoc[e;a]];
atom[car[e]] -> [eq[car[e];QUOTE] -> cadr[e];
eq[car[e];COND] -> evcon[cdr[e];a];
T -> apply[car[e];evlis[cdr[e];a];a]];
T -> apply[car[e];evlis[cdr[e];a];a]]
evcon[c;a] =
[eval[caar[c];a] -> eval[cadar[c];a];
T -> evcon[cdr[c];a]]
evlis[m;a] =
[null[m] -> NIL;
T -> cons[eval[car[m];a];evlis[cdr[m];a]]]
evalquote[fn;args] = apply[fn;args;NIL]