123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- /* $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];
- }
|