-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathlisp.pl
77 lines (47 loc) · 1.35 KB
/
lisp.pl
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
symbol(X) :- atom(X).
%symbol(X) :- freeze(X, atom(X)).
symbols(X) :- symbol(X).
symbols([]).
symbols([H|T]) :-
symbols(H),
symbols(T).
% lookup(X, Env, Val).
%
% [quote-unbound(quote)] will be the empty environment
% when unbound(quote) is returned, this means that
% `quote` is unbound
lookup(X, [X-Val|_], Val) :- !.
lookup(X, [Y-_|Tail], Val) :-
X \= Y,
%dif(X, Y),
lookup(X, Tail, Val).
% to avoid name clashing with `eval`
%
% evil(Expr, Env, Val).
evil([quote, X], Env, X) :-
lookup(quote, Env, unbound(quote)),
symbols(X).
evil(Expr, Env, Val) :-
symbol(Expr),
lookup(Expr, Env, Val),
Val \= unbound(quote).
%dif(Val, unbound(quote)).
evil([lambda, [X], Body], Env, closure(X, Body, Env)).
evil([list|Tail], Env, Val) :-
evil_list(Tail, Env, Val).
evil([E1, E2], Env, Val) :-
evil(E1, Env, closure(X, Body, Env1_Old)),
evil(E2, Env, Arg),
evil(Body, [X-Arg|Env1_Old], Val).
evil([cons, E1, E2], Env, Val) :-
evil(E1, Env, E1E),
evil(E2, Env, E2E),
Val = [E1E | E2E].
evil_list([], _, []).
evil_list([H|T], Env, [H2|T2]) :-
evil(H, Env, H2), evil_list(T, Env, T2).
% evaluate in the empty environment
evil(Expr, Val) :-
evil(Expr, [quote-unbound(quote)], Val).
%evil(X, [i, love, you]), print(X).
%https://stackoverflow.com/questions/65446636/pure-prolog-scheme-quine