cs_stack.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /* $Id$ */
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. */
  6. /*
  7. * S T A C K M O D U L E
  8. */
  9. #include "../share/types.h"
  10. #include "../share/global.h"
  11. #include "../share/debug.h"
  12. #include "../share/aux.h"
  13. #include "cs.h"
  14. #include "cs_aux.h"
  15. #define STACK_DEPTH 250
  16. STATIC struct token Stack[STACK_DEPTH];
  17. STATIC token_p free_token;
  18. #define Delete_top() {--free_token; }
  19. #define Empty_stack() {free_token = &Stack[0]; }
  20. #define Stack_empty() (free_token == &Stack[0])
  21. #define Top (free_token - 1)
  22. Push(tkp)
  23. token_p tkp;
  24. {
  25. if (tkp->tk_size == UNKNOWN_SIZE) {
  26. Empty_stack(); /* The contents of the Stack is useless. */
  27. } else {
  28. assert(free_token < &Stack[STACK_DEPTH]);
  29. free_token->tk_vn = tkp->tk_vn;
  30. free_token->tk_size = tkp->tk_size;
  31. (free_token++)->tk_lfirst = tkp->tk_lfirst;
  32. }
  33. }
  34. #define WORD_MULTIPLE(n) ((n / ws) * ws + ( n % ws ? ws : 0 ))
  35. Pop(tkp, size)
  36. token_p tkp;
  37. offset size;
  38. {
  39. /* Pop a token with given size from the valuenumber stack into tkp. */
  40. /* First simple case. */
  41. if (size != UNKNOWN_SIZE && !Stack_empty() && size == Top->tk_size) {
  42. tkp->tk_vn = Top->tk_vn;
  43. tkp->tk_size = size;
  44. tkp->tk_lfirst = Top->tk_lfirst;
  45. Delete_top();
  46. return;
  47. }
  48. /* Now we're in trouble: we must pop something that is not there!
  49. * We just put a dummy into tkp and pop tokens until we've
  50. * popped size bytes.
  51. */
  52. /* Create dummy. */
  53. tkp->tk_vn = newvalnum();
  54. tkp->tk_lfirst = (line_p) 0;
  55. /* Now fiddle with the Stack. */
  56. if (Stack_empty()) return;
  57. if (size == UNKNOWN_SIZE) {
  58. Empty_stack();
  59. return;
  60. }
  61. if (size > Top->tk_size) {
  62. while (!Stack_empty() && size >= Top->tk_size) {
  63. size -= Top->tk_size;
  64. Delete_top();
  65. }
  66. }
  67. /* Now Stack_empty OR size < Top->tk_size. */
  68. if (!Stack_empty()) {
  69. if (Top->tk_size - size < ws) {
  70. Delete_top();
  71. } else {
  72. Top->tk_vn = newvalnum();
  73. Top->tk_size -= WORD_MULTIPLE(size);
  74. }
  75. }
  76. }
  77. Dup(lnp)
  78. line_p lnp;
  79. {
  80. /* Duplicate top bytes on the Stack. */
  81. register token_p bottom = Top;
  82. register token_p oldtop = Top;
  83. register offset nbytes = off_set(lnp);
  84. struct token dummy;
  85. /* Find the bottom of the bytes to be duplicated.
  86. * It is possible that we cannot find it.
  87. */
  88. while (bottom > &Stack[0] && bottom->tk_size < nbytes) {
  89. nbytes -= bottom->tk_size;
  90. bottom--;
  91. }
  92. if (bottom < &Stack[0]) {
  93. /* There was nothing. */
  94. dummy.tk_vn = newvalnum();
  95. dummy.tk_size = nbytes;
  96. dummy.tk_lfirst = lnp;
  97. Push(&dummy);
  98. } else {
  99. if (bottom->tk_size < nbytes) {
  100. /* Not enough, bottom == &Stack[0]. */
  101. dummy.tk_vn = newvalnum();
  102. dummy.tk_size = nbytes - bottom->tk_size;
  103. dummy.tk_lfirst = lnp;
  104. Push(&dummy);
  105. } else if (bottom->tk_size > nbytes) {
  106. /* Not integral # tokens. */
  107. dummy.tk_vn = newvalnum();
  108. dummy.tk_size = nbytes;
  109. dummy.tk_lfirst = lnp;
  110. Push(&dummy);
  111. bottom++;
  112. }
  113. /* Bottom points to lowest token to be dupped. */
  114. while (bottom <= oldtop) {
  115. Push(bottom++);
  116. Top->tk_lfirst = lnp;
  117. }
  118. }
  119. }
  120. clr_stack()
  121. {
  122. free_token = &Stack[0];
  123. }