Lisp|
begin comment ALGOL 60 version of program lisp(input,output).
*** version 1, March 28, l988 ***
*** author: F.E.J. Kruseman Aretz ***
*** Philips Research Laboratory Eindhoven ***;
integer maxidf,maxnbr,maxstruct; maxidf:= 200; maxnbr:= 200; maxstruct:= 2000;
begin
integer sym,shift,lastidf,lastnbr,d24,d25,free,indentation,linewidth,dummy,
f,
args,
p,
id,
olp,
t,
nilv,
quote,
cond,
lambda,
define,
car,
cdr,
cons,
equal,
atom,
numberp,
lessp,
greaterp,
add1,
sub1,
add,
minus,
timesv,
divf;
integer array idf[0:maxidf,0:9],alist[0:maxidf];
real array nbr[0:maxnbr];
integer array a,d[1:maxstruct];
boolean array m[1:maxstruct];
comment *** error handling ***;
procedure SPACE (n); value n; integer n;
begin integer i;
for i:= 1 step 1 until n do
writetext(10,[*]);
end SPACE;
procedure errorhandler(errorstring); string errorstring;
begin SPACE(2); writetext(10,[+++*error:*]); writetext(10,errorstring);
goto ex;
end errorhandler;
comment *** representation dependent functions ***;
procedure collect garbage;
begin integer i,j;
free:= 0;
for i:= 1 step 1 until maxstruct do m[i]:= true;
SPACE(1); writetext(10,[garbage*collector:*]);
mark(olp);
for i:= 0 step 1 until lastidf - 1 do mark(alist[i]);
for i:= 1 step 1 until maxstruct do
if m[i] then begin a[i]:= free; free:= i end;
if free = 0 then errorhandler([free*list*exhausted_]);
i:= 1; j:= free;
for j:= carf(j) while j ± 0 do i:= i + 1;
write(10,format([-nnnd_]),i); SPACE(1)
end collect garbage;
procedure mark(ref); value ref; integer ref;
begin
work: if ref < d24
then begin if m[ref]
then begin m[ref]:= false;
mark(a[ref]); ref:= d[ref]; goto work
end
end
end mark;
integer procedure createidf;
begin integer i,j;
i:= 0;
for dummy:= 0 while i < lastidf do
begin for j:= 0 step 1 until 9 do
if idf[lastidf,j] ± idf[i,j] then goto diff;
goto old;
diff: i:= i + 1
end;
new: i:= lastidf; alist[i]:= nilv; lastidf:= lastidf + 1;
if lastidf = maxidf then
begin for i:= 0 step 1 until 99 do
begin SPACE(1); writev(d25+i) end;
errorhandler([too*much*identifiers_])
end;
old: createidf:= d25 + i
end createidf;
integer procedure createnum(x); real x;
begin integer i;
nbr[last nbr]:= x; i:= 0;
for dummy:= 0 while i < last nbr do
begin if nbr[last nbr] = nbr[i] then goto old;
i:= i + 1
end;
new: i:= last nbr; last nbr:= last nbr + 1;
if last nbr = maxnbr then errorhandler([too*much*numbers_]);
old: createnum:= d24 + i
end createnum;
boolean procedure atomf(x); value x; integer x;
begin atomf:= x > d24 end atomf;
boolean procedure numberpf(x); value x; integer x;
begin numberpf:= x > d24 and x < d25 end numberpf;
procedure getidfval(x,idf); value x; integer x,idf;
begin idf:= x - d25 end getidfval;
real procedure numval(x); value x; integer x;
begin numval:=nbr[ x - d24] end numval;
integer procedure carf(x); value x; integer x;
begin if x > d24
then errorhandler([car*undefined*for*atomic*lisp*value_]);
carf:= a[x]
end carf;
integer procedure cdrf(x); value x; integer x;
begin if x > d24
then errorhandler([cdr*undefined*for*atomic*lisp*value_]);
cdrf:= d[x]
end cdrf;
integer procedure consf(x,y);
value x,y; integer x,y;
begin integer n;
if free = 0 then collect garbage;
n:= free; free:= a[free];
a[n]:= x; d[n]:= y; consf:= n
end consf;
procedure returncell(x); value x; integer x;
begin a[x]:= free; free:= x end;
procedure returnlist(x); value x; integer x;
begin for dummy:= 0 while x ± nilv do
begin returncell(x); x:= d[x] end
end returnlist;
procedure recycle(x); value x; integer x;
begin for dummy:= 0 while not atomf(x) do
begin recycle(a[x]); returncell(x); x:= d[x] end
end recycle;
boolean procedure equalf(x,y);
value x,y; integer x,y;
begin switch s:= str,num,id;
work:
if x ÷ d24 = y ÷ d24
then begin goto s[x ÷ d24 + 1];
id: num: equalf:= x = y; goto ex;
str: if equalf(a[x],a[y])
then begin x:= d[x]; y:= d[y];
goto work
end
else equalf:= false
end
else equalf := false;
ex:
end equalf;
comment *** input procedures ***;
integer procedure RESYM;
begin integer s;
s:= charin(20);
if s = 122 or s = 124 then begin shift:= s;
RESYM:= RESYM
end else
if s = 16 then RESYM:= 93 else
if s = 26 then RESYM:=119 else
if s = 8 and shift = 124 then RESYM:= 98 else
if s = 25 and shift = 124 then RESYM:= 99 else
if s = 107 then RESYM:= 88 else
if s = 32 then RESYM:= 0 else
begin s:= s÷32×32 + s - s÷16×16;
if s = 0 then errorhandler([eof_]);
RESYM:= if s < 10 then s else
if s < 64 then s - 6 else
if s < 96 then s - 46 else s - 87
end
end RESYM;
procedure nextsym;
begin sym:= RESYM; PRSYM(sym) end nextsym;
procedure skipspaces;
begin for dummy:= 0
while sym = 93 or sym = 118 or sym = 119 do nextsym
end skipspaces;
integer procedure number;
begin real x; boolean signed;
x:= 0; signed:= (sym = 65);
if signed
then begin nextsym;
if sym > 9 then errorhandler([digit*expected*in*input_])
end;
for dummy:= 0 while sym < 10 do
begin x:= 10 × x + sym; nextsym end;
number:= createnum(if signed then -x else x)
end number;
integer procedure identifier;
begin integer i;
idf[lastidf,0]:= sym; nextsym;
for i:= 1 step 1 until 9 do idf[lastidf,i]:= 93;
i:= 0;
for dummy:= 0 while sym < 64 and i < 9 do
begin i:= i + 1; idf[lastidf,i]:= sym; nextsym end;
for dummy:= 0 while sym < 64 do nextsym;
identifier:= createidf
end identifier;
integer procedure nextitem;
begin integer lv,op;
skipspaces;
if sym < 10 or sym = 65 then nextitem:= number
else
if sym < 64 then nextitem := identifier
else
if sym = 98
then begin nextsym; skipspaces;
if sym = 99
then begin nextitem:= nilv; nextsym end
else begin op:= olp; olp:= consf(nilv,op);
lv:= a[olp]:= consf(nilv,nilv); nextitem:= lv;
a[lv]:= nextitem; skipspaces;
if sym = 88
then begin nextsym; d[lv]:= nextitem;
skipspaces;
if sym ± 99
then errorhandler
([close*missing*for*dotted*pair*in*input_])
end
else for dummy:= 0 while sym ± 99 do
begin lv:= d[lv]:= consf(nilv,nilv);
a[lv]:= nextitem; skipspaces
end;
nextsym;
olp:= op
end;
end
else
if sym = 120
then begin nextsym;
op:= olp; olp:= consf(nilv,olp);
lv:= a[olp]:= consf(nilv,nilv); nextitem:= lv;
a[lv]:= quote; lv:= d[lv]:= consf(nilv,nilv); a[lv]:= nextitem;
olp:= op
end
else errorhandler([illegal*symbol*in*input_])
end nextitem;
comment *** output procedures ***;
procedure PRSYM(sym); value sym; integer sym;
begin switch sw:= a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,
a,b,c,d,e,f,g,h,i,j,k,l,m,
n,o,p,q,r,s,t,u,v,w,x,y,z;
if sym = 93 then SPACE(1) else
if sym = 88 then writetext(10,[.]) else
if sym = 98 then writetext(10,[(]) else
if sym = 99 then writetext(10,[)]) else
if sym = 119 then SPACE(1) else
begin if sym > 35
then errorhandler([illegal*output*symbol_]);
goto sw[sym+1];
a0: writetext(10,[0]); goto ex;
a1: writetext(10,[1]); goto ex;
a2: writetext(10,[2]); goto ex;
a3: writetext(10,[3]); goto ex;
a4: writetext(10,[4]); goto ex;
a5: writetext(10,[5]); goto ex;
a6: writetext(10,[6]); goto ex;
a7: writetext(10,[7]); goto ex;
a8: writetext(10,[8]); goto ex;
a9: writetext(10,[9]); goto ex;
a: writetext(10,[a_]); goto ex;
b: writetext(10,[b_]); goto ex;
c: writetext(10,[c_]); goto ex;
d: writetext(10,[d_]); goto ex;
e: writetext(10,[e_]); goto ex;
f: writetext(10,[f_]); goto ex;
g: writetext(10,[g_]); goto ex;
h: writetext(10,[h_]); goto ex;
i: writetext(10,[i_]); goto ex;
j: writetext(10,[j_]); goto ex;
k: writetext(10,[k_]); goto ex;
l: writetext(10,[l_]); goto ex;
m: writetext(10,[m_]); goto ex;
n: writetext(10,[n_]); goto ex;
o: writetext(10,[o_]); goto ex;
p: writetext(10,[p_]); goto ex;
q: writetext(10,[q_]); goto ex;
r: writetext(10,[r_]); goto ex;
s: writetext(10,[s_]); goto ex;
t: writetext(10,[t_]); goto ex;
u: writetext(10,[u_]); goto ex;
v: writetext(10,[v_]); goto ex;
w: writetext(10,[w_]); goto ex;
x: writetext(10,[x_]); goto ex;
y: writetext(10,[y_]); goto ex;
z: writetext(10,[z_])
end;
ex:
end PRSYM;
procedure analyse(x,r); value x; integer x,r;
begin integer n,l; boolean simple;
if numberpf(x)
then begin real dg,v,absv;
v:= numval(x);
if v > 0
then begin absv:= v; l:= 1 end
else begin absv:= - v;l:= 2 end;
dg:= 10;
for dummy:= 0 while dg < absv do
begin l:= l + 1; dg:= 10 × dg end;
r:= createnum(l)
end
else
if atomf(x)
then begin getidfval(x,id); n:= 10;
for dummy:= 0 while idf[id,n-1] = 93 do n:= n - 1;
r:= createnum(n)
end
else
if islist(x)
then begin indentation:= indentation + 1;
analyselist(x,r,l,simple);
indentation:= indentation - 1;
if simple and indentation + l < linewidth
then begin recycle(r); r:= createnum(l) end
end
else begin indentation:= indentation + 1;
olp:= consf(nilv,olp);
r:= a[olp]:= consf(nilv,nilv);
analyse(carf(x),a[r]); analyse(cdrf(x),d[r]);
indentation:= indentation - 1;
if atomf(a[r]) and atomf(d[r])
then begin l:= numval(carf(r)) + numval(cdrf(r)) + 5;
if indentation + l < linewidth
then begin recycle(r); r:= createnum(l) end
end;
returncell(olp); olp:= d[olp]
end
end analyse;
procedure analyselist(x,r,l,simple);
value x; integer x,r,l; boolean simple;
begin if x = nilv
then begin r:= nilv; l:= 1; simple:= true end
else begin olp:= consf(nilv, olp);
r:= a[olp]:= consf(nilv,nilv);
analyse(carf(x),a[r]); analyselist(cdrf(x),d[r],l,simple);
if simple and atomf(a[r])
then l:= numval(a[r]) + l + 1
else simple:= false;
returncell(olp); olp:= d[olp]
end
end analyselist;
boolean procedure islist(x); value x; integer x;
begin
work: if atomf(x)
then islist:= equalf(x,nilv)
else begin x:= cdrf(x); goto work end
end islist;
procedure writenumber(x); value x; integer x;
begin integer n,d,v;
v:= numval(x);
if v < 0 then v:= - v;
d:= 10;
for dummy:= 0 while d < v do d:= d × 10;
for d:= d ÷ 10 while d > 0.5 do
begin n:= v÷ d; PRSYM(n); v:= v - d × n end
end writenumber;
procedure writeidentifier(x); value x; integer x;
begin integer i;
getidfval(x,id);
for i:= 0 step 1 until 9 do
if idf[id,i] ± 93 then PRSYM(idf[id,i])
end writeidentifier;
procedure writelist(x,r); value x,r; integer x,r;
begin integer a,ind; boolean simple,nl;
PRSYM(98);
if atomf(r)
then begin for dummy:= 0 while x ± nilv do
begin writevalue(carf(x),r); x:= cdrf(x);
if x ± nilv then PRSYM(93)
end
end
else begin indentation:= indentation + 1; ind:= indentation;
for dummy:= 0 while x ± nilv do
begin a:= carf(r);
simple:= atomf(a);
if simple
then nl:= numval(a) + indentation > linewidth
else nl:= indentation > ind;
if nl
then begin indentation:= ind;
SPACE(1); SPACE(ind)
end
else if indentation > ind then PRSYM(93);
writevalue(carf(x),a);
if simple
then indentation:= indentation + numval(a) + 1
else indentation:= linewidth + 1;
x:= cdrf(x); r:= cdrf(r)
end;
indentation:= ind - 1; SPACE(1); SPACE(indentation)
end;
PRSYM(99)
end writelist;
procedure writepair(x,r); value x,r; integer x,r;
begin PRSYM(98);
if atomf(r)
then begin writevalue(carf(x),r); writetext(10,[*.*]);
writevalue(cdrf(x),r)
end
else begin indentation:= indentation + 1;
writevalue(carf(x),carf(r));
SPACE(1); SPACE(indentation-1); writetext(10,[*.*]);
SPACE(1); SPACE(indentation); writevalue(cdrf(x),cdrf(r));
SPACE(1); SPACE(indentation)
end;
PRSYM(99)
end writepair;
procedure writevalue(x,r); value x,r; integer x,r;
begin if numberpf(x) then writenumber(x)
else
if atomf(x) then writeidentifier(x)
else
if islist(x) then writelist(x,r)
else writepair(x,r)
end writevalue;
procedure writev(x); value x; integer x;
begin integer r;
indentation:= 0;
analyse(x,r); writevalue(x,r); recycle(r)
end writev;
comment *** interpreter proper ***;
integer procedure assoc(x); value x; integer x;
begin integer ax;
getidfval(x,id); ax:= alist[id];
if ax = nilv then errorhandler([identifier*has*no*value_]);
assoc:= carf(ax)
end assoc;
procedure pairlis(x,y); value x,y; integer x,y;
begin for dummy:= 0 while not equalf(x,nilv) do
begin getidfval(carf(x),id); alist[id]:= consf(carf(y),alist[id]);
x:= cdrf(x); y:= cdrf(y)
end
end pairlis;
procedure depairlis(x); value x; integer x;
begin for dummy:= 0 while not equalf(x,nilv) do
begin getidfval(carf(x),id); alist[id]:= cdrf(alist[id]);
x:= cdrf(x)
end
end depairlis;
integer procedure eval(e); value e; integer e;
begin integer care;
work: if atomf(e)
then begin if equalf(e,nilv) or equalf(e,t) or numberpf(e)
then eval:= e else eval:= assoc(e)
end
else begin care:= carf(e);
if equalf(care,cond)
then begin e:= evcon(cdrf(e)); goto work end
else if equalf(care,quote)
then eval:= carf(cdrf(e))
else begin olp:= consf(nilv,olp);
a[olp]:= evlist(cdrf(e)); eval:= apply(care,a[olp]);
returnlist(a[olp]); returncell(olp); olp:= cdrf(olp)
end
end
end eval;
integer procedure apply(f,x);
value f,x; integer f,x;
begin
work: if atomf(f)
then begin
if equalf(f,car) then apply:= carf(carf(x))
else
if equalf(f,cdr) then apply:= cdrf(carf(x))
else
if equalf(f,cons) then apply:= consf(carf(x),carf(cdrf(x)))
else
if equalf(f,equal)
then begin if equalf(carf(x),carf(cdrf(x)))
then apply:= t
else apply:= nilv
end
else
if equalf(f,atom) then begin if atomf(carf(x))
then apply:= t
else apply:= nilv
end
else
if equalf(f,numberp) then begin if numberpf(carf(x))
then apply:= t
else apply:= nilv
end
else
if equalf(f,lessp)
then begin if numval(carf(x)) < numval(carf(cdrf(x)))
then apply:= t
else apply:= nilv
end
else
if equalf(f,greaterp)
then begin if numval(carf(x)) > numval(carf(cdrf(x)))
then apply:= t
else apply:= nilv
end
else
if equalf(f,add)
then apply:= createnum(numval(carf(x)) + 1)
else
if equalf(f,sub1)
then apply:= createnum(numval(carf(x)) - 1)
else
if equalf(f,add)
then apply:= createnum(numval(carf(x)) + numval(carf(cdrf(x))))
else
if equalf(f,minus)
then apply:= createnum(numval(carf(x)) - numval(carf(cdrf(x))))
else
if equalf(f,timesv)
then apply:= createnum(numval(carf(x)) × numval(carf(cdrf(x))))
else
if equalf(f,divf)
then apply:= createnum(numval(carf(x)) ÷ numval(carf(cdrf(x))))
else begin f:= assoc(f); goto work end
end
else begin pairlis(carf(cdrf(f)),x);
apply:= eval(carf(cdrf(cdrf(f))));
depairlis(carf(cdrf(f)))
end
end apply;
integer procedure evcon(x); value x; integer x;
begin integer r;
work: r:= carf(x);
if equalf(eval(carf(r)),nilv)
then begin x:= cdrf(x); goto work end
else evcon:= carf(cdrf(r))
end evcon;
integer procedure evlist(x); value x; integer x;
begin integer res;
if equalf(x,nilv)
then evlist:= nilv
else begin olp:= consf(nilv,olp); a[olp]:= res:= consf(nilv,nilv);
a[res]:= eval(carf(x)); d[res]:= evlist(cdrf(x));
evlist:= res;
returncell(olp); olp:= cdrf(olp)
end
end evlist;
comment *** initialization ***;
procedure create(lv); integer lv;
begin skipspaces;
lv:= identifier;
end create;
procedure init;
begin integer i,j;
d24:= 16777216; d25:= 33554432;
last idf:= 0; sym:= 93; nilv:= d25 + 1;
create(t); create(nilv);
create(quote); create(cond);
create(lambda); create(define);
create(car); create(cdr);
create(cons); create(equal);
create(atom); create(numberp);
create(lessp); create(greaterp);
create(add1); create(sub1);
create(add); create(minus);
create(timesv); create(divf);
olp:= nilv;
free:= 1; last nbr:= 0; linewidth:= 40;
for i:= 1 step 1 until maxstruct - 1 do a[i]:= i + 1;
a[maxstruct]:= 0
end init;
comment *** main program ***;
procedure func defs(x,a,r); value x; integer x,a,r;
begin integer carx,lr;
if equalf(x,nilv)
then r:= nilv
else begin carx:= carf(x);
a:= consf(consf(carf(carx),carf(cdrf(carx))),a);
func defs(cdrf(x),a,lr);
r:= consf(carf(carx),lr)
end
end func defs;
open(10);
open(20);
writetext(10,[Lisp*interpreter*version*1,*Oktober*2004]);
writetext(10,[[cccc_]]); SPACE(2);
init;
for dummy:= 0 while true do
begin olp:= consf(nilv,olp); a[olp]:= p:= consf(nilv,nilv);
writetext(10,[A_[c_]]);
a[p]:= f:= nextitem; d[p]:= args:= nextitem;
writetext(10,[B_[c_]]);
SPACE(1);
if equalf(f,define)
then begin args:= carf(args); PRSYM(98);
for dummy:= 0 while not equalf(args,nilv) do
begin p:= carf(args); writev(carf(p));
getidfval(carf(p),id);
alist[id]:= consf(carf(cdrf(p)),nilv);
args:= cdrf(args);
if not equalf(args,nilv) then SPACE(1)
end;
PRSYM(99)
end
else begin p:= apply(f,args);
SPACE(1); writev(p)
end;
olp:= cdrf(olp);
writetext(10,[Z_[c_]]);
end;
ex:
end;
close(20);
close(10);
end
|
t nil quote cond lambda define car cdr cons equal atom numberp
lessp greaterp add1 sub1 add minus times div
define ((
(crossriver (lambda ( ) (complete (cons (i) nil))))
(complete
(lambda (path)
(cond ((equal (car path) (f)) (cons path nil))
(t (try path (fullmoveset)))
) ) )
(try
(lambda (path moveset)
(cond ((null moveset) nil)
((feasible (car moveset) (car path))
(append (try1 path (result (car moveset) (car path)))
(try path (cdr moveset))))
(t (try path (cdr moveset)))
) ) )
(try1
(lambda (path newstate)
(cond ((not (admissible newstate)) nil)
((member newstate path) nil)
(t (complete (cons newstate path)))
) ) )
(i (lambda ( ) (quote ((c c c) (m m m) ( ) ( ) left))))
(f (lambda ( ) (quote ((c c c) (m m m) ( ) ( ) right))))
(fullmoveset
(lambda ( )
(quote (((c c) ( )) ((c) (m)) (( ) (m m)) ((c) ( )) (( ) (m))))
) )
(feasible
(lambda (move state)
(cond ((smaller (car state) (car move)) nil)
((smaller (cadr state) (cadr move)) nil)
(t t)
) ) )
(admissible
(lambda (state)
(cond ((null (cadr state)) t)
((null (cadddr state)) t)
(t (ofequallength (car state) (cadr state)))
) ) )
(result
(lambda (move state)
(list (inc (caddr state) (car move))
(inc (cadddr state) (cadr move))
(dec (car state) (car move))
(dec (cadr state) (cadr move))
(other (caddddr state))
) ) )
(other
(lambda (riverside)
(cond ((equal riverside (quote left)) (quote right))
(t (quote left))
) ) )
(list
(lambda (a b c d e)
(cons a (cons b (cons c (cons d (cons e nil)))))
) )
(smaller
(lambda (x y)
(cond ((null y) nil)
((null x) t)
(t (smaller (cdr x) (cdr y)))
) ) )
(inc
(lambda (x y)
(cond ((null y) x)
(t (inc (cons (car y) x) (cdr y)))
) ) )
(dec
(lambda (x y)
(cond ((null y) x)
(t (dec (cdr x) (cdr y)))
) ) )
(ofequallength
(lambda (x y)
(cond ((null x) (null y))
((null y) nil)
(t (ofequallength (cdr x) (cdr y)))
) ) )
(null (lambda (x) (equal x nil)))
(append
(lambda (x y)
(cond ((null x) y)
(t (cons (car x) (append (cdr x) y)))
) ) )
(not (lambda (x) (equal x nil)))
(member
(lambda (x y)
(cond ((null y) nil)
((equal x (car y)) t)
(t (member x (cdr y)))
) ) )
(cadr (lambda (x) (car (cdr x))))
(caddr (lambda (x) (car (cdr (cdr x)))))
(cadddr (lambda (x) (car (cdr (cdr (cdr x))))))
(caddddr (lambda (x) (car (cdr (cdr (cdr (cdr x)))))))
))
crossriver ( )
||