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