stack.cpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // _______
  2. // | | <- stack
  3. // | |
  4. // |_______|
  5. // | | <- stack + tos
  6. // | |
  7. // | |
  8. // |_______|
  9. // | | <- frame
  10. // |_______|
  11. // <- stack + TOS
  12. //
  13. // The stack grows from low memory towards high memory. This is so that
  14. // multiple expressions can be pushed on the stack and then accessed as an
  15. // array.
  16. //
  17. // The frame area holds local variables and grows from high memory towards
  18. // low memory. The frame area makes local variables visible to the garbage
  19. // collector.
  20. #include "stdafx.h"
  21. #include "defs.h"
  22. U **frame, **stack;
  23. int tos;
  24. void
  25. push(U *p)
  26. {
  27. if (stack + tos >= frame)
  28. stop("stack overflow");
  29. stack[tos++] = p;
  30. }
  31. U *
  32. pop()
  33. {
  34. if (tos == 0)
  35. stop("stack underflow");
  36. return stack[--tos];
  37. }
  38. void
  39. push_frame(int n)
  40. {
  41. int i;
  42. frame -= n;
  43. if (frame < stack + tos)
  44. stop("frame overflow, circular reference?");
  45. for (i = 0; i < n; i++)
  46. frame[i] = symbol(NIL);
  47. }
  48. void
  49. pop_frame(int n)
  50. {
  51. frame += n;
  52. if (frame > stack + TOS)
  53. stop("frame underflow");
  54. }
  55. void
  56. save(void)
  57. {
  58. frame -= 10;
  59. if (frame < stack + tos)
  60. stop("frame overflow, circular reference?");
  61. frame[0] = p0;
  62. frame[1] = p1;
  63. frame[2] = p2;
  64. frame[3] = p3;
  65. frame[4] = p4;
  66. frame[5] = p5;
  67. frame[6] = p6;
  68. frame[7] = p7;
  69. frame[8] = p8;
  70. frame[9] = p9;
  71. }
  72. void
  73. restore(void)
  74. {
  75. if (frame > stack + TOS - 10)
  76. stop("frame underflow");
  77. p0 = frame[0];
  78. p1 = frame[1];
  79. p2 = frame[2];
  80. p3 = frame[3];
  81. p4 = frame[4];
  82. p5 = frame[5];
  83. p6 = frame[6];
  84. p7 = frame[7];
  85. p8 = frame[8];
  86. p9 = frame[9];
  87. frame += 10;
  88. }
  89. // Local U * is OK here because there is no functional path to the garbage collector.
  90. void
  91. swap(void)
  92. {
  93. U *p, *q;
  94. p = pop();
  95. q = pop();
  96. push(p);
  97. push(q);
  98. }
  99. // Local U * is OK here because there is no functional path to the garbage collector.
  100. void
  101. dupl(void)
  102. {
  103. U *p;
  104. p = pop();
  105. push(p);
  106. push(p);
  107. }