prog-and-friends.red 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. %
  2. % PROG-AND-FRIENDS.RED - PROG, GO, and RETURN
  3. %
  4. % Author: Eric Benson
  5. % Symbolic Computation Group
  6. % Computer Science Dept.
  7. % University of Utah
  8. % Date: 20 August 1981
  9. % Copyright (c) 1981 University of Utah
  10. %
  11. % <PSL.KERNEL>PROG-AND-FRIENDS.RED.2, 11-Oct-82 17:55:57, Edit by BENSON
  12. % Changed CATCH/THROW to *CATCH/*THROW
  13. % Error numbers:
  14. % 3000 - Unknown label
  15. % 3100 - outside the scope of a PROG
  16. % +1 in GO
  17. % +2 in RETURN
  18. fluid '(ProgJumpTable!* % A-List of labels and expressions
  19. ProgBody!*); % Tail of the current PROG
  20. fexpr procedure Prog ProgBody!*; %. Program feature function
  21. begin scalar ProgJumpTable!*, N, Result;
  22. if not PairP ProgBody!* then return NIL;
  23. N := 0;
  24. for each X in car ProgBody!* do
  25. << PBind1 X;
  26. N := N + 1 >>;
  27. ProgBody!* := cdr ProgBody!*;
  28. for each X on ProgBody!* do
  29. if IDP car X then
  30. ProgJumpTable!* := X . ProgJumpTable!*;
  31. while << while PairP ProgBody!* and IDP car ProgBody!* do
  32. ProgBody!* := cdr ProgBody!*; % skip over labels
  33. PairP ProgBody!* >> do % eval the expression
  34. << Result := !*Catch('!$Prog!$, Eval car ProgBody!*);
  35. if not ThrowSignal!* then
  36. << Result := NIL;
  37. ProgBody!* := cdr ProgBody!* >> >>;
  38. UnBindN N;
  39. return Result;
  40. end;
  41. lisp fexpr procedure GO U; %. Goto label within PROG
  42. begin scalar NewProgBody;
  43. return if ProgBody!* then
  44. << NewProgBody := Atsoc(car U, ProgJumpTable!*);
  45. if null NewProgBody then
  46. ContinuableError(3001,
  47. BldMsg(
  48. "%r is not a label within the current scope", car U),
  49. 'GO . U)
  50. else
  51. << ProgBody!* := NewProgBody;
  52. !*Throw('!$Prog!$, NIL) >> >>
  53. else ContinuableError(3101,
  54. "GO attempted outside the scope of a PROG",
  55. 'GO . U);
  56. end;
  57. lisp procedure Return U; %. Return value from PROG
  58. if ProgBody!* then
  59. << ProgBody!* := NIL;
  60. !*Throw('!$Prog!$, U) >>
  61. else ContError(3102, "RETURN attempted outside the scope of a PROG",
  62. Return U);
  63. END;