home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Guide
/
c-cplusplus-interactive-guide.iso
/
c_ref
/
csource4
/
251_01
/
advcom.c
< prev
next >
Wrap
Text File
|
1987-10-29
|
15KB
|
657 lines
/* advcom.c - a compiler for adventure games */
/*
Copyright (c) 1986, by David Michael Betz
All rights reserved
*/
#include "advcom.h"
#include "advavl.h"
#include "advdbs.h"
/* symbol tables */
SYMBOL *symbols;
ARGUMENT *arguments;
ARGUMENT *temporaries;
/* adventure id information */
char aname[19];
int aversion;
/* word table */
int wtable[WMAX+1],wcnt;
/* object table */
int otable[OMAX+1],ocnt;
/* action table */
int atable[AMAX+1],acnt;
/* constant, variable and property symbol counts */
int ccnt,vcnt,pcnt;
/* data and code space */
char *data,*code;
int dptr,cptr;
/* buffer for building an object */
int objbuf[OSIZE];
int nprops;
/* global variables */
char ifile[FMAX]; /* input file name */
char ofile[FMAX]; /* output file name */
FILE *ifp; /* input file pointer */
unsigned int msgoff; /* message section offset */
TREE *words; /* word tree */
int curwrd; /* current word number */
int curobj; /* current object */
int curact; /* current action */
int def_flag; /* default action flag value */
int def_mask; /* default action mask value */
/* header information variables */
int h_init; /* initialization code */
int h_update; /* update code */
int h_before; /* before handler code */
int h_after; /* after handler code */
int h_error; /* error handling code */
/* external routines */
extern char *malloc();
extern char *calloc();
extern TREE *tnew();
/* external variables */
extern int errcount; /* error count */
extern int t_value; /* token value */
extern char t_token[]; /* token string */
extern char *t_names[]; /* token names */
extern long ad_foff; /* data file offset */
/* forward declarations */
SYMBOL *sfind();
SYMBOL *senter();
char *save();
/* main - the main routine */
main(argc,argv)
int argc; char *argv[];
{
int tkn,obj,i;
/* initialize */
#ifdef MAC
macinit(ifile,ofile);
#else
printf("ADVCOM v1.2 - Copyright (c) 1986, by David Betz\n");
#endif
wcnt = ocnt = acnt = ccnt = vcnt = pcnt = msgoff = 0;
symbols = NULL; arguments = temporaries = NULL;
h_init = h_update = h_before = h_after = h_error = NIL;
def_flag = def_mask = 0;
aname[0] = 0;
sinit();
/* setup the code and data space */
if ((data = calloc(1,DMAX)) == 0)
fail("insufficient memory");
if ((code = calloc(1,CMAX)) == 0)
fail("insufficient memory");
dptr = cptr = 1; /* make sure nothing has a zero offset */
/* get the file name */
#ifndef MAC
if (argc < 2)
fail("usage: advcom <file> [ <ofile> ]");
strcpy(ifile,argv[1]); strcat(ifile,".adv");
strcpy(ofile,(argc < 3 ? argv[1] : argv[2])); strcat(ofile,".dat");
#endif
/* open the input file */
if ((ifp = fopen(ifile,"r")) == NULL)
fail("can't open input file");
/* create and initialize the output file */
ad_create(ofile);
for (i = 0; i++ < 512; ad_putc('\0'))
;
/* create the word tree */
words = tnew();
/* enter builtin constants */
center("t",-1);
center("nil",0);
/* enter the builtin variables */
venter("$actor");
venter("$action");
venter("$dobject");
venter("$ndobjects");
venter("$iobject");
venter("$ocount");
/* enter the preposition "to" */
add_word("to",WT_PREPOSITION);
/* process statements until end of file */
while ((tkn = token()) == T_OPEN) {
frequire(T_IDENTIFIER);
/* identification statement */
if (match("adventure"))
do_adventure();
/* vocabulary statements */
else if (match("adjective"))
do_word(WT_ADJECTIVE);
else if (match("preposition"))
do_word(WT_PREPOSITION);
else if (match("conjunction"))
do_word(WT_CONJUNCTION);
else if (match("article"))
do_word(WT_ARTICLE);
else if (match("synonym"))
do_synonym();
/* constant, variable, function and default definition statements */
else if (match("define"))
do_define();
else if (match("variable"))
do_variable();
else if (match("default"))
do_default();
/* property definition statement */
else if (match("property"))
do_defproperty();
/* handle the init, before and after code statements */
else if (match("init"))
h_init = do_code(t_token);
else if (match("update"))
h_update = do_code(t_token);
else if (match("before"))
h_before = do_code(t_token);
else if (match("after"))
h_after = do_code(t_token);
else if (match("error"))
h_error = do_code(t_token);
/* action definition statement */
else if (match("action"))
do_action();
/* object definition statements */
else if (match("object"))
do_object(t_token,NIL);
/* object instance definition statements */
else if (obj = ofind(t_token))
do_object(t_token,obj);
/* error, unknown statement */
else
error("Unknown statement type");
}
require(tkn,T_EOF);
/* close the input file */
fclose(ifp);
/* output the data structures */
output();
/* close the output file */
ad_close();
}
/* getvalue - get a value */
int getvalue()
{
SYMBOL *sym;
switch (token()) {
case T_IDENTIFIER: if (sym = sfind(t_token))
return (sym->s_value);
return (oenter(t_token));
case T_NUMBER: return (t_value);
case T_STRING: return (t_value);
default: error("Expecting identifier, number or string");
return (0);
}
}
/* dalloc - allocate data space */
int dalloc(size)
int size;
{
if ((dptr += size) > DMAX)
fail("out of data space");
return (dptr - size);
}
/* add_word - add a word to the dictionary */
int add_word(str,type)
char *str; int type;
{
if ((curwrd = tfind(words,str)) == NIL) {
if (wcnt < WMAX) {
curwrd = ++wcnt;
wtable[curwrd] = type;
tenter(words,str);
}
else {
error("too many words");
curwrd = 0;
}
}
else if (wtable[curwrd] == WT_UNKNOWN)
wtable[curwrd] = type;
else if (type != WT_UNKNOWN && type != wtable[curwrd])
error("Ambiguous word type");
return (curwrd);
}
/* add_synonym - add a synonym to a word */
int add_synonym(str,wrd)
char *str; int wrd;
{
curwrd = wrd;
return (tenter(words,str));
}
/* getword - get a word from an object field */
int getword(off)
int off;
{
return ((data[off] & 0xFF) | (data[off+1] << 8));
}
/* putword - put a word into an object field */
putword(off,dat)
int off,dat;
{
data[off] = dat;
data[off+1] = dat >> 8;
}
/* getbyte - get a byte from an object field */
int getbyte(off)
int off;
{
return (data[off]);
}
/* putbyte - put a byte into an object field */
putbyte(off,dat)
int off,dat;
{
data[off] = dat;
}
/* output - output the binary data structures */
output()
{
int woff,wsize; /* word table offset and size */
int ooff,osize; /* object table offset and size */
int aoff,asize; /* action table offset and size */
int toff,tsize; /* word type table offset and size */
int voff,vsize; /* variable table offset and size */
int soff,ssize; /* save area offset and size */
int dsize; /* data size without dictionary */
int dbase,cbase,size,mblk,dblk,i;
/* make sure the adventure id information is present */
if (aname[0] == 0) {
xerror("no adventure identification information");
strcpy(aname,"ADVENTURE");
aversion = 0;
}
/* pad the remainder of this message block */
while (msgoff & 0x007F)
{ ad_putc('\0'); ad_putc('\0'); ad_putc('\0'); ad_putc('\0'); msgoff++; }
/* save the size of the data area before the dictionary */
dsize = dptr;
/* insert the vocabulary into the data array */
woutput(words->tr_root);
/* compute table offsets */
woff = 0; wsize = tentries(words) * 2 + 2;
toff = woff + wsize; tsize = wcnt;
ooff = toff + tsize; osize = ocnt * 2 + 2;
aoff = ooff + osize; asize = acnt * 2 + 2;
voff = aoff + asize; vsize = vcnt * 2 + 2;
dbase = voff + vsize;
cbase =