block.red 4.6 KB

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