|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T p
Length: 8195 (0x2003)
Types: TextFile
Names: »process.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/Adventure/src/adv/process.c«
/*
** 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) ;
}