|
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 a
Length: 13701 (0x3585) Types: TextFile Names: »advfcn.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/General/Advsys/advfcn.c«
/* 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(prop,flags,value); } /* addprop - add a property to the current object's property list */ addprop(prop,flags,value) int prop,flags,value; { if (nprops >= OPMAX) { printf("too many properties for this object\n"); return; } objbuf[O_PROPERTIES/2 + nprops*2] = prop|flags; objbuf[O_PROPERTIES/2 + nprops*2 + 1] = value; objbuf[O_NPROPERTIES/2] = ++nprops; } /* do_code - compile code for an expression */ int do_code(type) char *type; { int adr,tkn; if (type) printf("[ compiling %s code ]\n",type); adr = putcbyte(OP_PUSH); while ((tkn = token()) != T_CLOSE) { stoken(tkn); do_expr(); } putcbyte(OP_RETURN); return (adr); } /* do_action - handle <ACTION ... > statement */ do_action() { int tkn,act; /* get the action name */ frequire(T_IDENTIFIER); printf("[ action: %s ]\n",t_token); /* create a new action */ act = aenter(t_token); curact = atable[act] = dalloc(A_SIZE); putword(curact+A_VERBS,NIL); putword(curact+A_PREPOSITIONS,NIL); putbyte(curact+A_FLAG,def_flag); putbyte(curact+A_MASK,def_mask); putword(curact+A_CODE,NIL); /* process statements until end of file */ while ((tkn = token()) == T_OPEN) { frequire(T_IDENTIFIER); if (match("actor")) do_flag(A_ACTOR); else if (match("verb")) do_verb(); else if (match("direct-object")) do_flag(A_DOBJECT); else if (match("preposition")) do_preposition(); else if (match("indirect-object")) do_flag(A_IOBJECT); else if (match("code")) putword(curact+A_CODE,do_code(NULL)); else error("Unknown action definition statement type"); } require(tkn,T_CLOSE); } /* do_flag - handle ACTOR, DIRECT-OBJECT, and INDIRECT-OBJECT statements */ do_flag(flag) int flag; { int tkn; if ((tkn = token()) == T_IDENTIFIER) { if (match("required")) { putbyte(curact+A_FLAG,getbyte(curact+A_FLAG) | flag); putbyte(curact+A_MASK,getbyte(curact+A_MASK) & ~flag); } else if (match("forbidden")) { putbyte(curact+A_FLAG,getbyte(curact+A_FLAG) & ~flag); putbyte(curact+A_MASK,getbyte(curact+A_MASK) & ~flag); } else if (match("optional")) putbyte(curact+A_MASK,getbyte(curact+A_MASK) | flag); else error("Expecting: REQUIRED, FORBIDDEN or OPTIONAL"); tkn = token(); } else { putbyte(curact+A_FLAG,getbyte(curact+A_FLAG) | flag); putbyte(curact+A_MASK,getbyte(curact+A_MASK) & ~flag); } require(tkn,T_CLOSE); } /* do_verb - handle the <VERB ... > statement */ do_verb() { int tkn,new,lst; while ((tkn = token()) == T_IDENTIFIER || tkn == T_OPEN) { new = dalloc(L_SIZE); putword(new+L_NEXT,getword(curact+A_VERBS)); putword(curact+A_VERBS,new); lst = dalloc(L_SIZE); putword(lst+L_NEXT,NIL); putword(new+L_DATA,lst); if (tkn == T_IDENTIFIER) putword(lst+L_DATA,add_word(t_token,WT_VERB)); else { if ((tkn = token()) == T_IDENTIFIER) putword(lst+L_DATA,add_word(t_token,WT_VERB)); else error("Expecting verb"); while ((tkn = token()) == T_IDENTIFIER) { new = dalloc(L_SIZE); putword(new+L_DATA,add_word(t_token,WT_UNKNOWN)); putword(new+L_NEXT,NIL); putword(lst+L_NEXT,new); lst = new; } require(tkn,T_CLOSE); } } require(tkn,T_CLOSE); } /* do_preposition - handle the <PREPOSITION ... > statement */ do_preposition() { int tkn,new; while ((tkn = token()) == T_IDENTIFIER) { new = dalloc(L_SIZE); putword(new+L_DATA,add_word(t_token,WT_PREPOSITION)); putword(new+L_NEXT,getword(curact+A_PREPOSITIONS)); putword(curact+A_PREPOSITIONS,new); } require(tkn,T_CLOSE); } /* do_function - handle <DEFINE (FUN ...) ... > statement */ do_function() { int tkn,act,tcnt; /* get the function name */ frequire(T_IDENTIFIER); printf("[ function: %s ]\n",t_token); /* create a new action */ act = aenter(t_token); /* initialize the action */ curact = atable[act] = dalloc(A_SIZE); putword(curact+A_VERBS,NIL); putword(curact+A_PREPOSITIONS,NIL); arguments = temporaries = NULL; tcnt = 0; /* 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; } /* addargument - add a formal argument */ addargument(list,name) ARGUMENT **list; char *name; { ARGUMENT *arg; if ((arg = (ARGUMENT *)malloc(sizeof(ARGUMENT))) == NULL) fail("out of memory"); arg->arg_name = save(name); arg->arg_next = *list; *list = arg; } /* freelist - free a list of arguments or temporaries */ freelist(arg) ARGUMENT *arg; { ARGUMENT *nxt; while (arg) { nxt = arg->arg_next; free(arg->arg_name); free(arg); arg = nxt; } } /* findarg - find an argument offset */ int findarg(name) char *name; { ARGUMENT *arg; int n; for (n = 0, arg = arguments; arg; n++, arg = arg->arg_next) if (strcmp(name,arg->arg_name) == 0) return (n); return (-1); } /* findtmp - find a temporary variable offset */ int findtmp(name) char *name; { ARGUMENT *tmp; int n; for (n = 0, tmp = temporaries; tmp; n++, tmp = tmp->arg_next) if (strcmp(name,tmp->arg_name) == 0) return (n); return (-1); }