DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T p

⟦6779ed282⟧ TextFile

    Length: 8195 (0x2003)
    Types: TextFile
    Names: »process.c«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/General/Adventure/src/adv/process.c« 

TextFile

/*
**		    Copyright (c) 1985	Ken Wellsch
**
**     Permission is hereby granted to all users to possess, use, copy,
**     distribute, and modify the programs and files in this package
**     provided it is not for direct commercial benefit and secondly,
**     that this notice and all modification information be kept and
**     maintained in the package.
**
*/

#include "adefs.h"

#ifdef SHOWOP
	extern int CurKey ;
#endif SHOWOP

int process (key)
  int key ;
{
	int rec, calls, dos, endb ;
	int srec[MAXCALLS], sbp[MAXCALLS], sdos[MAXCALLS] ;
	int dovar[MAXDOS], dopnt[MAXDOS], domod[MAXDOS] ;
	short int instr, op[3] ;
	register int bp, i, j ;
	int n ;

	rec = key ;
	calls = 0 ;
	dos = 0 ;

	forever
	{
		bp = 0 ;
		while ( rec == ERROR || ( endb = rdcode (rec) ) == ERROR )
		{
			if ( calls <= 0 )
				return ;
			rec = srec [calls] ;
			bp = sbp [calls] ;
			dos = sdos [calls] ;
			calls-- ;
		}

#ifdef SHOWOP
		CurKey = rec ;
#endif SHOWOP
		while ( bp < endb )
		{
			instr = codebuf [bp] ;
			if ( logical (instr) )
			{
				bp = condition (bp,codebuf,endb) ;
				continue ;
			}
			bp++ ;
			n = opnum (instr) ;
			for ( i = 0 ; i < n ; i++, bp++ )
				op [i] = codebuf [bp] ;

#ifdef SHOWOP
			showop (YES,instr,op) ;
#endif SHOWOP
			switch (instr)
			{
			  case ADD:

				setval (op[0],(eval(op[0])+eval(op[1]))) ;
				continue ;

			  case ANYOF:

				bp -= 2 ;
				for ( j = 0 ; codebuf [bp] == ANYOF ; bp+=2 )
					for ( i = 0 ; i < LINELEN ; i++ )
					    if ( codebuf [bp+1] == linewd [i] )
							j++ ;
				if ( j > 0 )
					continue ;
				break ;

			  case APPORT:

				movobj ( ref (op[0]), ref (op[1]) ) ;
				continue ;

			  case AT:

				bp -= 2 ;
				i = eval (here) ;
				for ( j = 0 ; codebuf [bp] == AT ; bp += 2 )
					if ( codebuf [bp+1] == i )
						j++ ;
				if ( j > 0 )
					continue ;
				break ;

			  case BIC:

				setbit (op[0],bitval(op[0])&(~bitval(op[1]))) ;
				continue ;

			  case BIS:

				setbit (op[0],bitval(op[0])|bitval(op[1])) ;
				continue ;

			  case CALL:

				if ( (++calls) >= MAXCALLS )
				   error ("Process","call stack overflow (%d)!",
					   calls) ;
				srec [calls] = rec ;
				sbp  [calls] = bp ;
				sdos [calls] = dos ;
				rec = ref ( op[0] ) ;
				j = class ( rec ) ;
				if ( j == OBJECT )
					rec += (MAXOTEXT * MAXOBJECTS) ;
				else
					if ( j == PLACE )
						rec += ( 2 * MAXPLACES ) ;
				break ;

			  case DEFAULT:

				if ( linlen != 1 )
					continue ;
				j = 0 ;
				for ( i = OBJKEY ; indx(i) < nobj ; i++ )
				{
					if ( near (i) == NO ||
				     	(bitval(i)&bitval(op[0])) == 0 )
						continue ;
					if ( j != 0 )
					{
						j = 0 ;
						break ;
					}
					j = i ;
				}
				if ( j == 0 )
					continue ;
				setval (argwd[1],j) ;
				setbit (argwd[1],bitval(j)) ;
				linewd[1] = j ;
				setval (status,2) ;
				linlen = 2 ;
				continue ;

			  case DEPOSIT:

				setval (ref(op[0]),eval(op[1])) ;
				continue ;

			  case DIVIDE:

				setval (op[0],(eval(op[0])/eval(op[1]))) ;
				continue ;

			  case DROP:

				movobj ( ref (op[0]), eval (here) ) ;
				continue ;

			  case ELSE:

				bp = flushc (bp,codebuf,endb) ;
				continue ;

			  case EOF:

				continue ;

			  case EOI:

				i = eval ( dovar[dos] ) ;
				switch ( domod[dos] )
				{
					/* only iterate with nearby objects */
					case ITLIST:

						do
						{
							if ( indx(++i) >= nobj )
							{
								dos-- ;
								break ;
							}
						}
						while ( near (i) != YES ) ;
						if ( indx(i) >= nobj )
							continue ;
						break ;

					case ITOBJ :

						if ( indx(++i) >= nobj )
						{
							dos-- ;
							continue ;
						}
						break ;

					case ITPLACE :

						if ( indx(++i) >= nplace )
						{
							dos-- ;
							continue ;
						}
						break ;

					default :
						error ("Process",
							"unknown IT* type!") ;
						break ;

				}
				setval (dovar[dos],i) ;
				bp = dopnt[dos] ;
				continue ;

			  case EVAL:

				setval (op[0],eval(ref(op[1]))) ;
				continue ;

			  case EXEC:

				executive (op[0],op[1]) ;
				continue ;

			  case FIN:

				continue ;

			  case GET:

				j = ref ( op[0] ) ;
				movobj (j,INHAND) ;
				i = eval (j) ;
				if ( i < 0 )
					setval (j,-1-i) ;
				continue ;

			  case GOTO:

				/* must do this so "back" will work */
				i = eval (here) ;
				j = bitval (here) ;

				setval (here,ref(op[0])) ;
				setbit (here,bitval(ref(op[0]))) ;
				setval (there,i) ;
				setbit (there,j) ;
				setbit (status,(bitval(status)|MOVED)) ;
				continue ;

			  case HAVE:

				if ( where ( ref (op[0]) ) == INHAND )
					continue ;
				break ;

			  case INPUT:

				command () ;
				continue ;

			  case ITLIST:

				dos++ ;
				dovar[dos] = op[0] ;
				/* do first object and all others nearby */
				setval (op[0],OBJKEY) ;
				dopnt[dos] = bp ;
				domod[dos] = ITLIST ;
				continue ;

			  case ITOBJ:

				dos++ ;
				dovar[dos] = op[0] ;
				setval (op[0],OBJKEY) ;
				dopnt[dos] = bp ;
				domod[dos] = ITOBJ ;
				continue ;

			  case ITPLACE:

				dos++ ;
				dovar[dos] = op[0] ;
				setval (op[0],PLACEKEY) ;
				dopnt[dos] = bp ;
				domod[dos] = ITPLACE ;
				continue ;

			  case KEYWORD:

				for ( i = 0 ; i < LINELEN ; i++ )
					if ( op[0] == linewd[i] )
						break ;
				if ( i < LINELEN )
					continue ;
				break ;

			  case LDA:

				setval (op[0],op[1]) ;
				continue ;

			  case LOCATE:

				setval (op[0],where(ref(op[1]))) ;
				continue ;

			  case MOVE:

				if ( op[0] != linewd[0] )
				{
					if ( linlen < 2 )
						continue ;
					if ( op[0] != linewd[1] )
						continue ;
				}
				i = eval (here) ;
				j = bitval (here) ;
				setval (here,ref(op[1])) ;
				setbit (here,bitval(ref(op[1]))) ;
				setval (there,i) ;
				setbit (there,j) ;
				setbit (status,(bitval(status)|MOVED)) ;
				return ;

			  case MULT:

				setval (op[0],(eval(op[0])*eval(op[1]))) ;
				continue ;

			  case NAME:

				for ( i = 0 ; i < LINELEN ; i++ )
					if ( op[1] == argwd[i] )
					{
						saynam (ref(op[0]),op[1]) ;
						break ;
					}
				if ( i >= LINELEN )
					saynam (ref(op[0]),ref(op[1])) ;
				continue ;

			  case NEAR:

				i = ref ( op[0] ) ;
				if ( where (i) == INHAND || near (i) == YES )
					continue ;
				break ;

			  case PROCEED:

				break ;

			  case QUIT:

				return ;

			  case RANDOM:

				setval (op[0],rnd(eval(op[1]))) ;
				continue ;

			  case SAY:

				say ( ref (op[0]) ) ;
				continue ;

			  case SET:

				setval (op[0],eval(op[1])) ;
				continue ;

			  case SMOVE:

				if ( op[0] != linewd[0] )
				{
					if ( linlen < 2 )
						continue ;
					if ( op[0] != linewd[1] )
						continue ;
				}
				i = eval (here) ;
				j = bitval (here) ;
				setval (here,ref(op[1])) ;
				setbit (here,bitval(ref(op[1]))) ;
				setval (there,i) ;
				setbit (there,j) ;
				setbit (status,(bitval(status)|MOVED)) ;
				say (op[2]) ;
				return ;

			  case STOP:

				fini () ;

			  case SUB:

				setval (op[0],(eval(op[0])-eval(op[1]))) ;
				continue ;

			  case SVAR:

				i = eval (op[1]) ;
				i = svar (eval(op[0]),i) ;
				setval (op[1],i) ;
				continue ;

			  case VALUE:

				sayval (ref(op[0]),ref(op[1])) ;
				continue ;

			  default:

				error ("Process","unrecognized opcode %d!",
					instr) ;
				break ;

			}
			break ;
		}

		if ( instr != CALL )
			rec = nextrec (rec) ;
	}
}

int nextrec (key)
  register int key ;
{
	register int n ;

	switch (class(key))
	{
		case INITIAL:
			if ( key < REPEAT )
			{
				if ( ++key >= ninit )
					key = ERROR ;
			}
			else
			{
				if ( ++key >= nrep+REPEAT )
					key = ERROR ;
			}
			break ;

		case LABEL:
			key = ERROR ;
			break ;

		case VERB:
			key += MAXVERBS ;
			n = key - VERBKEY ;
			n /= MAXVERBS ;
			if ( n >= MAXVCODE )
				key = ERROR ;
			break ;

		case PLACE:
			key += MAXPLACES ;
			n = key - PLACEKEY ;
			n /= MAXPLACES ;
			n -= 2 ;
			if ( n >= MAXPCODE )
				key = ERROR ;
			break ;
		
		case OBJECT:
			key += MAXOBJECTS ;
			n = key - OBJKEY ;
			n /= MAXOBJECTS ;
			n -= MAXOTEXT ;
			if ( n >= MAXOCODE )
				key = ERROR ;
			break ;
		
		default:
			error ("NextRey","bad key %d!",key) ;
			break ;
	}
	return (key) ;
}

int fini ()
{
	closek (dbunit) ;
	exit (0) ;
}