Initial revision
This commit is contained in:
132
util/ego/cs/cs_stack.c
Normal file
132
util/ego/cs/cs_stack.c
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* S T A C K M O D U L E
|
||||
*/
|
||||
#include "../share/types.h"
|
||||
#include "../share/global.h"
|
||||
#include "../share/debug.h"
|
||||
#include "../share/aux.h"
|
||||
#include "cs.h"
|
||||
#include "cs_aux.h"
|
||||
|
||||
#define STACK_DEPTH 50
|
||||
|
||||
STATIC struct token Stack[STACK_DEPTH];
|
||||
STATIC token_p free_token;
|
||||
|
||||
#define Delete_top() {--free_token; }
|
||||
#define Empty_stack() {free_token = &Stack[0]; }
|
||||
#define Stack_empty() (free_token == &Stack[0])
|
||||
#define Top (free_token - 1)
|
||||
|
||||
Push(tkp)
|
||||
token_p tkp;
|
||||
{
|
||||
if (tkp->tk_size == UNKNOWN_SIZE) {
|
||||
Empty_stack(); /* The contents of the Stack is useless. */
|
||||
} else {
|
||||
assert(free_token < &Stack[STACK_DEPTH]);
|
||||
|
||||
free_token->tk_vn = tkp->tk_vn;
|
||||
free_token->tk_size = tkp->tk_size;
|
||||
free_token++->tk_lfirst = tkp->tk_lfirst;
|
||||
}
|
||||
}
|
||||
|
||||
#define WORD_MULTIPLE(n) ((n / ws) * ws + ( n % ws ? ws : 0 ))
|
||||
|
||||
Pop(tkp, size)
|
||||
token_p tkp;
|
||||
offset size;
|
||||
{
|
||||
/* Pop a token with given size from the valuenumber stack into tkp. */
|
||||
|
||||
/* First simple case. */
|
||||
if (size != UNKNOWN_SIZE && !Stack_empty() && size == Top->tk_size) {
|
||||
tkp->tk_vn = Top->tk_vn;
|
||||
tkp->tk_size = size;
|
||||
tkp->tk_lfirst = Top->tk_lfirst;
|
||||
Delete_top();
|
||||
return;
|
||||
}
|
||||
/* Now we're in trouble: we must pop something that is not there!
|
||||
* We just put a dummy into tkp and pop tokens until we've
|
||||
* popped size bytes.
|
||||
*/
|
||||
/* Create dummy. */
|
||||
tkp->tk_vn = newvalnum();
|
||||
tkp->tk_lfirst = (line_p) 0;
|
||||
|
||||
/* Now fiddle with the Stack. */
|
||||
if (Stack_empty()) return;
|
||||
if (size == UNKNOWN_SIZE) {
|
||||
Empty_stack();
|
||||
return;
|
||||
}
|
||||
if (size > Top->tk_size) {
|
||||
while (!Stack_empty() && size >= Top->tk_size) {
|
||||
size -= Top->tk_size;
|
||||
Delete_top();
|
||||
}
|
||||
}
|
||||
/* Now Stack_empty OR size < Top->tk_size. */
|
||||
if (!Stack_empty()) {
|
||||
if (Top->tk_size - size < ws) {
|
||||
Delete_top();
|
||||
} else {
|
||||
Top->tk_vn = newvalnum();
|
||||
Top->tk_size -= WORD_MULTIPLE(size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dup(lnp)
|
||||
line_p lnp;
|
||||
{
|
||||
/* Duplicate top bytes on the Stack. */
|
||||
|
||||
register token_p bottom = Top;
|
||||
register token_p oldtop = Top;
|
||||
register offset nbytes = off_set(lnp);
|
||||
struct token dummy;
|
||||
|
||||
/* Find the bottom of the bytes to be duplicated.
|
||||
* It is possible that we cannot find it.
|
||||
*/
|
||||
while (bottom > &Stack[0] && bottom->tk_size < nbytes) {
|
||||
nbytes -= bottom->tk_size;
|
||||
bottom--;
|
||||
}
|
||||
|
||||
if (bottom < &Stack[0]) {
|
||||
/* There was nothing. */
|
||||
dummy.tk_vn = newvalnum();
|
||||
dummy.tk_size = nbytes;
|
||||
dummy.tk_lfirst = lnp;
|
||||
Push(&dummy);
|
||||
} else {
|
||||
if (bottom->tk_size < nbytes) {
|
||||
/* Not enough, bottom == &Stack[0]. */
|
||||
dummy.tk_vn = newvalnum();
|
||||
dummy.tk_size = nbytes - bottom->tk_size;
|
||||
dummy.tk_lfirst = lnp;
|
||||
Push(&dummy);
|
||||
} else if (bottom->tk_size > nbytes) {
|
||||
/* Not integral # tokens. */
|
||||
dummy.tk_vn = newvalnum();
|
||||
dummy.tk_size = nbytes;
|
||||
dummy.tk_lfirst = lnp;
|
||||
Push(&dummy);
|
||||
bottom++;
|
||||
}
|
||||
/* Bottom points to lowest token to be dupped. */
|
||||
while (bottom <= oldtop) {
|
||||
Push(bottom++);
|
||||
Top->tk_lfirst = lnp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clr_stack()
|
||||
{
|
||||
free_token = &Stack[0];
|
||||
}
|
||||
Reference in New Issue
Block a user