138 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* $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)
 | |
| 
 | |
| 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 ))
 | |
| 
 | |
| void
 | |
| 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];
 | |
| }
 |