home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Guide
/
c-cplusplus-interactive-guide.iso
/
c_ref
/
csource4
/
251_01
/
advfcn.c
< prev
next >
Wrap
Text File
|
1987-10-29
|
14KB
|
585 lines
/* advfcn.c - functions for the adventure compiler */
/*
Copyright (c) 1986, by David Michael Betz
All rights reserved
*/
#include "advcom.h"
#include "advdbs.h"
/* external variables */
extern char aname[]; /* adventure name */
extern int aversion; /* adventure version number */
extern int cptr; /* code space pointer */
extern int objbuf[]; /* object staging buffer */
extern int nprops; /* number of properties in current object */
extern int t_value; /* token value */
extern char t_token[]; /* token string */
extern char *t_names[]; /* token names */
extern int otable[]; /* object table */
extern int curobj; /* current object number */
extern int curact; /* current action offset */
extern int atable[],acnt; /* action table and count */
extern ARGUMENT *arguments; /* function argument list */
extern ARGUMENT *temporaries; /* function temporary variable list */
extern int def_flag; /* default action flag value */
extern int def_mask; /* default action mask value */
/* external routines */
extern char *malloc();
extern char *save();
/* do_adventure - handle the <ADVENTURE name version-number> statement */
do_adventure()
{
/* get the adventure name */
frequire(T_IDENTIFIER);
strncpy(aname,t_token,18);
aname[18] = 0;
/* get the adventure version number */
frequire(T_NUMBER);
aversion = t_value;
/* check for the closing paren */
frequire(T_CLOSE);
}
/* do_word - enter words of a particular type */
do_word(type)
{
int tkn;
while ((tkn = token()) == T_IDENTIFIER)
add_word(t_token,type);
require(tkn,T_CLOSE);
}
/* do_synonym - handle the <SYNONYMS ... > statement */
do_synonym()
{
int tkn,wrd;
frequire(T_IDENTIFIER);
wrd = add_word(t_token,WT_UNKNOWN);
while ((tkn = token()) == T_IDENTIFIER)
add_synonym(t_token,wrd);
require(tkn,T_CLOSE);
}
/* do_define - handle the <DEFINE ... > statement */
do_define()
{
char name[TKNSIZE+1];
int tkn;
if ((tkn = token()) == T_OPEN)
return (do_function());
stoken(tkn);
while ((tkn = token()) == T_IDENTIFIER) {
strcpy(name,t_token);
center(name,getvalue());
}
require(tkn,T_CLOSE);
}
/* do_variable - handle the <VARIABLE ... > statement */
do_variable()
{
int tkn;
while ((tkn = token()) == T_IDENTIFIER)
venter(t_token);
require(tkn,T_CLOSE);
}
/* do_defproperty - handle the <PROPERTY ... > statement */
do_defproperty()
{
int tkn;
while ((tkn = token()) == T_IDENTIFIER)
penter(t_token);
require(tkn,T_CLOSE);
}
/* do_default - handle the <DEFAULT ... > statement */
do_default()
{
int tkn;
/* process statements until end of file */
while ((tkn = token()) == T_OPEN) {
frequire(T_IDENTIFIER);
if (match("actor"))
do_dflag(A_ACTOR);
else if (match("direct-object"))
do_dflag(A_DOBJECT);
else if (match("indirect-object"))
do_dflag(A_IOBJECT);
else
error("Unknown default definition statement type");
}
require(tkn,T_CLOSE);
}
/* do_dflag - handle ACTOR, DIRECT-OBJECT, and INDIRECT-OBJECT statements */
do_dflag(flag)
int flag;
{
int tkn;
if ((tkn = token()) == T_IDENTIFIER) {
if (match("required")) {
def_flag |= flag;
def_mask &= ~flag;
}
else if (match("forbidden")) {
def_flag &= ~flag;
def_mask &= ~flag;
}
else if (match("optional"))
def_mask |= flag;
else
error("Expecting: REQUIRED, FORBIDDEN or OPTIONAL");
tkn = token();
}
else {
def_flag |= flag;
def_mask &= ~flag;
}
require(tkn,T_CLOSE);
}
/* do_object - handle object (LOCATION,OBJECT,ACTOR) definitions */
int do_object(cname,class)
char *cname; int class;
{
int tkn,obj,obase,osize,i,p;
printf("[ %s: ",cname);
frequire(T_IDENTIFIER);
printf("%s ]\n",t_token);
obj = curobj = oenter(t_token);
/* initialize the object */
objbuf[O_CLASS/2] = class;
objbuf[O_NOUNS/2] = NIL;
objbuf[O_ADJECTIVES/2] = NIL;
objbuf[O_NPROPERTIES/2] = nprops = 0;
/* copy the property list of the class object */
if (class) {
obase = otable[class];
osize = getword(obase+O_NPROPERTIES);
for (i = p = 0; i < osize; i++, p += 4)
if ((getword(obase+O_PROPERTIES+p) & P_CLASS) == 0)
addprop(getword(obase+O_PROPERTIES+p),0,
getword(obase+O_PROPERTIES+p+2));
}
/* process statements until end of file */
while ((tkn = token()) == T_OPEN) {
frequire(T_IDENTIFIER);
if (match("noun"))
do_noun();
else if (match("adjective"))
do_adjective();
else if (match("property"))
do_property(0);
else if (match("class-property"))
do_property(P_CLASS);
else if (match("method"))
do_method();
else
error("Unknown object definition statement type");
}
require(tkn,T_CLOSE);
/* copy the object to data memory */
osize = O_SIZE/2 + nprops*2;
obase = dalloc(osize*2);
for (i = p = 0; i < osize; i++, p += 2)
putword(obase+p,objbuf[i]);
otable[obj] = obase;
curobj = NIL;
/* return the object number */
return (obj);
}
/* do_noun - handle the <NOUN ... > statement */
do_noun()
{
int tkn,new;
while ((tkn = token()) == T_IDENTIFIER) {
new = dalloc(L_SIZE);
putword(new+L_DATA,add_word(t_token,WT_NOUN));
putword(new+L_NEXT,objbuf[O_NOUNS/2]);
objbuf[O_NOUNS/2] = new;
}
require(tkn,T_CLOSE);
}
/* do_adjective - handle the <ADJECTIVE ... > statement */
do_adjective()
{
int tkn,new;
while ((tkn = token()) == T_IDENTIFIER) {
new = dalloc(L_SIZE);
putword(new+L_DATA,add_word(t_token,WT_ADJECTIVE));
putword(new+L_NEXT,objbuf[O_ADJECTIVES/2]);
objbuf[O_ADJECTIVES/2] = new;
}
require(tkn,T_CLOSE);
}
/* do_property - handle the <PROPERTY ... > statement */
do_property(flags)
int flags;
{
int tkn,name,value;
while ((tkn = token()) == T_IDENTIFIER || tkn == T_NUMBER) {
name = (tkn == T_IDENTIFIER ? penter(t_token) : t_value);
value = getvalue();
setprop(name,flags,value);
}
require(tkn,T_CLOSE);
}
/* do_method - handle <METHOD (FUN ...) ... > statement */
do_method()
{
int tkn,name,tcnt;
/* get the property name */
frequire(T_OPEN);
frequire(T_IDENTIFIER);
printf("[ method: %s ]\n",t_token);
/* create a new property */
name = penter(t_token);
/* allocate a new (anonymous) action */
if (acnt < AMAX)
++acnt;
else
error("too many actions");
/* store the action as the value of the property */
setprop(name,P_CLASS,acnt);
/* initialize the action */
curact = atable[acnt] = dalloc(A_SIZE);
putword(curact+A_VERBS,NIL);
putword(curact+A_PREPOSITIONS,NIL);
arguments = temporaries = NULL;
tcnt = 0;
/* enter the "self" argument */
addargument(&arguments,"self");
addargument(&arguments,"(dummy)");
/* get the argument list */
while ((tkn = token()) != T_CLOSE) {
require(tkn,T_IDENTIFIER);
if (match("&aux"))
break;
addargument(&arguments,t_token);
}
/* check for temporary variable definitions */
if (tkn == T_IDENTIFIER)
while ((tkn = token()) != T_CLOSE) {
require(tkn,T_IDENTIFIER);
addargument(&temporaries,t_token);
tcnt++;
}
/* store the code address */
putword(curact+A_CODE,cptr);
/* allocate space for temporaries */
if (temporaries) {
putcbyte(OP_TSPACE);
putcbyte(tcnt);
}
/* compile the code */
do_code(NULL);
/* free the argument and temporary variable symbol tables */
freelist(arguments);
freelist(temporaries);
arguments = temporaries = NULL;
}
/* setprop - set the value of a property */
setprop(prop,flags,value)
int prop,flags,value;
{
int i;
/* look for the property */
for (i = 0; i < nprops; i++)
if ((objbuf[O_PROPERTIES/2 + i*2] & ~P_CLASS) == prop) {
objbuf[O_PROPERTIES/2 + i*2 + 1] = value;
return;
}
addprop(pr