block.red 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. module block; % Block statement and related operators.
  2. % Author: Anthony C. Hearn.
  3. % Copyright (c) 1993 RAND. All rights reserved.
  4. fluid '(!*blockp !*novarmsg !*rlisp88);
  5. global '(!*vars!* cursym!* nxtsym!*);
  6. flag('(novarmsg),'switch);
  7. % ***** GO statement *****
  8. symbolic procedure gostat;
  9. begin scalar var;
  10. var := if eq(scan(),'to) then scan() else cursym!*;
  11. scan();
  12. return list('go,var)
  13. end;
  14. put('go,'stat,'gostat);
  15. put('goto,'newnam,'go);
  16. % ***** Declaration Statement *****
  17. symbolic procedure decl u;
  18. begin scalar varlis,w;
  19. a: if cursym!* eq '!*semicol!* then go to c
  20. else if cursym!* eq 'local and !*reduce4 then nil
  21. else if not flagp(cursym!*,'type) then return varlis
  22. else if !*reduce4 then typerr(cursym!*,"local declaration");
  23. w := cursym!*;
  24. scan();
  25. if null !*reduce4
  26. then if cursym!* eq 'procedure then return procstat1 w
  27. else varlis
  28. := append(varlis,pairvars(remcomma xread1 nil,nil,w))
  29. else varlis := append(varlis,read_param_list nil);
  30. if not(cursym!* eq '!*semicol!*) or null u then symerr(nil,t);
  31. c: scan();
  32. go to a
  33. end;
  34. put('integer,'initvalue!*,0);
  35. symbolic procedure decstat;
  36. % Called if a declaration occurs at the top level or not first
  37. % in a block.
  38. begin scalar x,y,z;
  39. if !*blockp then symerr('block,t);
  40. x := cursym!*;
  41. y := nxtsym!*;
  42. z := decl nil;
  43. if y neq 'procedure
  44. then rerror('rlisp,7,list(x,"invalid outside block"));
  45. return z
  46. end;
  47. flag('(integer real scalar),'type);
  48. symbolic procedure blocktyperr u;
  49. % Type declaration found at wrong position.
  50. rerror('rlisp,8,list(u,"invalid except at head of block"));
  51. % ***** Block Statement *****
  52. symbolic procedure mapovercar u;
  53. begin scalar x;
  54. a: if u then progn(x := caar u . x, u := cdr u, go to a);
  55. return reversip!* x
  56. end;
  57. symbolic procedure blockstat;
  58. begin scalar hold,varlis,x,!*blockp;
  59. !*blockp := t;
  60. scan();
  61. if cursym!* memq '(nil !*rpar!*)
  62. then rerror('rlisp,9,"BEGIN invalid");
  63. varlis := decl t;
  64. a: if cursym!* eq 'end and not(nxtsym!* eq '!:) then go to b;
  65. x := xread1 nil;
  66. if eqcar(x,'end) then go to c;
  67. not(cursym!* eq 'end) and scan();
  68. if x
  69. then progn((if eqcar(x,'equal)
  70. then lprim list("top level",cadr x,"= ... in block")),
  71. hold := aconc!*(hold,x));
  72. go to a;
  73. b: comm1 'end;
  74. c: return mkblock(varlis,hold)
  75. end;
  76. symbolic procedure mkblock(u,v); 'rblock . (u . v);
  77. putd('rblock,'macro,
  78. '(lambda (u) (cons 'prog (cons (mapovercar (cadr u)) (cddr u)))));
  79. symbolic procedure symbvarlst(vars,body,mode);
  80. begin scalar x,y;
  81. if null(mode eq 'symbolic) then return nil;
  82. y := vars;
  83. a: if null y then return nil;
  84. x := if pairp car y then caar y else car y;
  85. if not fluidp x and not globalp x and not smemq(x,body)
  86. and not !*novarmsg
  87. then lprim list("local variable",x,"in procedure",
  88. fname!*,"not used");
  89. y := cdr y;
  90. go to a
  91. end;
  92. symbolic procedure formblock(u,vars,mode);
  93. progn(symbvarlst(cadr u,cddr u,mode),
  94. 'prog . append(initprogvars cadr u,
  95. formprog1(cddr u,append(cadr u,vars),mode)));
  96. symbolic procedure initprogvars u;
  97. begin scalar x,y,z;
  98. a: if null u then return(reversip!* x . reversip!* y)
  99. else if (z := get(caar u,'initvalue!*))
  100. or (z := get(cdar u,'initvalue!*))
  101. then y := mksetq(caar u,z) . y;
  102. x := caar u . x;
  103. u := cdr u;
  104. go to a
  105. end;
  106. symbolic procedure formprog(u,vars,mode);
  107. 'prog . cadr u . formprog1(cddr u,pairvars(cadr u,vars,mode),mode);
  108. symbolic procedure formprog1(u,vars,mode);
  109. if null u then nil
  110. else if null car u then formprog1(cdr u,vars,mode)
  111. % remove spurious NILs, probably generated by FOR statements.
  112. else if atom car u then car u . formprog1(cdr u,vars,mode)
  113. else if idp caar u and flagp(caar u,'modefn)
  114. then if !*rlisp88 and null(caar u eq 'symbolic)
  115. then typerr("algebraic expression","Rlisp88 form")
  116. else formc(cadar u,vars,caar u) . formprog1(cdr u,vars,mode)
  117. else formc(car u,vars,mode) . formprog1(cdr u,vars,mode);
  118. put('rblock,'formfn,'formblock);
  119. put('prog,'formfn,'formprog);
  120. put('begin,'stat,'blockstat);
  121. % ***** Return Statement *****
  122. symbolic procedure retstat;
  123. if not !*blockp then symerr(nil,t)
  124. else begin scalar !*blockp; % To prevent RETURN within a RETURN.
  125. return list('return,
  126. if flagp(scan(),'delim) then nil else xread1 t)
  127. end;
  128. put('return,'stat,'retstat);
  129. endmodule;
  130. end;