123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- module block; % Block statement and related operators.
- % Author: Anthony C. Hearn.
- % Copyright (c) 1993 RAND. All rights reserved.
- fluid '(!*blockp !*novarmsg !*rlisp88);
- global '(!*vars!* cursym!* nxtsym!*);
- flag('(novarmsg),'switch);
- % ***** GO statement *****
- symbolic procedure gostat;
- begin scalar var;
- var := if eq(scan(),'to) then scan() else cursym!*;
- scan();
- return list('go,var)
- end;
- put('go,'stat,'gostat);
- put('goto,'newnam,'go);
- % ***** Declaration Statement *****
- symbolic procedure decl u;
- begin scalar varlis,w;
- a: if cursym!* eq '!*semicol!* then go to c
- else if cursym!* eq 'local and !*reduce4 then nil
- else if not flagp(cursym!*,'type) then return varlis
- else if !*reduce4 then typerr(cursym!*,"local declaration");
- w := cursym!*;
- scan();
- if null !*reduce4
- then if cursym!* eq 'procedure then return procstat1 w
- else varlis
- := append(varlis,pairvars(remcomma xread1 nil,nil,w))
- else varlis := append(varlis,read_param_list nil);
- if not(cursym!* eq '!*semicol!*) or null u then symerr(nil,t);
- c: scan();
- go to a
- end;
- put('integer,'initvalue!*,0);
- symbolic procedure decstat;
- % Called if a declaration occurs at the top level or not first
- % in a block.
- begin scalar x,y,z;
- if !*blockp then symerr('block,t);
- x := cursym!*;
- y := nxtsym!*;
- z := decl nil;
- if y neq 'procedure
- then rerror('rlisp,7,list(x,"invalid outside block"));
- return z
- end;
- flag('(integer real scalar),'type);
- symbolic procedure blocktyperr u;
- % Type declaration found at wrong position.
- rerror('rlisp,8,list(u,"invalid except at head of block"));
- % ***** Block Statement *****
- symbolic procedure mapovercar u;
- begin scalar x;
- a: if u then progn(x := caar u . x, u := cdr u, go to a);
- return reversip!* x
- end;
- symbolic procedure blockstat;
- begin scalar hold,varlis,x,!*blockp;
- !*blockp := t;
- scan();
- if cursym!* memq '(nil !*rpar!*)
- then rerror('rlisp,9,"BEGIN invalid");
- varlis := decl t;
- a: if cursym!* eq 'end and not(nxtsym!* eq '!:) then go to b;
- x := xread1 nil;
- if eqcar(x,'end) then go to c;
- not(cursym!* eq 'end) and scan();
- if x
- then progn((if eqcar(x,'equal)
- then lprim list("top level",cadr x,"= ... in block")),
- hold := aconc!*(hold,x));
- go to a;
- b: comm1 'end;
- c: return mkblock(varlis,hold)
- end;
- symbolic procedure mkblock(u,v); 'rblock . (u . v);
- putd('rblock,'macro,
- '(lambda (u) (cons 'prog (cons (mapovercar (cadr u)) (cddr u)))));
- symbolic procedure symbvarlst(vars,body,mode);
- begin scalar x,y;
- if null(mode eq 'symbolic) then return nil;
- y := vars;
- a: if null y then return nil;
- x := if pairp car y then caar y else car y;
- if not fluidp x and not globalp x and not smemq(x,body)
- and not !*novarmsg
- then lprim list("local variable",x,"in procedure",
- fname!*,"not used");
- y := cdr y;
- go to a
- end;
- symbolic procedure formblock(u,vars,mode);
- progn(symbvarlst(cadr u,cddr u,mode),
- 'prog . append(initprogvars cadr u,
- formprog1(cddr u,append(cadr u,vars),mode)));
- symbolic procedure initprogvars u;
- begin scalar x,y,z;
- a: if null u then return(reversip!* x . reversip!* y)
- else if (z := get(caar u,'initvalue!*))
- or (z := get(cdar u,'initvalue!*))
- then y := mksetq(caar u,z) . y;
- x := caar u . x;
- u := cdr u;
- go to a
- end;
- symbolic procedure formprog(u,vars,mode);
- 'prog . cadr u . formprog1(cddr u,pairvars(cadr u,vars,mode),mode);
- symbolic procedure formprog1(u,vars,mode);
- if null u then nil
- else if null car u then formprog1(cdr u,vars,mode)
- % remove spurious NILs, probably generated by FOR statements.
- else if atom car u then car u . formprog1(cdr u,vars,mode)
- else if idp caar u and flagp(caar u,'modefn)
- then if !*rlisp88 and null(caar u eq 'symbolic)
- then typerr("algebraic expression","Rlisp88 form")
- else formc(cadar u,vars,caar u) . formprog1(cdr u,vars,mode)
- else formc(car u,vars,mode) . formprog1(cdr u,vars,mode);
- put('rblock,'formfn,'formblock);
- put('prog,'formfn,'formprog);
- put('begin,'stat,'blockstat);
- % ***** Return Statement *****
- symbolic procedure retstat;
- if not !*blockp then symerr(nil,t)
- else begin scalar !*blockp; % To prevent RETURN within a RETURN.
- return list('return,
- if flagp(scan(),'delim) then nil else xread1 t)
- end;
- put('return,'stat,'retstat);
- endmodule;
- end;
|