% LISP 1.5 implemented in Prolog % https://archive.org/details/lisp1.5programmersmanual, p. 13 assoc(A, L, B) :- !, member([A|B], L). pairlis([], [], A, A). pairlis([Kh|Kt], [Vh|Vt], A, [[Kh|Vh]|A0]) :- pairlis(Kt, Vt, A, A0). apply(car, [[E|_]], _, E). apply(cdr, [[_|E]], _, E). apply(cons, [A,B], _, [A|B]). apply(atom, [A], _, R) :- atom(A) -> R = t ; R = []. apply(eq, [A,B], _, R) :- A = B -> R = t ; R = []. apply([lambda, Params, Body], Args, Ctx, R) :- pairlis(Params, Args, Ctx, Ctx0), eval(Body, Ctx0, R). apply([label, Name, Val], Args, Ctx, R) :- apply(Name, Args, [[Name|Val]|Ctx], R). eval(A, Ctx, E) :- atom(A), assoc(A, Ctx, E). eval([quote, A], _, A). eval([cond | Cs], Ctx, A) :- evcon(Cs, Ctx, A). eval([H|T], Ctx, E) :- evlist(T, Ctx, A), apply(H, A, Ctx, E). evcon([], _, []). evcon([H|T], Ctx, R) :- eval(H, Ctx, R) -> evcon(T, Ctx, R); R \= []. evlist([], _, []). evlist([H|T], Ctx, [E|R]) :- eval(H, Ctx, E), evlist(T, Ctx, R). ?- eval([[lambda, [a], [eq, a, [quote, b]]], [quote, b]], [], R).