home *** CD-ROM | disk | FTP | other *** search
- (*******************************************************)
- (* LISP.INC *)
- (* Include-Modul des LittleLisp-Systems *)
- (* (C) 1988 Reinhard Häring & TOOLBOX *)
- (*******************************************************)
-
- function self_evalp(x:objp):boolean;
- function del_obj(x:objp):boolean;
- begin
- del_obj:=false;
- if x^.typ=3 then
- del_obj:=equal(car(x),p_delayed_obj);
- end;
- var t:integer; n:string20;
- begin
- t:=x^.typ;
- if t=2 then n:=x^.a^;
- self_evalp:= (t=0) or (t=1)
- or ((t=2) and (n='t'))
- or ((t=2) and (n='true'))
- or (t=-1) or del_obj(x);
- end;
-
- function variable(x:objp):boolean;
- begin
- variable:=2=x^.typ;
- end;
-
- function definition_variable(exp:objp):objp;
- begin
- if variable(car(cdr(exp))) then
- definition_variable:=car(cdr(exp))
- else
- definition_variable:=car(car(cdr(exp)));
- end;
-
- function definition_value(exp:objp):objp;
- begin
- if variable(car(cdr(exp))) then
- definition_value:=car(cdr(cdr(exp)))
- else
- definition_value:=cons(p_lambda,
- cons(cdr(car(cdr(exp))),
- cdr(cdr(exp))));
- end;
-
- function eval_definition(exp,env:objp):objp;
- begin
- dummy:=define_variable(definition_variable(exp),
- eval(definition_value(exp),env),
- env);
- eval_definition:=definition_variable(exp);
- end;
-
- function eval_assignment(exp,env:objp):objp;
- var new_value:objp;
- begin
- new_value:=eval(car(cdr(cdr(exp))),env);
- dummy:=set_variable_value(car(cdr(exp)),
- new_value,env);
- eval_assignment:=new_value;
- end;
-
-
- function make_procedure(typ,exp,env:objp):objp;
- begin
- make_procedure:=cons(typ,cons(exp,cons(env,null)));
- end;
-
- function mproc(p:objp):boolean;
- begin
- mproc:=false;
- if (3=p^.typ) then if equal(car(p),p_mprocedure)
- then mproc:=true;
- end;
-
- function dproc(p:objp):boolean;
- begin
- dproc:=false;
- if (3=p^.typ) then if equal(car(p),p_dprocedure)
- then dproc:=true;
- end;
-
- function dellist(l:objp):objp;
- function delay_item(x:objp):objp;
- begin
- delay_item:=cons(p_delay,cons(x,null));
- end;
- begin
- if nullp(l) then dellist:=null else
- dellist:=cons(delay_item(car(l)),dellist(cdr(l)));
- end;
-
- function else_clause(x:objp):boolean;
- begin
- else_clause:= (3=x^.typ) and equal(car(x),p_else)
- end;
-
- function eval_sequence(exps,env:objp):objp;
- begin
- if nullp(cdr(exps)) then
- eval_sequence:=eval(car(exps),env) else
- begin
- dummy:=eval(car(exps),env);
- eval_sequence:=eval_sequence(cdr(exps),env);
- end;
- end;
-
- function map(proc,list,env:objp):objp;
- begin
- if nullp(list) then map:=null else
- if 3<>list^.typ then
- error('no list for map: '+outlist(list))
- else
- map:=cons(apply(proc,cons(car(list),null),env),
- map(proc,cdr(list),env));
- end;
-
- function eval_cond(clist,env:objp):objp;
- begin
- if nullp(clist) then eval_cond:=null else
- if else_clause(car(clist))
- then eval_cond:=eval_sequence(cdr(car(clist)),env)
- else if not nullp(eval(car(car(clist)),env))
- then eval_cond:=eval_sequence(cdr(car(clist)),env)
- else eval_cond:=eval_cond(cdr(clist),env);
- end;
-
- function list_of_values(exps,env:objp):objp;
- begin
- if nullp(exps) then list_of_values:=null else
- list_of_values:=cons(eval(car(exps),env),
- list_of_values(cdr(exps),env));
- end;
-
- function getprop(atom,key:objp):objp;
- var alist,p:objp;
- begin
- alist:=assoc(atom,property);
- if nullp(alist) then getprop:=null
- else begin p:=assoc(key,cdr(alist));
- if nullp(p) then getprop:=null
- else getprop:=cdr(p);
- end;
- end;
-
- function proplist(atom:objp):objp;
- var plist:objp;
- begin
- plist:=assoc(atom,property);
- if nullp(plist) then proplist:=null
- else proplist:=cdr(plist);
- end;
-
- function replace(alist,atom,new_entry:objp):objp;
- { ersetzt in alist alle Einträge für atom durch new_entry}
- begin
- if nullp(alist) then replace:=cons(new_entry,null) else
- if equal(car(car(alist)),atom) then
- if nullp(new_entry) then
- replace:=cdr(alist)
- else
- replace:=cons(new_entry,cdr(alist))
- else
- replace:=cons(car(alist),replace(cdr(alist),
- atom,new_entry));
- end;
-
- function putprop(atom,key,value:objp):objp;
- var old_alist,new_alist:objp;
- begin
- putprop:=value;
- old_alist:=assoc(atom,property);
- if nullp(old_alist) then
- new_alist:=cons(atom,cons(cons(key,value),null))
- else new_alist:=cons(atom,cons(cons(key,value),
- cdr(old_alist)));
- property:=replace(property,atom,new_alist);
- end;
-
- function remprop(atom,key:objp):objp;
- var new_alist,old_alist:objp;
- begin
- remprop:=key;
- old_alist:=assoc(atom,property);
- if not nullp(old_alist) then begin
- new_alist:=cons(atom,replace(cdr(old_alist),
- key,null));
- property:=replace(property,atom,new_alist);
- end;
- end;
-
- function primitive(proc,args,env:objp):objp;
- var a,b,c,d,h:objp;
- p:string[20];
- st:lstring;
- ai,bi:integer;
- function ll(x:boolean):objp;
- begin
- if x then ll:=p_t else ll:=null;
- end;
- begin
- p:=proc^.a^;
- if nullp(args) then { Funktionen mit 0 Argumenten }
- if p='property' then primitive:=property else
- if p='the-env' then primitive:=env else
- if p='dynamic' then begin
- dynamic:=true; primitive:=null;
- end else if p='lexical' then begin
- dynamic:=false; primitive:=null;
- end else if p='dynamic?' then primitive:=ll(dynamic)
- else if p='newline'then begin
- writeln; primitive:=null;
- end
- else if p='read' then begin
- readln(st); primitive:=inlist(st);
- end
- else
- error('0 Arguments to '+outlist(proc))
- else begin
- a:=car(args); b:=cdr(args);
- if nullp(b) then { Funktionen mit 1 Argument }
- if p='delayed?' then primitive:=ll(eq(car(a),p_delayed_obj))
- else if p='proplist' then primitive:=proplist(a)
- else if p='length' then primitive:=make_number(llen(a))
- else if p='-' then primitive:=make_number(-a^.i)
- else if p='+' then primitive:=a
- else if p='strlen' then primitive:=make_number(length(a^.s^))
- else if p='eval' then primitive:=eval(a,env)
- else if p='proc-env' then primitive:=car(cdr(cdr(a)))
- else if p='proc-def' then primitive:=car(cdr(a))
- else if p='null?' then primitive:=ll(nullp(a))
- else if p='atom?' then
- primitive:=ll((2=a^.typ) or (-1=a^.typ) or (0=a^.typ))
- else if p='integer?' then primitive:=ll(0=a^.typ)
- else if p='symbol?' then primitive:=ll(2=a^.typ)
- else if p='number?' then primitive:=ll(0=a^.typ)
- else if p='string?' then primitive:=ll(1=a^.typ)
- else if p='pair?' then primitive:=ll(3=a^.typ)
- else if p='car' then primitive:=car(a)
- else if p='cdr' then primitive:=cdr(a)
- else if p='cdar' then primitive:=cdr(car(a))
- else if p='cddr' then primitive:=cdr(cdr(a))
- else if p='caar' then primitive:=car(car(a))
- else if p='cadr' then primitive:=car(cdr(a))
- else if p='list' then primitive:=cons(a,null) else
- if p='not' then primitive:=ll(nullp(a)) else
- if p='inlist' then primitive:=inlist(a^.s^) else
- if p='outlist' then begin new(h); h^.typ:=1; new(h^.s);
- h^.s^:=outlist(a); primitive:=h; end else
- if p='print' then begin primitive:=a; write(outlist(a)); end else
- if p='read-file' then begin read_file(a); primitive:=a; end else
- error('1 Argument to '+outlist(proc)) else begin
- c:=cdr(b); b:=car(b);
- if nullp(c) then { Funktionen mit 2 Argumenten }
- if p='get' then primitive:=getprop(a,b) else
- if p='rem' then primitive:=remprop(a,b) else
- if p='apply' then primitive:=apply(a,b,env) else
- if p='setcar!' then primitive:=setcar(a,b) else
- if p='setcdr!' then primitive:=setcdr(a,b) else
- if p='eval' then primitive:=eval(a,b) else
- if p='cons' then primitive:=cons(a,b) else
- if p='append' then primitive:=append(a,b) else
- if p='member' then primitive:=ll(member(a,b)) else
- if p='list' then primitive:=cons(a,cons(b,null)) else
- if p='equal' then primitive:=ll(equal(a,b)) else
- if p='eq' then primitive:=ll(eq(a,b)) else
- if p='equal?' then primitive:=ll(equal(a,b)) else
- if p='eq?' then primitive:=ll(eq(a,b)) else
- if p='assoc' then primitive:=assoc(a,b) else
- if p='concat' then begin new(h); h^.typ:=1; new(h^.s);
- h^.s^:=a^.s^+b^.s^; primitive:=h; end else
- if p='+' then primitive:=make_number(a^.i+b^.i) else
- if p='-' then primitive:=make_number(a^.i-b^.i) else
- if p='*' then primitive:=make_number(a^.i*b^.i) else
- if p='/' then primitive:=make_number(a^.i div b^.i) else
- if p='>' then primitive:=ll(a^.i>b^.i) else
- if p='<' then primitive:=ll(a^.i<b^.i) else
- if p='>=' then primitive:=ll(a^.i>=b^.i) else
- if p='<>' then primitive:=ll(a^.i<>b^.i) else
- if p='<=' then primitive:=ll(a^.i<=b^.i) else
- if p='=' then primitive:=ll(a^.i=b^.i) else
- if p='access' then primitive:=lookup_variable_value(a,b) else
- if p='bound-in-frame?' then
- primitive:=ll(not(nullp(assoc(a,car(b))))) else
- if p='bound?' then
- primitive:=ll(not(nullp(binding_in_env(a,b)))) else
- if p='map' then primitive:=map(a,b,env) else
- error('2 Arguments to '+outlist(proc)) else begin
- d:=cdr(c); c:=car(c); { Funktionen mit 3 Argumenten }
- if p='put' then primitive:=putprop(a,b,c) else
- if p='apply' then primitive:=apply(a,b,c) else
- if p='list' then primitive:=cons(a,cons(b,cons(c,null))) else
- if p='+' then primitive:=make_number(a^.i+b^.i+c^.i) else
- if p='*' then primitive:=make_number(a^.i*b^.i*c^.i) else
- if p='set' then primitive:=set_variable_value(a,b,c) else
- if p='def' then primitive:=define_variable(a,b,c) else
- if p='strcopy' then begin new(h); h^.typ:=1; new(h^.s);
- h^.s^:=copy(a^.s^,b^.i,c^.i); primitive:=h; end else
- if p='extend-env' then primitive:=extend_environment(a,b,c) else
- error('Unknown Function '+outlist(proc));
- end; end; end;
- end;
-
- function apply;
- var ext_env:objp;
- begin
- if 3=proc^.typ then
- if dynamic then
- apply:=eval_sequence(cdr(cdr(car(cdr(proc)))),
- extend_environment(car(cdr(car(cdr(proc)))),
- args,env))
- else begin
- ext_env:= extend_environment(car(cdr(car(cdr(proc)))),
- args,
- car(cdr(cdr(proc))));
- apply:=eval_sequence(cdr(cdr(car(cdr(proc)))),ext_env);
- end else
- apply:=primitive(proc,args,env);
- end;
-
- function eval_op(op,env:objp):objp;
- begin
- if not nullp(binding_in_env(op,env)) then
- eval_op:=eval(op,env) else
- eval_op:=op;
- end;
-
- function eval_and(l,env:objp):objp;
- begin
- if nullp(l) then eval_and:=p_t else
- if nullp(eval(car(l),env)) then eval_and:=null else
- eval_and:=eval_and(cdr(l),env);
- end;
-
- function eval_or(l,env:objp):objp;
- begin
- if nullp(l) then eval_or:=null else
- if not nullp(eval(car(l),env)) then eval_or:=p_t else
- eval_or:=eval_or(cdr(l),env);
- end;
-
-
- function eval_iff(exp,env:objp):objp;
- begin
- if not nullp(eval(car(exp),env))
- then eval_iff:=eval(car(cdr(exp)),env)
- else if not nullp(cdr(cdr(exp))) then
- eval_iff:=eval(car(cdr(cdr(exp))),env)
- else eval_iff:=null
- end;
-
- function eval_let(exp,env:objp):objp;
- var eenv,vars,vals:objp;
- function carlist(x:objp):objp;
- begin
- if nullp(x) then carlist:=null else
- carlist:=cons(car(car(x)),carlist(cdr(x)));
- end;
- function cadrlist(x:objp):objp;
- begin
- if nullp(x) then cadrlist:=null else
- cadrlist:=cons(car(cdr(car(x))),cadrlist(cdr(x)));
- end;
- begin
- vars:=carlist(car(exp));
- vals:=list_of_values(cadrlist(car(exp)),env);
- eenv:=extend_environment(vars,vals,env);
- eval_let:=eval_sequence(cdr(exp),eenv);
- end;
-
- function make_delay(ex,env:objp):objp;
- function delay:objp;
- var l:objp;
- begin
- l:=cons(p_lambda,cons(null,cons(ex,null)));
- delay:=eval(cons(p_memo_proc,cons(l,null)),env);
- end;
- begin
- make_delay:=cons(p_delayed_obj,cons(delay,null));
- end;
-
- function careq(l,x:objp):boolean;
- begin
- if l^.typ=3 then careq:=equal(x,car(l)) else careq:=false;
- end;
-
- function eval;
- var op:objp;
- begin
- if self_evalp(exp) then eval:=exp else
- if careq(exp,p_quote) then eval:=car(cdr(exp)) else
- if variable(exp) then eval:=lookup_variable_value(exp,env) else
- if careq(exp,p_define) then eval:=eval_definition(exp,env) else
- if careq(exp,p_set) then eval:=eval_assignment(exp,env) else
- if careq(exp,p_begin) then eval:=eval_sequence(cdr(exp),env) else
- if careq(exp,p_let) then eval:=eval_let(cdr(exp),env) else
- if careq(exp,p_if) then eval:=eval_iff(cdr(exp),env) else
- if careq(exp,p_or) then eval:=eval_or(cdr(exp),env) else
- if careq(exp,p_and) then eval:=eval_and(cdr(exp),env) else
- if careq(exp,p_delay) then eval:=make_delay(car(cdr(exp)),env) else
- if careq(exp,p_lambda) then
- eval:=make_procedure(p_procedure,exp,env) else
- if careq(exp,p_mlambda) then
- eval:=make_procedure(p_mprocedure,exp,env) else
- if careq(exp,p_dlambda) then
- eval:=make_procedure(p_dprocedure,exp,env) else
- if careq(exp,p_cond) then eval:=eval_cond(cdr(exp),env) else
- if exp^.typ=3 then begin
- op:=eval(car(exp),env);
- if mproc(op) then
- eval:=apply(op,cdr(exp),env)
- else if dproc(op) then
- eval:=apply(op,list_of_values(dellist(cdr(exp)),env),env)
- else eval:=apply(op,list_of_values(cdr(exp),env),env)
- end else
- error('Unknown Typ of expression -- EVAL');
- end;