/* $Id$ */ /* * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ /* * 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 250 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) void Push(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 )) void Pop(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); } } } void Dup(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; } } } void clr_stack() { free_token = &Stack[0]; }