home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / TOP / USR / SRC / world.t.Z / world.t / parser.c < prev    next >
C/C++ Source or Header  |  1989-03-04  |  18KB  |  871 lines

  1. #include "parame.inc"
  2. #include "variab.h"
  3. #include "arrays.h"
  4. #include "vocab.inc"
  5. #include "verbtb.inc"
  6. #define abs(A) ((A < 0) ? -A : A)
  7.  
  8. /* World C Version 1.00 copyright 1987 J.D.McDonald 
  9.    Use as you like for non-commercial purposes, but please
  10.    leave this note, and document any changes you make as yours */
  11.  
  12. /* No apologies for all the goto's. If you can get rid of them, well,
  13.    I guess some persons are just naturally masochists */
  14.  
  15. static int      typlst[4] = {VRBMIN, ADJMIN, NUNMIN, PRPMIN};
  16. static int      index[5], indx;
  17.  
  18. scan()
  19. /*
  20.  * this function scans the input line for gross syntax errors it also expands
  21.  * special direction commands such as "ne" into their full form. it also
  22.  * works on adverbs, removes such expressions as "ask frog," etc. finally it
  23.  * puts the word numbers and types in the wrdnum and wrdtyp arrays the input
  24.  * is inbuf ,the output is wrdnum,wrdtyp,actor,adverb 
  25.  *
  26.  */
  27. {
  28.     int             result, offlg, askx, lptr0, wptr, i, lxx, errno;
  29.  
  30.     result = 0;
  31.     offlg = 0;
  32.     chgact = 0;
  33.     askx = 0;
  34.  
  35. lab5:
  36.     adverb = 0;
  37.     for (i = 0; i < 30; i++) {
  38.     wrdnum[i] = 0;
  39.     wrdtyp[i] = 0;
  40.     }
  41.     /*
  42.      * wordtyp is -1 for a period,-2 comma 1 for adverb,2 verb,3 adjective,4
  43.      * noun,5 preposition numbers are type 4,and wrdnum=number+10000 
  44.      */
  45.  
  46.     wptr = 0;
  47. lab10:
  48.     lptr0 = lptr;
  49.     wscan();
  50.     /*
  51.      * on return from wscan punct contains: 0 for a word 1 for a period 2 for
  52.      * a comma 3 for a number 4 if an illegal character 5 if a number follows
  53.      * a letter directly 6 if a letter follows a number directly 
  54.      */
  55.  
  56.     if (punct == 1)
  57.     return (result);
  58.     else if (punct == 4)
  59.     goto lab9000;
  60.     else if (punct == 2)
  61.     goto lab9010;
  62.     else if (punct == 3)
  63.     goto lab9019;
  64.     else if (punct == 5)
  65.     goto lab9020;
  66.     else if (punct == 6)
  67.     goto lab9140;
  68.     else;
  69.     /* it's a real word, so find out what it is */
  70.  
  71.     find(VOCMAX);
  72.  
  73.     /* discard buzzword  */
  74.  
  75.     if (indx > 0 && indx <= BUZMAX)
  76.     goto lab10;
  77.     if (indx == 0)
  78.     goto lab9040;
  79.  
  80.     if ((indx >= NORTH && indx <= NORTHW) || indx == UP
  81.     || indx == DOWN) {
  82.     /* yes,it's a special word  */
  83.  
  84.     lptr0 = lptr;
  85.     wscan();
  86.     /* check if it's all that's on the line  */
  87.  
  88.     if (punct != 1)
  89.         goto lab9030;
  90.     /* expand a direction word into full form */
  91.  
  92.     wrdtyp[1] = 4;
  93.     wrdnum[1] = indx;
  94.     wrdnum[0] = GO;
  95.     wrdtyp[0] = 2;
  96.     wrdtyp[2] = -1;
  97.     goto lab9999;
  98.     }
  99.     if (index[0] != 0) {
  100.     if (adverb != 0)
  101.         goto lab9070;
  102.     /* adverbs are removed from the wrdtyp list and handled separately */
  103.  
  104.     adverb = index[0];
  105.     if (adverb != WHERE && adverb != WHAT)
  106.         goto lab10;
  107.     if (actor == 1 || askx != ASK)
  108.         goto lab9130;
  109.     goto lab10;
  110.     }
  111.     if (index[1] == 0)
  112.     goto lab9050;
  113.     wrdtyp[wptr] = 2;
  114.     wrdnum[wptr] = index[1];
  115.     /*
  116.      * we've found the verb check for legal question  
  117.      */
  118.  
  119.     if ((adverb == WHAT || adverb == WHERE) - (wrdnum[0] == IS))
  120.     goto lab9130;
  121.     if (wrdnum[0] == YELL) {
  122.     /* the player is told to use "ask" or "tell" */
  123.  
  124. lab131:
  125.     wscan();
  126.     if (punct != 1)
  127.         goto lab131;
  128.     wrdtyp[0] = 2;
  129.     wrdnum[0] = YELL;
  130.     result = 1;
  131.     return (result);
  132.     }
  133.     if (wrdnum[0] < SHIT)
  134.     goto lab200;
  135.     /*
  136.      * special handling for words which take no objects or modifiers they
  137.      * should be alone on a line. they are verbs >= shit  
  138.      */
  139.  
  140.     lptr0 = lptr;
  141.     wscan();
  142.     {
  143.     if (punct == 1)
  144.         goto lab9998;
  145.     else if (punct == 5)
  146.         goto lab9120;
  147.     else
  148.         goto lab9150;
  149.     }
  150.     /* inner loop for all words after verb  */
  151.  
  152. lab200:
  153.     wptr += 1;
  154.     if (wptr > 27)
  155.     goto lab9180;
  156.  
  157. lab201:
  158.     lptr0 = lptr;
  159.     wscan();
  160.     if (punct != 0)
  161.     goto lab210;
  162.     find(BUZMAX);
  163.     /* special code for "noun1 of noun2" construct  */
  164.  
  165.     if (indx == 4 && wrdtyp[wptr - 1] == 4)
  166.     offlg = 1;
  167.     if (indx != 0)
  168.     goto lab201;
  169.     goto lab215;
  170. lab210:
  171.     if (punct == 4)
  172.     goto lab9000;
  173.     if (punct == 5)
  174.     goto lab9020;
  175.     if (punct == 6)
  176.     goto lab9140;
  177.     if (punct != 2)
  178.     goto lab215;
  179.     if (wrdtyp[wptr - 1] != 4)
  180.     goto lab9010;
  181.     wrdtyp[wptr] = -2;
  182.     goto lab200;
  183.  
  184. lab215:
  185.     if (wrdtyp[wptr - 1] != 2 || (wrdnum[wptr - 1] != ASK
  186.                   && wrdnum[wptr - 1] != TELL))
  187.     goto lab220;
  188.     if (punct == 3)
  189.     goto lab9019;
  190.     if (punct != 0)
  191.     goto lab9010;
  192.     if (actor != 1)
  193.     goto lab9100;
  194.     /*
  195.      * this code is to set up addressing a second "person" the phrases "ask
  196.      * frog" or "tell frog" etc are discarded and the variable "actor" tells
  197.      * us who is addressed  
  198.      */
  199.  
  200.     askx = wrdnum[wptr - 1];
  201.     find(VOCMAX);
  202.     if ((index[3] != 0) &&
  203.     (index[3] < ROBOT || index[3] > FERRET))
  204.     goto lab9090;
  205.     if (index[3] == 0)
  206.     goto lab9160;
  207.     actor = index[3];
  208.     lptr0 = lptr;
  209.     chgact = 1;
  210.     wscan();
  211.     if (punct != 2)
  212.     goto lab9110;
  213.     goto lab5;
  214.     /* code for numbers inputted in a statement */
  215.  
  216. lab220:
  217.     if (punct != 3)
  218.     goto lab240;
  219.     wrdtyp[wptr] = 4;
  220.     wrdnum[wptr] = three[0] + 10000;
  221.     goto lab200;
  222.     /* all regular words go here */
  223.  
  224. lab240:
  225.  
  226.     if (punct != 1)
  227.     goto lab250;
  228.     wrdtyp[wptr] = -1;
  229.     goto lab9999;
  230. lab250:
  231.     find(VOCMAX);
  232.     if (indx == 0)
  233.     goto lab9040;
  234.     /* special code for "of" handler */
  235.  
  236.     if (offlg) {
  237.     offlg = 0;
  238.     if (index[3] != 0 && wrdtyp[wptr - 2] != 3) {
  239.         /* exchange two nouns and tell parser the first is an adjective */
  240.  
  241.         wrdtyp[wptr] = wrdtyp[wptr - 1];
  242.         wrdnum[wptr] = wrdnum[wptr - 1];
  243.         wrdtyp[wptr - 1] = 3;
  244.         wrdnum[wptr - 1] = index[3];
  245.         if (wrdnum[wptr] == PHOTOG && wrdnum[wptr - 1] == FERRET) {
  246.         wrdnum[wptr - 1] = FAMILY;
  247.             }
  248.             goto lab200;
  249.         }
  250.     else
  251.             goto lab9200;
  252.     }
  253.     if (indx != AND)
  254.     goto lab270;
  255.     if (wrdtyp[wptr - 1] == -2)
  256.     goto lab201;
  257.     if (wrdtyp[wptr - 1] != 4)
  258.     goto lab9120;
  259.     wrdtyp[wptr] = -2;
  260.     goto lab200;
  261. lab270:
  262.     if (index[1] != 0 && index[0] == 0 && index[2] == 0
  263.     && index[3] == 0 && index[4] == 0)
  264.     goto lab9080;
  265.     if (index[0] == 0)
  266.     goto lab280;
  267.     if (adverb != 0)
  268.     goto lab9070;
  269.     adverb = indx;
  270.     if (adverb == WHERE || adverb == WHAT)
  271.     goto lab9130;
  272.     goto lab201;
  273.     /* at this point the word must be an adjectine, noun or preposition */
  274.  
  275. lab280:
  276.     if (wrdtyp[wptr - 1] == 3 && index[2] != 0)
  277.     goto lab9170;
  278.     if (index[2] != 0) {
  279.     wrdtyp[wptr] = 3;
  280.     wrdnum[wptr] = index[2];
  281.     } else if (index[3] != 0) {
  282.     wrdtyp[wptr] = 4;
  283.     wrdnum[wptr] = index[3];
  284.     } else {
  285.     wrdtyp[wptr] = 5;
  286.     wrdnum[wptr] = index[4];
  287.     }
  288.     if ((wrdtyp[wptr] == 4 && wrdtyp[wptr - 1] == 3) &&
  289.     wrdnum[wptr] < SAPPHI)
  290.     goto lab9190;
  291.     goto lab200;
  292.  
  293.  
  294.     /***********       error processing  */
  295.  
  296. lab9000:
  297.     lxx = lptr;
  298.     errno = 1;
  299.     goto lab9900;
  300. lab9010:
  301.     lxx = lptr;
  302.     errno = 2;
  303.     goto lab9900;
  304. lab9019:
  305.     lptr -= 1;
  306. lab9020:
  307.     lptr += 1;
  308.     lxx = lptr;
  309.     errno = 3;
  310.     goto lab9900;
  311. lab9030:
  312.     lxx = lptr;
  313.     errno = 4;
  314.     goto lab9900;
  315. lab9040:
  316.     lxx = lptr;
  317.     errno = 5;
  318.     goto lab9900;
  319. lab9050:
  320.     lxx = lptr;
  321.     errno = 6;
  322.     goto lab9900;
  323. lab9070:
  324.     lxx = lptr;
  325.     errno = 8;
  326.     goto lab9900;
  327. lab9080:
  328.     lxx = lptr;
  329.     errno = 9;
  330.     goto lab9900;
  331. lab9090:
  332.     lxx = 0;
  333.     errno = 10;
  334.     goto lab9900;
  335. lab9100:
  336.     lxx = 0;
  337.     errno = 11;
  338.     goto lab9900;
  339. lab9110:
  340.     lxx = lptr0 + 1;
  341.     errno = 12;
  342.     goto lab9900;
  343. lab9120:
  344.     lxx = lptr;
  345.     errno = 13;
  346.     goto lab9900;
  347. lab9130:
  348.     lxx = 0;
  349.     errno = 14;
  350.     goto lab9900;
  351. lab9140:
  352.     lxx = lptr;
  353.     errno = 15;
  354.     goto lab9900;
  355. lab9150:
  356.     lxx = lptr0;
  357.     errno = 16;
  358.     goto lab9900;
  359. lab9160:
  360.     lxx = 0;
  361.     errno = 17;
  362.     goto lab9900;
  363. lab9170:
  364.     lxx = lptr;
  365.     errno = 18;
  366.     goto lab9900;
  367. lab9180:
  368.     lxx = 0;
  369.     errno = 25;
  370.     goto lab9900;
  371. lab9190:
  372.     lxx = lptr;
  373.     errno = 107;
  374.     goto lab9900;
  375. lab9200:
  376.     lxx = lptr;
  377.     errno = 112;
  378. lab9900:
  379.     carerr(lxx, errno);
  380.     return (result);
  381. lab9998:
  382.     wrdtyp[1] = -1;
  383. lab9999:
  384.     if ((askx == TELL && (adverb == WHERE || adverb == WHAT))
  385.     || (askx == ASK && (adverb != WHERE && adverb != WHAT)))
  386.     goto lab9130;
  387.     if (adverb == WHERE || adverb == WHAT)
  388.     dotflg = 1;
  389.     result = 1;
  390.     return (result);
  391.  
  392. }
  393.  
  394. wscan()
  395. /*
  396.  * this routine reads the input ascii code and scans for punctuation or
  397.  * numbers and then converts the first 9 letters of a word to three integer*2
  398.  * words of radix 32 form  
  399.  */
  400.  
  401. {
  402.     char            m;
  403.     static int      pow32[] = {1, 32, 1024, 32768};
  404.     int             plcpnt, wpnt, kchar;
  405.  
  406.     if (dotflg) {
  407.     actor = 1;
  408.     dotflg = 0;
  409.     }
  410.     plcpnt = 1;
  411.     punct = 0;
  412.     wpnt = 1;
  413.     three[0] = 0;
  414.     three[1] = 0;
  415.     three[2] = 0;
  416.     while (inbuf[lptr] == ' ')
  417.     lptr++;
  418.     /*
  419.      * punct =1 is period, 2 is comma, 3 is number,4 is illegal character and
  420.      * 5 means a number directly follows a word 6 means letter follows a
  421.      * number 
  422.      */
  423.  
  424.     if (inbuf[lptr] == '.' || inbuf[lptr] == '?') {
  425.     dotflg = 1;
  426.     punct = 1;
  427.     lptr += 1;
  428.     return (0);
  429.     }
  430.     if (inbuf[lptr] == ',') {
  431.     punct = 2;
  432.     lptr += 1;
  433.     return (0);
  434.     }
  435.     while (inbuf[lptr] >= '0' && inbuf[lptr] <= '9') {
  436.     /* number handling */
  437.  
  438.     punct = 3;
  439.     if (three[0] < 3200)
  440.         three[0] = three[0] * 10 + inbuf[lptr] - '0';
  441.     lptr += 1;
  442.     }
  443.     if (punct == 3 && (inbuf[lptr] != '.' &&
  444.                inbuf[lptr] != ',' && inbuf[lptr] != '?' &&
  445.                inbuf[lptr] != ' '))
  446.     punct = 6;
  447.     if (punct == 3 || punct == 6)
  448.     return (0);
  449.     do {
  450.     if (!((inbuf[lptr] >= 'a' && inbuf[lptr] <= 'z') ||
  451.           (inbuf[lptr] >= 'A' && inbuf[lptr] <= 'Z'))) {
  452.         lptr += 1;
  453.         punct = 4;
  454.         return (0);
  455.         /* the actual letter packing is done here  */
  456.  
  457.     }
  458.     kchar = inbuf[lptr];
  459.     if (kchar >= 'a' && kchar <= 'z')
  460.         kchar -= ' ';
  461.     if (wpnt < 4)
  462.         three[wpnt - 1] = three[wpnt - 1] +
  463.                                 (kchar - '@') * pow32[3 - plcpnt];
  464.     plcpnt += 1;
  465.     if (plcpnt >= 4) {
  466.         wpnt += 1;
  467.         plcpnt = 1;
  468.     }
  469.     lptr += 1;
  470.     m = inbuf[lptr];
  471.     if (m == ' ' || m == ',' || m == '.' || m == '?') {
  472.         if (three[0] != 20741 || three[1] != 14336 ||
  473.         three[2] != 0)
  474.         return (0);
  475.         punct = 1;
  476.         return (0);
  477.     }
  478.     }
  479.     while (m < '0' || m > '9');
  480.     punct = 5;
  481.     return (0);
  482. }
  483.  
  484.  
  485. find(m)
  486.     int             m;
  487. {
  488.     /*
  489.      * this routine searches a vocabulary to find a word. index, on output,
  490.      * gives the position of the word in the list. synonyms do not increment
  491.      * the counter, so index*3-2 is **not** the actual pointer to the word in
  492.      * the list 
  493.      */
  494.  
  495.     int             i, t, k, type;
  496.  
  497.     for (i = 0; i < 5; i++)
  498.     index[i] = 0;
  499.     t = 0;
  500.     indx = 0;
  501.  
  502.     for (i = 1; i <= m * 3 - 2; i += 3) {
  503.     if (vocab[i] > 0)
  504.         indx += 1;
  505.     if (abs(vocab[i]) != three[0])
  506.         continue;
  507.     if (vocab[i + 1] != three[1])
  508.         continue;
  509.     if (vocab[i + 2] == three[2]) {
  510.         t = indx;
  511.         type = 1;
  512.         for (k = 1; k <= 4; k++)
  513.         if (indx >= typlst[k - 1])
  514.             type = type + 1;
  515.         index[type - 1] = indx;
  516.     }
  517.     }
  518.     indx = t;
  519. }
  520.  
  521. lbit(arg, pow)
  522.     int             arg, pow;
  523. {
  524.     return ((arg & (1 << pow)) != 0);
  525. }
  526.  
  527. parse()
  528. {
  529.     /*
  530.      * subroutine parse this mess deciphers the various direct and indirect
  531.      * (i.e. second, usually, but in 'give frog cup' the frog is the i.o.)
  532.      * objects. it associates them with their respective adjectives (dobjs(i)
  533.      * and doadjs(i) correspond) butflg is set if the "all but" construct is
  534.      * encountered allflg is set if the "all" construct is enconntered the
  535.      * d.o. and i.o prepositions are put in prepdo and prepio 
  536.      */
  537.  
  538.     int             result, wptr, thevrb, vrbind, vdo, vio, vobj, i;
  539.     int             frstaj, frstnn, errno, tprp;
  540.     result = 0;
  541.     thevrb = wrdnum[0];
  542.     vrbind = thevrb - VRBMIN + 1;
  543.  
  544.     vdo = 0;
  545.     vio = 0;
  546.     vobj = 0;
  547.     if (thevrb < SHIT) {
  548.     vdo = vrbpdo[vrbind];
  549.     vio = vrbpio[vrbind];
  550.     vobj = vrbobj[vrbind];
  551.     }
  552.     butflg = 0;
  553.     allflg = 0;
  554.     numdo = 0;
  555.     prepdo = 0;
  556.     prepio = 0;
  557.     iobj = 0;
  558.     ioadj = 0;
  559.     for (i = 0; i < 12; i++) {
  560.     dobjs[i] = 0;
  561.     doadjs[i] = 0;
  562.     }
  563.     /* this block is a test for "sit down" or "get up" or "look up" etc */
  564.  
  565.     if (((lbit(vobj, 1) && wrdnum[1] == DOWN) ||
  566.      (lbit(vobj, 2) && wrdnum[1] == UP)) && wrdtyp[2] == -1) {
  567.     prepdo = wrdnum[1];
  568.     result = 1;
  569.     goto finalout;
  570.     }
  571.     /* yell allows anything after it */
  572.  
  573.     if (thevrb == YELL)
  574.     goto testout;
  575.     wptr = 1;
  576.     frstaj = 0;
  577.     frstnn = 0;
  578.     /* a preposition immediately follows verb */
  579.  
  580.     if (wrdtyp[wptr] == 5) {
  581.     prepdo = wrdnum[wptr];
  582.     if (prepdo == BUT) {
  583.         errno = 21;
  584.         goto errorout;
  585.     }
  586.     if (!lbit(vdo, (prepdo - PRPMIN))) {
  587.         errno = 21;
  588.         goto errorout;
  589.     }
  590.     wptr += 1;
  591.     }
  592.     /*
  593.      * adjective follows verb *** special case of "terran" and "cygnan" as
  594.      * nouns 
  595.      */
  596.  
  597.     if (wrdtyp[wptr] == 3) {
  598.     if ((wrdnum[wptr] == TERRAN || wrdnum[wptr] == CYGNAN)
  599.         && wrdnum[0] == TRANSL)
  600.         wrdtyp[wptr] = 4;
  601.     else {
  602.         frstaj = wrdnum[wptr];
  603.         doadjs[0] = frstaj;
  604.         wptr += 1;
  605.     }
  606.     }
  607.     /* this takes care of the case of a verb alone on a line */
  608.  
  609.     if (wrdtyp[wptr] != 4) {
  610.     if (wrdtyp[wptr] != -1) {
  611.         errno = 28;
  612.         goto errorout;
  613.     } else {
  614.         {
  615.         if (thevrb >= SHIT) {
  616.             result = 1;
  617.             goto finalout;
  618.         }
  619.         if (!lbit(vobj, 7)) {
  620.             result = 1;
  621.             goto finalout;
  622.         }
  623.         }
  624.         errno = 27;
  625.         goto errorout;
  626.     }
  627.     }
  628.     frstnn = wrdnum[wptr];
  629.     /* look at first set of objects (not always d.o.) */
  630.  
  631.     dobjs[0] = frstnn;
  632.     numdo += 1;
  633.     if (numdo == 9) {
  634.     errno = 25;
  635.     goto errorout;
  636.     }
  637.     wptr += 1;
  638.  
  639.  
  640.     /* the following takes care of multiple objects */
  641.  
  642.     if (frstnn == ALL) {
  643.     if (!lbit(vobj, 5)) {
  644.         errno = 22;
  645.         goto errorout;
  646.     }
  647.     if (frstaj != 0) {
  648.         errno = 26;
  649.         goto errorout;
  650.     }
  651.     allflg = 1;
  652.     if (wrdnum[wptr] == BUT) {
  653.         butflg = 1;
  654.         /* check for adjective before noun */
  655.  
  656.         if (!(wrdtyp[wptr + 1] == 4 || (wrdtyp[wptr + 1] == 3
  657.                         && wrdtyp[wptr + 2] == 4))) {
  658.         errno = 23;
  659.         goto errorout;
  660.         }
  661.         wptr += 1;
  662.     }
  663.     }
  664.     if (butflg || (wrdtyp[wptr] == -2)) {
  665.     if (!lbit(vobj, 5)) {
  666.         errno = 22;
  667.         goto errorout;
  668.     }
  669.     mulobj(&wptr);
  670.     if (numdo > 9) {
  671.         errno = 25;
  672.         goto errorout;
  673.     }
  674.     }
  675.     /********** end multiple obj processor  */
  676.  
  677.  
  678.     if (wrdtyp[wptr] == -1)
  679.     goto testout;
  680.  
  681.     /* if the verb is "is" we may have a final adjective  */
  682.  
  683.     if (thevrb == IS && wrdtyp[wptr] == 3) {
  684.     doadjs[1] = wrdnum[wptr];
  685.     if (wrdtyp[wptr + 1] == -1)
  686.         goto testout;
  687.     errno = 20;
  688.     goto errorout;
  689.     }
  690.     /*
  691.      * if the next word is a noun or adjective, and verb is not "is" we have
  692.      * a non-prep indirect object such as the frog in "give frog water" 
  693.      */
  694.  
  695.     if (wrdtyp[wptr] == 4 || (wrdtyp[wptr] == 3 && wrdtyp[wptr + 1]
  696.                   == 4)) {
  697.     if (numdo > 1 || prepdo != 0) {
  698.         errno = 22;
  699.         goto errorout;
  700.     }
  701.     if (!lbit(vobj, 3)) {
  702.         errno = 24;
  703.         goto errorout;
  704.     }
  705.     prepio = TO;
  706.     ioadj = frstaj;
  707.     iobj = frstnn;
  708.     doadjs[0] = 0;
  709.     if (wrdtyp[wptr] == 3) {
  710.         doadjs[0] = wrdnum[wptr];
  711.         wptr += 1;
  712.     }
  713.     dobjs[0] = wrdnum[wptr];
  714.     numdo = 1;
  715.     wptr += 1;
  716.     /****** repeat the multiple obj processor */
  717.  
  718.     if (dobjs[0] == ALL) {
  719.         if (!lbit(vobj, 5)) {
  720.         errno = 22;
  721.         goto errorout;
  722.         }
  723.         if (doadjs[0] != 0) {
  724.         errno = 26;
  725.         goto errorout;
  726.         }
  727.         allflg = 1;
  728.         if (wrdtyp[wptr] == 5 && wrdnum[wptr] == BUT) {
  729.         butflg = 1;
  730.         if (!(wrdtyp[wptr + 1] == 4 || (wrdtyp[wptr + 1] == 3
  731.                         && wrdtyp[wptr + 2] == 4))) {
  732.             errno = 23;
  733.             goto errorout;
  734.         }
  735.         }
  736.     }
  737.     if (butflg || wrdtyp[wptr] == -2) {
  738.         if (!lbit(vobj, 5)) {
  739.         errno = 22;
  740.         goto errorout;
  741.         }
  742.         mulobj(&wptr);
  743.         if (numdo > 9) {
  744.         errno = 25;
  745.         goto errorout;
  746.         }
  747.     }
  748.     /***** end multiple object processor */
  749.  
  750.     if (wrdtyp[wptr] != -1) {
  751.         errno = 20;
  752.         goto errorout;
  753.     }
  754.     goto testout;
  755.     }
  756.     /* the only thing left that is legal is a perpositional construct */
  757.  
  758.     if (wrdtyp[wptr] != 5 || wrdnum[wptr] == BUT || (
  759.             wrdtyp[wptr + 1] == 5 && wrdnum[wptr + 1] == BUT)) {
  760.     errno = 20;
  761.     goto errorout;
  762.     }
  763.     tprp = wrdnum[wptr];
  764.     wptr += 1;
  765.     /*
  766.      * check for end of line or two preps in a row (e.g. fill the bottle up
  767.      * with water) 
  768.      */
  769.  
  770.     if (wrdtyp[wptr] == -1 || wrdtyp[wptr] == 5) {
  771.     if (prepdo != 0 || (!lbit(vdo, (tprp - PRPMIN)))
  772.         || (!lbit(vobj, 0))) {
  773.         errno = 20;
  774.         goto errorout;
  775.     }
  776.     prepdo = tprp;
  777.     if (wrdtyp[wptr] == -1)
  778.         goto testout;
  779.     wptr += 1;
  780.     }
  781.     if (!lbit(vio, (wrdnum[wptr - 1] - PRPMIN))) {
  782.     errno = 20;
  783.     goto errorout;
  784.     }
  785.     prepio = wrdnum[wptr - 1];
  786.     if (wrdtyp[wptr] == 3) {
  787.     ioadj = wrdnum[wptr];
  788.     wptr += 1;
  789.     }
  790.     if (wrdtyp[wptr] != 4) {
  791.     errno = 20;
  792.     goto errorout;
  793.     }
  794.     iobj = wrdnum[wptr];
  795.     wptr += 1;
  796.     if (wrdtyp[wptr] != -1) {
  797.     errno = 20;
  798.     goto errorout;
  799.     }
  800. testout:
  801.     if ((dobjs[0] == 0 && lbit(vobj, 7)) || (iobj == 0 &&
  802.                          lbit(vobj, 6))) {
  803.     errno = 20;
  804.     goto errorout;
  805.     }
  806.     if (!lbit(vobj, 4) && dobjs[0] != 0 && prepdo == 0) {
  807.     errno = 19;
  808.     goto errorout;
  809.     }
  810.     result = 1;
  811. finalout:
  812.  
  813.     if (wrdnum[0] == AGAIN) {
  814.     for (i = 0; i < 12; i++) {
  815.         doadjs[i] = zadjs[i];
  816.         dobjs[i] = zobjs[i];
  817.     }
  818.     ioadj = ziadj;
  819.     iobj = ziobj;
  820.     prepdo = zpdo;
  821.     prepio = zpio;
  822.     actor = zactor;
  823.     adverb = zadvrb;
  824.     wrdnum[0] = zverb;
  825.     numdo = znumb;
  826.     allflg = zall;
  827.     butflg = zbut;
  828.     } else {
  829.     for (i = 0; i < 12; i++) {
  830.         zadjs[i] = doadjs[i];
  831.         zobjs[i] = dobjs[i];
  832.     }
  833.     ziadj = ioadj;
  834.     ziobj = iobj;
  835.     zpdo = prepdo;
  836.     zpio = prepio;
  837.     zactor = actor;
  838.     zadvrb = adverb;
  839.     zverb = wrdnum[0];
  840.     zall = allflg;
  841.     zbut = butflg;
  842.     }
  843.     return (result);
  844. errorout:
  845.     carerr(0, errno);
  846.     return (result);
  847. }
  848.  
  849. mulobj(wptr)
  850.     int            *wptr;
  851. {
  852.     /****   multiple opject subroutine from "parse" */
  853.  
  854.     while (1) {
  855.     if (wrdtyp[*wptr] == 3) {
  856.         doadjs[numdo] = wrdnum[*wptr];
  857.         *wptr += 1;
  858.     }
  859.     if (wrdtyp[*wptr] == 4) {
  860.         numdo += 1;
  861.         if (numdo > 10)
  862.         return (1);
  863.         dobjs[numdo - 1] = wrdnum[*wptr];
  864.         *wptr += 1;
  865.         if (wrdtyp[*wptr] != -2)
  866.         return (1);
  867.     }
  868.     *wptr += 1;
  869.     }
  870. }
  871.