cs_stack.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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. void Push(token_p tkp)
  23. {
  24. if (tkp->tk_size == UNKNOWN_SIZE) {
  25. Empty_stack(); /* The contents of the Stack is useless. */
  26. } else {
  27. assert(free_token < &Stack[STACK_DEPTH]);
  28. free_token->tk_vn = tkp->tk_vn;
  29. free_token->tk_size = tkp->tk_size;
  30. (free_token++)->tk_lfirst = tkp->tk_lfirst;
  31. }
  32. }
  33. #define WORD_MULTIPLE(n) ((n / ws) * ws + ( n % ws ? ws : 0 ))
  34. void Pop(token_p tkp, offset size)
  35. {
  36. /* Pop a token with given size from the valuenumber stack into tkp. */
  37. /* First simple case. */
  38. if (size != UNKNOWN_SIZE && !Stack_empty() && size == Top->tk_size) {
  39. tkp->tk_vn = Top->tk_vn;
  40. tkp->tk_size = size;
  41. tkp->tk_lfirst = Top->tk_lfirst;
  42. Delete_top();
  43. return;
  44. }
  45. /* Now we're in trouble: we must pop something that is not there!
  46. * We just put a dummy into tkp and pop tokens until we've
  47. * popped size bytes.
  48. */
  49. /* Create dummy. */
  50. tkp->tk_vn = newvalnum();
  51. tkp->tk_lfirst = (line_p) 0;
  52. /* Now fiddle with the Stack. */
  53. if (Stack_empty()) return;
  54. if (size == UNKNOWN_SIZE) {
  55. Empty_stack();
  56. return;
  57. }
  58. if (size > Top->tk_size) {
  59. while (!Stack_empty() && size >= Top->tk_size) {
  60. size -= Top->tk_size;
  61. Delete_top();
  62. }
  63. }
  64. /* Now Stack_empty OR size < Top->tk_size. */
  65. if (!Stack_empty()) {
  66. if (Top->tk_size - size < ws) {
  67. Delete_top();
  68. } else {
  69. Top->tk_vn = newvalnum();
  70. Top->tk_size -= WORD_MULTIPLE(size);
  71. }
  72. }
  73. }
  74. void Dup(line_p lnp)
  75. {
  76. /* Duplicate top bytes on the Stack. */
  77. register token_p bottom = Top;
  78. register token_p oldtop = Top;
  79. register offset nbytes = off_set(lnp);
  80. struct token dummy;
  81. /* Find the bottom of the bytes to be duplicated.
  82. * It is possible that we cannot find it.
  83. */
  84. while (bottom > &Stack[0] && bottom->tk_size < nbytes) {
  85. nbytes -= bottom->tk_size;
  86. bottom--;
  87. }
  88. if (bottom < &Stack[0]) {
  89. /* There was nothing. */
  90. dummy.tk_vn = newvalnum();
  91. dummy.tk_size = nbytes;
  92. dummy.tk_lfirst = lnp;
  93. Push(&dummy);
  94. } else {
  95. if (bottom->tk_size < nbytes) {
  96. /* Not enough, bottom == &Stack[0]. */
  97. dummy.tk_vn = newvalnum();
  98. dummy.tk_size = nbytes - bottom->tk_size;
  99. dummy.tk_lfirst = lnp;
  100. Push(&dummy);
  101. } else if (bottom->tk_size > nbytes) {
  102. /* Not integral # tokens. */
  103. dummy.tk_vn = newvalnum();
  104. dummy.tk_size = nbytes;
  105. dummy.tk_lfirst = lnp;
  106. Push(&dummy);
  107. bottom++;
  108. }
  109. /* Bottom points to lowest token to be dupped. */
  110. while (bottom <= oldtop) {
  111. Push(bottom++);
  112. Top->tk_lfirst = lnp;
  113. }
  114. }
  115. }
  116. void clr_stack()
  117. {
  118. free_token = &Stack[0];
  119. }