loops88.red 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. module loops88; % Rlisp88 looping forms other than the FOR statement.
  2. % Author: Anthony C. Hearn.
  3. fluid '(!*blockp loopdelimslist!*);
  4. global '(cursym!* repeatkeywords!* whilekeywords!*);
  5. % ***** REPEAT STATEMENT *****
  6. repeatkeywords!* := '(finally initially returns until with);
  7. symbolic procedure repeatstat88;
  8. begin scalar body,!*blockp,x,y,z;
  9. loopdelimslist!* := repeatkeywords!* . loopdelimslist!*;
  10. flag(repeatkeywords!*,'delim);
  11. body := erroreval '(xread t);
  12. if not (cursym!* memq repeatkeywords!*) then symerr('repeat,t);
  13. a: x := cursym!*;
  14. y := erroreval if x eq 'with then '(xread 'lambda)
  15. else '(xread t);
  16. z := (x . y) . z;
  17. if cursym!* memq repeatkeywords!* then go to a;
  18. remflag(car loopdelimslist!*,'delim);
  19. loopdelimslist!* := cdr loopdelimslist!*;
  20. if loopdelimslist!* then flag(car loopdelimslist!*,'delim);
  21. return 'repeat . body . reversip z
  22. end;
  23. symbolic macro procedure repeat88 u;
  24. begin scalar body,lab,xwith;
  25. body := cadr u; u := cddr u;
  26. xwith := atsoc('with,u);
  27. return sublis(pair('(!$locals !$do !$rets !$inits !$fins !$bool
  28. !$label),
  29. list(if xwith then cdr xwith else nil,
  30. body,
  31. x!-car x!-cdr atsoc('returns,u),
  32. mkfn(x!-cdr atsoc('initially,u),'progn),
  33. mkfn(x!-cdr atsoc('finally,u),'progn),
  34. x!-car x!-cdr atsoc('until,u),
  35. gensym())),
  36. '(prog !$locals
  37. !$inits
  38. !$label !$do
  39. (cond (!$bool !$fins (return !$rets)))
  40. (go !$label)))
  41. end;
  42. symbolic procedure remcomma!* u; if null u then nil else remcomma cdr u;
  43. symbolic procedure x!-car u; if atom u then u else car u;
  44. symbolic procedure x!-cdr u; if null u then nil else list cdr u;
  45. % flag('(repeat),'nochange);
  46. symbolic procedure formrepeat88(u,vars,mode);
  47. begin scalar y,z;
  48. for each x in cddr u do
  49. if car x eq 'with
  50. then <<y := remcomma cdr x;
  51. vars := nconc(for each j in y collect j . 'scalar,
  52. vars);
  53. z := (car x . y) . z>>
  54. % else if car x eq 'until
  55. % then z := (car x . formbool(cdr x,vars,mode)) . z
  56. else z := (car x . formc(cdr x,vars,mode)) . z;
  57. return 'repeat . formc(cadr u,vars,mode) . reversip z
  58. end;
  59. % ***** WHILE STATEMENT *****
  60. whilekeywords!* := '(collect do finally initially returns with);
  61. symbolic procedure whilstat88;
  62. begin scalar !*blockp,bool1,x,y,z;
  63. loopdelimslist!* := whilekeywords!* . loopdelimslist!*;
  64. flag(whilekeywords!*,'delim);
  65. bool1 := erroreval '(xread t);
  66. if not (cursym!* memq whilekeywords!*) then symerr('while,t);
  67. a: x := cursym!*;
  68. y := erroreval if x eq 'with then '(xread 'lambda)
  69. else '(xread t);
  70. z := (x . y) . z;
  71. if cursym!* memq whilekeywords!* then go to a;
  72. remflag(car loopdelimslist!*,'delim);
  73. loopdelimslist!* := cdr loopdelimslist!*;
  74. if loopdelimslist!* then flag(car loopdelimslist!*,'delim);
  75. return 'while . bool1 . reversip z
  76. end;
  77. symbolic macro procedure while88 u;
  78. begin scalar body,bool,lab,rets,vars;
  79. bool := cadr u; u := cddr u;
  80. rets := x!-car x!-cdr atsoc('returns,u);
  81. vars := x!-car x!-cdr atsoc('with,u);
  82. if body := atsoc('collect,u)
  83. then <<vars := gensym() . vars;
  84. body := list('setq,
  85. car vars,
  86. list('cons,cdr body,car vars));
  87. if rets then rederr "While loop value conflict";
  88. rets := list('reversip,car vars)>>
  89. else if body := atsoc('do,u) then body := cdr body
  90. else rederr "Missing body in WHILE statement";
  91. return sublis(pair('(!$locals !$do !$rets !$inits !$fins !$bool
  92. !$label),
  93. list(vars,
  94. body,
  95. rets,
  96. mkfn(x!-cdr atsoc('initially,u),'progn),
  97. mkfn(x!-cdr atsoc('finally,u),'progn),
  98. bool,
  99. gensym())),
  100. '(prog !$locals
  101. !$inits
  102. !$label
  103. (cond ((not !$bool) !$fins (return !$rets)))
  104. !$do
  105. (go !$label)))
  106. end;
  107. % flag('(while),'nochange);
  108. symbolic procedure formwhile88(u,vars,mode);
  109. begin scalar y,z;
  110. for each x in cddr u do
  111. if car x eq 'with
  112. then <<y := remcomma cdr x;
  113. vars := nconc(for each j in y collect j . 'scalar,
  114. vars);
  115. z := (car x . y) . z>>
  116. else z := (car x . formc(cdr x,vars,mode)) . z;
  117. return 'while . formc(cadr u,vars,mode) . reversip z
  118. end;
  119. endmodule;
  120. end;