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 >
Text File  |  1987-10-29  |  14KB  |  585 lines

  1. /* advfcn.c - functions for the adventure compiler */
  2. /*
  3.     Copyright (c) 1986, by David Michael Betz
  4.     All rights reserved
  5. */
  6.  
  7. #include "advcom.h"
  8. #include "advdbs.h"
  9.  
  10. /* external variables */
  11. extern char aname[];        /* adventure name */
  12. extern int aversion;        /* adventure version number */
  13. extern int cptr;        /* code space pointer */
  14. extern int objbuf[];        /* object staging buffer */
  15. extern int nprops;        /* number of properties in current object */
  16. extern int t_value;        /* token value */
  17. extern char t_token[];        /* token string */
  18. extern char *t_names[];        /* token names */
  19. extern int otable[];        /* object table */
  20. extern int curobj;        /* current object number */
  21. extern int curact;        /* current action offset */
  22. extern int atable[],acnt;    /* action table and count */
  23. extern ARGUMENT *arguments;    /* function argument list */
  24. extern ARGUMENT *temporaries;    /* function temporary variable list */
  25. extern int def_flag;        /* default action flag value */
  26. extern int def_mask;        /* default action mask value */
  27.  
  28. /* external routines */
  29. extern char *malloc();
  30. extern char *save();
  31.  
  32. /* do_adventure - handle the <ADVENTURE name version-number> statement */
  33. do_adventure()
  34. {
  35.     /* get the adventure name */
  36.     frequire(T_IDENTIFIER);
  37.     strncpy(aname,t_token,18);
  38.     aname[18] = 0;
  39.  
  40.     /* get the adventure version number */
  41.     frequire(T_NUMBER);
  42.     aversion = t_value;
  43.  
  44.     /* check for the closing paren */
  45.     frequire(T_CLOSE);
  46. }
  47.  
  48. /* do_word - enter words of a particular type */
  49. do_word(type)
  50. {
  51.     int tkn;
  52.  
  53.     while ((tkn = token()) == T_IDENTIFIER)
  54.     add_word(t_token,type);
  55.     require(tkn,T_CLOSE);
  56. }
  57.  
  58. /* do_synonym - handle the <SYNONYMS ... > statement */
  59. do_synonym()
  60. {
  61.     int tkn,wrd;
  62.  
  63.     frequire(T_IDENTIFIER);
  64.     wrd = add_word(t_token,WT_UNKNOWN);
  65.     while ((tkn = token()) == T_IDENTIFIER)
  66.     add_synonym(t_token,wrd);
  67.     require(tkn,T_CLOSE);
  68. }
  69.  
  70. /* do_define - handle the <DEFINE ... > statement */
  71. do_define()
  72. {
  73.     char name[TKNSIZE+1];
  74.     int tkn;
  75.  
  76.     if ((tkn = token()) == T_OPEN)
  77.     return (do_function());
  78.     stoken(tkn);
  79.  
  80.     while ((tkn = token()) == T_IDENTIFIER) {
  81.     strcpy(name,t_token);
  82.     center(name,getvalue());
  83.     }
  84.     require(tkn,T_CLOSE);
  85. }
  86.  
  87. /* do_variable - handle the <VARIABLE ... > statement */
  88. do_variable()
  89. {
  90.     int tkn;
  91.  
  92.     while ((tkn = token()) == T_IDENTIFIER)
  93.     venter(t_token);
  94.     require(tkn,T_CLOSE);
  95. }
  96.  
  97. /* do_defproperty - handle the <PROPERTY ... > statement */
  98. do_defproperty()
  99. {
  100.     int tkn;
  101.  
  102.     while ((tkn = token()) == T_IDENTIFIER)
  103.     penter(t_token);
  104.     require(tkn,T_CLOSE);
  105. }
  106.  
  107. /* do_default - handle the <DEFAULT ... > statement */
  108. do_default()
  109. {
  110.     int tkn;
  111.  
  112.     /* process statements until end of file */
  113.     while ((tkn = token()) == T_OPEN) {
  114.     frequire(T_IDENTIFIER);
  115.     if (match("actor"))
  116.         do_dflag(A_ACTOR);
  117.     else if (match("direct-object"))
  118.         do_dflag(A_DOBJECT);
  119.     else if (match("indirect-object"))
  120.         do_dflag(A_IOBJECT);
  121.     else
  122.         error("Unknown default definition statement type");
  123.     }
  124.     require(tkn,T_CLOSE);
  125. }
  126.  
  127. /* do_dflag - handle ACTOR, DIRECT-OBJECT, and INDIRECT-OBJECT statements */
  128. do_dflag(flag)
  129.   int flag;
  130. {
  131.     int tkn;
  132.  
  133.     if ((tkn = token()) == T_IDENTIFIER) {
  134.     if (match("required")) {
  135.         def_flag |= flag;
  136.         def_mask &= ~flag;
  137.     }
  138.     else if (match("forbidden")) {
  139.         def_flag &= ~flag;
  140.         def_mask &= ~flag;
  141.     }
  142.     else if (match("optional"))
  143.         def_mask |= flag;
  144.     else
  145.         error("Expecting: REQUIRED, FORBIDDEN or OPTIONAL");
  146.     tkn = token();
  147.     }
  148.     else {
  149.     def_flag |= flag;
  150.     def_mask &= ~flag;
  151.     }
  152.     require(tkn,T_CLOSE);
  153. }
  154.  
  155. /* do_object - handle object (LOCATION,OBJECT,ACTOR) definitions */
  156. int do_object(cname,class)
  157.   char *cname; int class;
  158. {
  159.     int tkn,obj,obase,osize,i,p;
  160.  
  161. printf("[ %s: ",cname);
  162.     frequire(T_IDENTIFIER);
  163. printf("%s ]\n",t_token);
  164.     obj = curobj = oenter(t_token);
  165.  
  166.     /* initialize the object */
  167.     objbuf[O_CLASS/2] = class;
  168.     objbuf[O_NOUNS/2] = NIL;
  169.     objbuf[O_ADJECTIVES/2] = NIL;
  170.     objbuf[O_NPROPERTIES/2] = nprops = 0;
  171.  
  172.     /* copy the property list of the class object */
  173.     if (class) {
  174.     obase = otable[class];
  175.     osize = getword(obase+O_NPROPERTIES);
  176.     for (i = p = 0; i < osize; i++, p += 4)
  177.         if ((getword(obase+O_PROPERTIES+p) & P_CLASS) == 0)
  178.         addprop(getword(obase+O_PROPERTIES+p),0,
  179.                         getword(obase+O_PROPERTIES+p+2));
  180.     }
  181.  
  182.     /* process statements until end of file */
  183.     while ((tkn = token()) == T_OPEN) {
  184.     frequire(T_IDENTIFIER);
  185.     if (match("noun"))
  186.         do_noun();
  187.     else if (match("adjective"))
  188.         do_adjective();
  189.     else if (match("property"))
  190.         do_property(0);
  191.     else if (match("class-property"))
  192.         do_property(P_CLASS);
  193.     else if (match("method"))
  194.         do_method();
  195.     else
  196.         error("Unknown object definition statement type");
  197.     }
  198.     require(tkn,T_CLOSE);
  199.  
  200.     /* copy the object to data memory */
  201.     osize = O_SIZE/2 + nprops*2;
  202.     obase = dalloc(osize*2);
  203.     for (i = p = 0; i < osize; i++, p += 2)
  204.     putword(obase+p,objbuf[i]);
  205.     otable[obj] = obase;
  206.     curobj = NIL;
  207.  
  208.     /* return the object number */
  209.     return (obj);
  210. }
  211.  
  212. /* do_noun - handle the <NOUN ... > statement */
  213. do_noun()
  214. {
  215.     int tkn,new;
  216.  
  217.     while ((tkn = token()) == T_IDENTIFIER) {
  218.     new = dalloc(L_SIZE);
  219.     putword(new+L_DATA,add_word(t_token,WT_NOUN));
  220.     putword(new+L_NEXT,objbuf[O_NOUNS/2]);
  221.     objbuf[O_NOUNS/2] = new;
  222.     }
  223.     require(tkn,T_CLOSE);
  224. }
  225.  
  226. /* do_adjective - handle the <ADJECTIVE ... > statement */
  227. do_adjective()
  228. {
  229.     int tkn,new;
  230.  
  231.     while ((tkn = token()) == T_IDENTIFIER) {
  232.     new = dalloc(L_SIZE);
  233.     putword(new+L_DATA,add_word(t_token,WT_ADJECTIVE));
  234.     putword(new+L_NEXT,objbuf[O_ADJECTIVES/2]);
  235.     objbuf[O_ADJECTIVES/2] = new;
  236.     }
  237.     require(tkn,T_CLOSE);
  238. }
  239.  
  240. /* do_property - handle the <PROPERTY ... > statement */
  241. do_property(flags)
  242.   int flags;
  243. {
  244.     int tkn,name,value;
  245.  
  246.     while ((tkn = token()) == T_IDENTIFIER || tkn == T_NUMBER) {
  247.     name = (tkn == T_IDENTIFIER ? penter(t_token) : t_value);
  248.     value = getvalue();
  249.     setprop(name,flags,value);
  250.     }
  251.     require(tkn,T_CLOSE);
  252. }
  253.  
  254. /* do_method - handle <METHOD (FUN ...) ... > statement */
  255. do_method()
  256. {
  257.     int tkn,name,tcnt;
  258.  
  259.     /* get the property name */
  260.     frequire(T_OPEN);
  261.     frequire(T_IDENTIFIER);
  262. printf("[ method: %s ]\n",t_token);
  263.  
  264.     /* create a new property */
  265.     name = penter(t_token);
  266.  
  267.     /* allocate a new (anonymous) action */
  268.     if (acnt < AMAX)
  269.     ++acnt;
  270.     else
  271.     error("too many actions");
  272.  
  273.     /* store the action as the value of the property */
  274.     setprop(name,P_CLASS,acnt);
  275.  
  276.     /* initialize the action */
  277.     curact = atable[acnt] = dalloc(A_SIZE);
  278.     putword(curact+A_VERBS,NIL);
  279.     putword(curact+A_PREPOSITIONS,NIL);
  280.     arguments = temporaries = NULL;
  281.     tcnt = 0;
  282.  
  283.     /* enter the "self" argument */
  284.     addargument(&arguments,"self");
  285.     addargument(&arguments,"(dummy)");
  286.  
  287.     /* get the argument list */
  288.     while ((tkn = token()) != T_CLOSE) {
  289.     require(tkn,T_IDENTIFIER);
  290.     if (match("&aux"))
  291.         break;
  292.     addargument(&arguments,t_token);
  293.     }
  294.     
  295.     /* check for temporary variable definitions */
  296.     if (tkn == T_IDENTIFIER)
  297.     while ((tkn = token()) != T_CLOSE) {
  298.         require(tkn,T_IDENTIFIER);
  299.         addargument(&temporaries,t_token);
  300.         tcnt++;
  301.     }
  302.  
  303.     /* store the code address */
  304.     putword(curact+A_CODE,cptr);
  305.  
  306.     /* allocate space for temporaries */
  307.     if (temporaries) {
  308.     putcbyte(OP_TSPACE);
  309.     putcbyte(tcnt);
  310.     }
  311.  
  312.     /* compile the code */
  313.     do_code(NULL);
  314.  
  315.     /* free the argument and temporary variable symbol tables */
  316.     freelist(arguments);
  317.     freelist(temporaries);
  318.     arguments = temporaries = NULL;
  319. }
  320.  
  321. /* setprop - set the value of a property */
  322. setprop(prop,flags,value)
  323.   int prop,flags,value;
  324. {
  325.     int i;
  326.  
  327.     /* look for the property */
  328.     for (i = 0; i < nprops; i++)
  329.     if ((objbuf[O_PROPERTIES/2 + i*2] & ~P_CLASS) == prop) {
  330.         objbuf[O_PROPERTIES/2 + i*2 + 1] = value;
  331.         return;
  332.     }
  333.     addprop(pr