home *** CD-ROM | disk | FTP | other *** search
/ PSION CD 2 / PsionCDVol2.iso / Programs / 875 / inform.sis (.txt) next >
EPOC Installation Package  |  1999-09-14  |  643KB  |  9,727 lines

  1. Lib\Verblibm.h!:\inform\lib\Verblibm.hLib\Verblib.h!:\inform\lib\Verblib.hLib\Parserm.h!:\inform\lib\Parserm.hLib\English.h!:\inform\lib\English.hLib\Linklv.h!:\inform\lib\Linklv.hLib\Linklpa.h!:\inform\lib\Linklpa.hLib\Infix.h!:\inform\lib\Infix.hLib\Grammar.h!:\inform\lib\Grammar.hLib\Parser.h!:\inform\lib\Parser.h\epoc32\wins\c\documents\Inform CLI!:\inform\Command Line\epoc32\wins\c\documents\Inform Readme!:\inform\Readme\epoc32\release\marm\rel\inform.exe!:\system\programs\inform.exeInform 6.21 with library 6/9! ----------------------------------------------------------------------------
  2. !  VERBLIBM:  Core of standard verbs library.
  3. !  Supplied for use with Inform 6                         Serial number 990428
  4. !                                                                  Release 6/9
  5. !  (c) Graham Nelson 1993, 1994, 1995, 1996, 1997, 1998, 1999
  6. !      but freely usable (see manuals)
  7. ! ----------------------------------------------------------------------------
  8. #IFDEF MODULE_MODE;
  9. Constant DEBUG;
  10. Constant Grammar__Version2;
  11. Include "linklpa";
  12. Include "linklv";
  13. #ENDIF;
  14. System_file;
  15. ! ----------------------------------------------------------------------------
  16. [ Banner i;
  17.    if (Story ~= 0)
  18. #IFV5; style bold; #ENDIF;
  19.    print (string) Story;
  20. #IFV5; style roman; #ENDIF;
  21.    if (Headline ~= 0)
  22.        print (string) Headline;
  23.    print "Release ", (0-->1) & $03ff, " / Serial number ";
  24.    for (i=18:i<24:i++) print (char) 0->i;
  25.    print " / Inform v"; inversion;
  26.    print " Library ", (string) LibRelease, " ";
  27. #ifdef STRICT_MODE;
  28.    print "S";
  29. #endif;
  30. #ifdef INFIX;
  31.    print "X";
  32. #ifnot;
  33. #ifdef DEBUG;
  34.    print "D";
  35. #endif;
  36. #endif;
  37.    new_line;
  38. [ VersionSub;
  39.   Banner();
  40.   if (standard_interpreter > 0)
  41.       print "Standard interpreter ",
  42.           standard_interpreter/256, ".", standard_interpreter%256,
  43.           " (", 0->$1e, (char) 0->$1f, ") / ";
  44.   else print "Interpreter ", 0->$1e, " Version ", (char) 0->$1f, " / ";
  45.   print "Library serial number ", (string) LibSerial, "^";
  46. #IFDEF LanguageVersion;
  47.   print (string) LanguageVersion, "^";
  48. #ENDIF;
  49. [ RunTimeError n p1 p2;
  50. #IFDEF DEBUG;
  51.   print "** Library error ", n, " (", p1, ",", p2, ") **^** ";
  52.   switch(n)
  53.   {   1: print "preposition not found (this should not occur)";
  54.       2: print "Property value not routine or string: ~",
  55.                (property) p2, "~ of ~", (name) p1, "~ (", p1, ")";
  56.       3: print "Entry in property list not routine or string: ~",
  57.                (property) p2, "~ list of ~", (name) p1, "~ (", p1, ")";
  58.       4: print "Too many timers/daemons are active simultaneously.  The
  59.                 limit is the library constant MAX_TIMERS (currently ",
  60.                 MAX_TIMERS, ") and should be increased";
  61.       5: print "Object ~", (name) p1, "~ has no ~time_left~ property";
  62.       7: print "The object ~", (name) p1, "~ can only be used as a player
  63.                 object if it has the ~number~ property";
  64.       8: print "Attempt to take random entry from an empty table array";
  65.       9: print p1, " is not a valid direction property number";
  66.       10: print "The player-object is outside the object tree";
  67.       11: print "The room ~", (name) p1, "~ has no ~description~ property";
  68.       12: print "Tried to set a non-existent pronoun using SetPronoun";
  69.       13: print "A 'topic' token can only be followed by a preposition";
  70.       default: print "(unexplained)";
  71.   " **";
  72. #IFNOT;
  73.   "** Library error ", n, " (", p1, ",", p2, ") **";
  74. #ENDIF;
  75. ! ----------------------------------------------------------------------------
  76. !  The WriteListFrom routine, a flexible object-lister taking care of
  77. !  plurals, inventory information, various formats and so on.  This is used
  78. !  by everything in the library which ever wants to list anything.
  79. !  If there were no objects to list, it prints nothing and returns false;
  80. !  otherwise it returns true.
  81. !  o is the object, and style is a bitmap, whose bits are given by:
  82. ! ----------------------------------------------------------------------------
  83. Constant NEWLINE_BIT    1;    !  New-line after each entry
  84. Constant INDENT_BIT     2;    !  Indent each entry by depth
  85. Constant FULLINV_BIT    4;    !  Full inventory information after entry
  86. Constant ENGLISH_BIT    8;    !  English sentence style, with commas and and
  87. Constant RECURSE_BIT   16;    !  Recurse downwards with usual rules
  88. Constant ALWAYS_BIT    32;    !  Always recurse downwards
  89. Constant TERSE_BIT     64;    !  More terse English style
  90. Constant PARTINV_BIT  128;    !  Only brief inventory information after entry
  91. Constant DEFART_BIT   256;    !  Use the definite article in list
  92. Constant WORKFLAG_BIT 512;    !  At top level (only), only list objects
  93.                               !  which have the "workflag" attribute
  94. Constant ISARE_BIT   1024;    !  Print " is" or " are" before list
  95. Constant CONCEAL_BIT 2048;    !  Omit objects with "concealed" or "scenery":
  96.                               !  if WORKFLAG_BIT also set, then does _not_
  97.                               !  apply at top level, but does lower down
  98. Constant NOARTICLE_BIT 4096;  !  Print no articles, definite or not
  99. [ NextEntry o odepth;
  100.   for(::)
  101.   {   o=sibling(o);
  102.       if (o==0) return 0;
  103.       if (lt_value ~=0 && o.list_together~=lt_value) continue;
  104.       if (c_style & WORKFLAG_BIT ~= 0 && odepth==0 && o hasnt workflag)
  105.           continue;
  106.       if (c_style & CONCEAL_BIT ~= 0 && (o has concealed || o has scenery))
  107.           continue;
  108.       return o;
  109. [ WillRecurs o;
  110.   if (c_style & ALWAYS_BIT ~= 0) rtrue;
  111.   if (c_style & RECURSE_BIT == 0) rfalse;
  112.   if (o has transparent
  113.       || o has supporter
  114.       || (o has container && o has open)) rtrue;
  115.   rfalse;
  116. [ ListEqual o1 o2;
  117.   if (child(o1)~=0 && WillRecurs(o1)~=0) rfalse;
  118.   if (child(o2)~=0 && WillRecurs(o2)~=0) rfalse;
  119.   if (c_style & (FULLINV_BIT + PARTINV_BIT) ~= 0)
  120.   {   if ((o1 hasnt worn && o2 has worn)
  121.           || (o2 hasnt worn && o1 has worn)) rfalse;
  122.       if ((o1 hasnt light && o2 has light)
  123.           || (o2 hasnt light && o1 has light)) rfalse;
  124.   return Identical(o1,o2);
  125. [ SortTogether obj value;
  126. !  print "Sorting together possessions of ",
  127. !         (object) obj, " by value ", value, "^";
  128. !  for (x=child(obj):x~=0:x=sibling(x))
  129. !      print (the) x, " no: ", x, " lt: ", x.list_together, "^";
  130.   while (child(obj)~=0)
  131.   {   if (child(obj).list_together~=value) move child(obj) to out_obj;
  132.       else move child(obj) to in_obj;
  133.   while (child(in_obj)~=0)
  134.       move child(in_obj) to obj;
  135.   while (child(out_obj)~=0)
  136.       move child(out_obj) to obj;
  137. [ SortOutList obj i k l;
  138. !  print "^^Sorting out list from ", (name) obj, "^  ";
  139. !  for (i=child(location):i~=0:i=sibling(i))
  140. !      print (name) i, " --> ";
  141. !  new_line;
  142.  .AP_SOL;
  143.   for (i=obj:i~=0:i=sibling(i))
  144.   {   k=i.list_together;
  145.       if (k~=0)
  146.       {   ! print "Scanning ", (name) i, " with lt=", k, "^";
  147.           for (i=sibling(i):i~=0 && i.list_together==k:) i=sibling(i);
  148.               if (i==0) rfalse;
  149.           !print "First not in block is ", (name) i,
  150.           ! " with lt=", i.list_together, "^";
  151.           for (l=sibling(i):l~=0:l=sibling(l))
  152.               if (l.list_together==k)
  153.               {   SortTogether(parent(obj), k);
  154. !  print "^^After ST:^  ";
  155. !  for (i=child(location):i~=0:i=sibling(i))
  156. !      print (name) i, " --> ";
  157. !  new_line;
  158.                   obj = child(parent(obj));
  159.                   jump AP_SOL;
  160.               }
  161.       }
  162. [ Print__Spaces n;         ! To avoid a bug occurring in Inform 6.01 to 6.10
  163.   if (n==0) return; spaces n; ];
  164. [ WriteListFrom o style depth;
  165.   if (o==child(parent(o)))
  166.   {   SortOutList(o); o=child(parent(o)); }
  167.   c_style=style;
  168.   wlf_indent=0; WriteListR(o,depth);
  169.   rtrue;
  170. [ WriteListR o depth stack_pointer  classes_p sizes_p i j k k2 l m n q senc mr;
  171.   if (depth>0 && o==child(parent(o)))
  172.   {   SortOutList(o); o=child(parent(o)); }
  173.   for (::)
  174.   {   if (o==0) rfalse;
  175.       if (c_style & WORKFLAG_BIT ~= 0 && depth==0 && o hasnt workflag)
  176.       {   o = sibling(o); continue; }
  177.       if (c_style & CONCEAL_BIT ~= 0
  178.           && (o has concealed || o has scenery))
  179.       {   o=sibling(o); continue; }
  180.       break;
  181.   classes_p = match_classes + stack_pointer;
  182.   sizes_p   = match_list + stack_pointer;
  183.   for (i=o,j=0:i~=0 && (j+stack_pointer)<128:i=NextEntry(i,depth),j++)
  184.   {   classes_p->j=0;
  185.       if (i.plural~=0) k++;
  186.   if (c_style & ISARE_BIT ~= 0)
  187.   {   if (j==1 && o hasnt pluralname)
  188.           print (string) IS__TX; else print (string) ARE__TX;
  189.       if (c_style & NEWLINE_BIT ~= 0) print ":^"; else print (char) ' ';
  190.       c_style = c_style - ISARE_BIT;
  191.   stack_pointer = stack_pointer+j+1;
  192.   if (k<2) jump EconomyVersion;   ! It takes two to plural
  193.   n=1;
  194.   for (i=o,k=0:k<j:i=NextEntry(i,depth),k++)
  195.       if (classes_p->k==0)
  196.       {   classes_p->k=n; sizes_p->n=1;
  197.           for (l=NextEntry(i,depth), m=k+1:l~=0 && m<j:
  198.                l=NextEntry(l,depth), m++)
  199.               if (classes_p->m==0 && i.plural~=0 && l.plural~=0)
  200.               {   if (ListEqual(i,l)==1)
  201.                   {   sizes_p->n = sizes_p->n + 1;
  202.                       classes_p->m = n;
  203.                   }
  204.               }
  205.           n++;
  206.       }
  207.   n--;
  208.   for (i=1, j=o, k=0: i<=n: i++, senc++)
  209.   {   while (((classes_p->k) ~= i)
  210.              && ((classes_p->k) ~= -i)) { k++; j=NextEntry(j,depth); }
  211.       m=sizes_p->i;
  212.       if (j==0) mr = 0;
  213.       else
  214.       {   if (j.list_together~=0 or lt_value
  215.               && ZRegion(j.list_together)==2 or 3
  216.               && j.list_together==mr) senc--;
  217.           mr=j.list_together;
  218.       }
  219.   senc--;
  220.   for (i=1, j=o, k=0, mr=0: senc>=0: i++, senc--)
  221.   {   while (((classes_p->k) ~= i)
  222.              && ((classes_p->k) ~= -i)) { k++; j=NextEntry(j,depth); }
  223.       if (j.list_together~=0 or lt_value)
  224.       {   if (j.list_together==mr) { senc++; jump Omit_FL2; }
  225.           k2=NextEntry(j,depth);
  226.           if (k2==0 || k2.list_together~=j.list_together) jump Omit_WL2;
  227.           k2=ZRegion(j.list_together);
  228.           if (k2==2 or 3)
  229.           {   q=j; listing_size=1; l=k; m=i;
  230.               while (m<n && q.list_together==j.list_together)
  231.               {   m++;
  232.                   while (((classes_p->l) ~= m)
  233.                          && ((classes_p->l) ~= -m))
  234.                   {   l++; q=NextEntry(q,depth); }
  235.                   if (q.list_together==j.list_together) listing_size++;
  236.               }
  237. !              print " [", listing_size, "] ";
  238.               if (listing_size==1) jump Omit_WL2;
  239.               if (c_style & INDENT_BIT ~= 0)
  240.                   Print__Spaces(2*(depth+wlf_indent));
  241.               if (k2==3)
  242.               {   q=0; for (l=0:l<listing_size:l++) q=q+sizes_p->(l+i);
  243.                   EnglishNumber(q); print " ";
  244.                   print (string) j.list_together;
  245.                   if (c_style & ENGLISH_BIT ~= 0) print " (";
  246.                   if (c_style & INDENT_BIT ~= 0) print ":^";
  247.               }
  248.               q=c_style;
  249.               if (k2~=3)
  250.               {   inventory_stage=1;
  251.                   parser_one=j; parser_two=depth+wlf_indent;
  252.                   if (RunRoutines(j,list_together)==1) jump Omit__Sublist2;
  253.               }
  254.               @push lt_value; @push listing_together; @push listing_size;
  255.               lt_value=j.list_together; listing_together=j; wlf_indent++;
  256.               WriteListR(j,depth,stack_pointer); wlf_indent--;
  257.               @pull listing_size; @pull listing_together; @pull lt_value;
  258.               if (k2==3)
  259.               {   if (q & ENGLISH_BIT ~= 0) print ")";
  260.               }
  261.               else
  262.               {   inventory_stage=2;
  263.                   parser_one=j; parser_two=depth+wlf_indent;
  264.                   RunRoutines(j,list_together);
  265.               }
  266.              .Omit__Sublist2;
  267.               if (q & NEWLINE_BIT ~= 0 && c_style & NEWLINE_BIT == 0)
  268.                   new_line;
  269.               c_style=q;
  270.               mr=j.list_together;
  271.               jump Omit_EL2;
  272.           }
  273.       }
  274.      .Omit_WL2;
  275.       if (WriteBeforeEntry(j,depth,-senc)==1) jump Omit_FL2;
  276.       if (sizes_p->i == 1)
  277.       {   if (c_style & NOARTICLE_BIT ~= 0) print (name) j;
  278.           else
  279.           {   if (c_style & DEFART_BIT ~= 0) print (the) j; else print (a) j;
  280.           }
  281.       }
  282.       else
  283.       {   if (c_style & DEFART_BIT ~= 0)
  284.               PrefaceByArticle(j, 1, sizes_p->i);
  285.           print (number) sizes_p->i, " ";
  286.           PrintOrRun(j,plural,1);
  287.       }
  288.       WriteAfterEntry(j,depth,stack_pointer);
  289.      .Omit_EL2;
  290.       if (c_style & ENGLISH_BIT ~= 0)
  291.       {   if (senc==1) print (string) AND__TX;
  292.           if (senc>1) print ", ";
  293.       }
  294.      .Omit_FL2;
  295.   rtrue;
  296.   .EconomyVersion;
  297.   n=j;
  298.   for (i=1, j=o: i<=n: j=NextEntry(j,depth), i++, senc++)
  299.   {   if (j.list_together~=0 or lt_value
  300.           && ZRegion(j.list_together)==2 or 3
  301.           && j.list_together==mr) senc--;
  302.       mr=j.list_together;
  303.   for (i=1, j=o, mr=0: i<=senc: j=NextEntry(j,depth), i++)
  304.   {   if (j.list_together~=0 or lt_value)
  305.       {   if (j.list_together==mr) { i--; jump Omit_FL; }
  306.           k=NextEntry(j,depth);
  307.           if (k==0 || k.list_together~=j.list_together) jump Omit_WL;
  308.           k=ZRegion(j.list_together);
  309.           if (k==2 or 3)
  310.           {   if (c_style & INDENT_BIT ~= 0)
  311.                   Print__Spaces(2*(depth+wlf_indent));
  312.               if (k==3)
  313.               {   q=j; l=0;
  314.                   do
  315.                   {   q=NextEntry(q,depth); l++;
  316.                   } until (q==0 || q.list_together~=j.list_together);
  317.                   EnglishNumber(l); print " ";
  318.                   print (string) j.list_together;
  319.                   if (c_style & ENGLISH_BIT ~= 0) print " (";
  320.                   if (c_style & INDENT_BIT ~= 0) print ":^";
  321.               }
  322.               q=c_style;
  323.               if (k~=3)
  324.               {   inventory_stage=1;
  325.                   parser_one=j; parser_two=depth+wlf_indent;
  326.                   if (RunRoutines(j,list_together)==1) jump Omit__Sublist;
  327.               }
  328.               @push lt_value; @push listing_together; @push listing_size;
  329.               lt_value=j.list_together; listing_together=j; wlf_indent++;
  330.               WriteListR(j,depth,stack_pointer); wlf_indent--;
  331.               @pull listing_size; @pull listing_together; @pull lt_value;
  332.               if (k==3)
  333.               {   if (q & ENGLISH_BIT ~= 0) print ")";
  334.               }
  335.               else
  336.               {   inventory_stage=2;
  337.                   parser_one=j; parser_two=depth+wlf_indent;
  338.                   RunRoutines(j,list_together);
  339.               }
  340.              .Omit__Sublist;
  341.               if (q & NEWLINE_BIT ~= 0 && c_style & NEWLINE_BIT == 0) new_line;
  342.               c_style=q;
  343.               mr=j.list_together;
  344.               jump Omit_EL;
  345.           }
  346.       }
  347.      .Omit_WL;
  348.       if (WriteBeforeEntry(j,depth,i-senc)==1) jump Omit_FL;
  349.       if (c_style & NOARTICLE_BIT ~= 0) print (name) j;
  350.       else
  351.       {   if (c_style & DEFART_BIT ~= 0) print (the) j; else print (a) j;
  352.       }
  353.       WriteAfterEntry(j,depth,stack_pointer);
  354.      .Omit_EL;
  355.       if (c_style & ENGLISH_BIT ~= 0)
  356.       {   if (i==senc-1) print (string) AND__TX;
  357.           if (i<senc-1) print ", ";
  358.       }
  359.      .Omit_FL;
  360. [ WriteBeforeEntry o depth sentencepos  flag;
  361.   if (c_style & INDENT_BIT ~= 0) Print__Spaces(2*(depth+wlf_indent));
  362.   if (c_style & FULLINV_BIT ~= 0)
  363.   {   if (o.invent~=0)
  364.       {   inventory_stage=1;
  365.           flag=PrintOrRun(o,invent,1);
  366.           if (flag==1)
  367.           {   if (c_style & ENGLISH_BIT ~= 0)
  368.               {   if (sentencepos == -1) print (string) AND__TX;
  369.                   if (sentencepos < -1) print ", ";
  370.               }
  371.               if (c_style & NEWLINE_BIT ~= 0) new_line;
  372.           }
  373.       }
  374.   return flag;
  375. [ WriteAfterEntry o depth stack_p  flag flag2 flag3 p comb;
  376.   if (c_style & PARTINV_BIT ~= 0)
  377.   {   comb=0;
  378.       if (o has light && location hasnt light) comb=comb+1;
  379.       if (o has container && o hasnt open)     comb=comb+2;
  380.       if ((o has container && (o has open || o has transparent))
  381.           && (child(o)==0)) comb=comb+4;
  382.       if (comb==1) L__M(##ListMiscellany, 1, o);
  383.       if (comb==2) L__M(##ListMiscellany, 2, o);
  384.       if (comb==3) L__M(##ListMiscellany, 3, o);
  385.       if (comb==4) L__M(##ListMiscellany, 4, o);
  386.       if (comb==5) L__M(##ListMiscellany, 5, o);
  387.       if (comb==6) L__M(##ListMiscellany, 6, o);
  388.       if (comb==7) L__M(##ListMiscellany, 7, o);
  389.   if (c_style & FULLINV_BIT ~= 0)
  390.   {   if (o.invent ~= 0)
  391.       {   inventory_stage=2;
  392.           if (RunRoutines(o,invent)~=0)
  393.           {   if (c_style & NEWLINE_BIT ~= 0) new_line;
  394.               rtrue;
  395.           }
  396.       }
  397.       if (o has light && o has worn)
  398.       {    L__M(##ListMiscellany, 8); flag2=1; }
  399.       else
  400.       {   if (o has light) {  L__M(##ListMiscellany, 9, o); flag2=1; }
  401.           if (o has worn)  {  L__M(##ListMiscellany, 10, o); flag2=1; }
  402.       }
  403.       if (o has container)
  404.       {   if (o has openable)
  405.           {   if (flag2==1) print (string) AND__TX;
  406.               else L__M(##ListMiscellany, 11, o);
  407.               if (o has open)
  408.               {   if (child(o)==0) L__M(##ListMiscellany, 13, o);
  409.                   else L__M(##ListMiscellany, 12, o);
  410.               }
  411.               else
  412.               {   if (o has lockable && o has locked)
  413.                       L__M(##ListMiscellany, 15, o);
  414.                   else L__M(##ListMiscellany, 14, o);
  415.               }
  416.               flag2=1;
  417.           }
  418.           else
  419.               if (child(o)==0 && o has transparent)
  420.               {   if (flag2==1) L__M(##ListMiscellany, 16, o);
  421.                   else L__M(##ListMiscellany, 17, o);
  422.               }
  423.       }
  424.       if (flag2==1) print ")";
  425.   if (c_style & CONCEAL_BIT == 0)
  426.   {   flag3 = children(o);
  427.       flag2 = child(o);
  428.   else
  429.   {   flag3 = 0;
  430.       objectloop (p in o)
  431.           if (p hasnt concealed && p hasnt scenery) { flag3++; flag2 = p; }
  432.   if (c_style & ALWAYS_BIT ~= 0 && flag3>0)
  433.   {   if (c_style & ENGLISH_BIT ~= 0) L__M(##ListMiscellany, 18, o);
  434.       flag=1;
  435.   if (c_style & RECURSE_BIT ~= 0 && flag3>0)
  436.   {   if (o has supporter)
  437.       {   if (c_style & ENGLISH_BIT ~= 0)
  438.           {   if (c_style & TERSE_BIT ~= 0)
  439.                    L__M(##ListMiscellany, 19, o);
  440.               else L__M(##ListMiscellany, 20, o);
  441.               if (o has animate) print (string) WHOM__TX;
  442.               else print (string) WHICH__TX;
  443.           }
  444.           flag=1;
  445.       }
  446.       if (o has container && (o has open || o has transparent))
  447.       {   if (c_style & ENGLISH_BIT ~= 0)
  448.           {   if (c_style & TERSE_BIT ~= 0)
  449.                    L__M(##ListMiscellany, 21, o);
  450.               else L__M(##ListMiscellany, 22, o);
  451.               if (o has animate) print (string) WHOM__TX;
  452.               else print (string) WHICH__TX;
  453.           }
  454.           flag=1;
  455.       }
  456.   if (flag==1 && c_style & ENGLISH_BIT ~= 0)
  457.   {   if (flag3 > 1 || flag2 has pluralname)
  458.            print (string) ARE2__TX;
  459.       else print (string) IS2__TX;
  460.   if (c_style & NEWLINE_BIT ~= 0) new_line;
  461.   if (flag==1)
  462.   {   o = child(o);
  463.       @push lt_value; @push listing_together; @push listing_size;
  464.       lt_value = 0; listing_together = 0; listing_size = 0;
  465.       WriteListR(o, depth+1, stack_p);
  466.       @pull listing_size; @pull listing_together; @pull lt_value;
  467.       if (c_style & TERSE_BIT ~= 0) print ")";
  468. ! ----------------------------------------------------------------------------
  469. !  Much better menus can be created using the optional library extension
  470. !  "menus.h".  These are provided for compatibility with previous practice:
  471. ! ----------------------------------------------------------------------------
  472. [ LowKey_Menu menu_choices EntryR ChoiceR lines main_title i j;
  473.   menu_nesting++;
  474.  .LKRD;
  475.   menu_item=0;
  476.   lines=indirect(EntryR);
  477.   main_title=item_name;
  478.   print "--- "; print (string) main_title; print " ---^^";
  479.   if (menu_choices ofclass Routine) menu_choices.call();
  480.   else print (string) menu_choices;
  481.   for (::)
  482.   {   L__M(##Miscellany, 52, lines);
  483.       print "> ";
  484.       #IFV3; read buffer parse;
  485.       #IFNOT; read buffer parse DrawStatusLine;
  486.       #ENDIF;
  487.       i=parse-->1;
  488.       if (i==QUIT1__WD or QUIT2__WD || parse->1==0)
  489.       {   menu_nesting--; if (menu_nesting>0) rfalse;
  490.           if (deadflag==0) <<Look>>;
  491.           rfalse;
  492.       }
  493.       i=TryNumber(1);
  494.       if (i==0) jump LKRD;
  495.       if (i<1 || i>lines) continue;
  496.       menu_item=i;
  497.       j=indirect(ChoiceR);
  498.       if (j==2) jump LKRD;
  499.       if (j==3) rfalse;
  500. #IFV3;
  501. [ DoMenu menu_choices EntryR ChoiceR;
  502.   LowKey_Menu(menu_choices,EntryR,ChoiceR);
  503. #ENDIF;
  504. #IFV5;
  505. [ DoMenu menu_choices EntryR ChoiceR
  506.          lines main_title main_wid cl i j oldcl pkey;
  507.   if (pretty_flag==0)
  508.       return LowKey_Menu(menu_choices,EntryR,ChoiceR);
  509.   menu_nesting++;
  510.   menu_item=0;
  511.   lines=indirect(EntryR);
  512.   main_title=item_name; main_wid=item_width;
  513.   cl=7;
  514.   .ReDisplay;
  515.       oldcl=0;
  516.       @erase_window $ffff;
  517.       i=lines+7;
  518.       @split_window i;
  519.       i = 0->33;
  520.       if (i==0) i=80;
  521.       @set_window 1;
  522.       @set_cursor 1 1;
  523.       style reverse;
  524.       spaces(i); j=i/2-main_wid;
  525.       @set_cursor 1 j;
  526.       print (string) main_title;
  527.       @set_cursor 2 1; spaces(i);
  528.       @set_cursor 2 2; print (string) NKEY__TX;
  529.       j=i-12; @set_cursor 2 j; print (string) PKEY__TX;
  530.       @set_cursor 3 1; spaces(i);
  531.       @set_cursor 3 2; print (string) RKEY__TX;
  532.       j=i-17; @set_cursor 3 j;
  533.       if (menu_nesting==1) print (string) QKEY1__TX;
  534.                       else print (string) QKEY2__TX;
  535.       style roman;
  536.       @set_cursor 5 2; font off;
  537.       if (menu_choices ofclass String) print (string) menu_choices;
  538.       else menu_choices.call();
  539.       for (::)
  540.       {   if (cl ~= oldcl)
  541.           {   if (oldcl>0) { @set_cursor oldcl 4; print " "; }
  542.               @set_cursor cl 4; print ">";
  543.           }
  544.           oldcl=cl;
  545.           @read_char 1 -> pkey;
  546.           if (pkey==NKEY1__KY or NKEY2__KY or 130)
  547.           {   cl++; if (cl==7+lines) cl=7; continue;
  548.           }
  549.           if (pkey==PKEY1__KY or PKEY2__KY or 129)
  550.           {   cl--; if (cl==6)  cl=6+lines; continue;
  551.           }
  552.           if (pkey==QKEY1__KY or QKEY2__KY or 27 or 131) break;
  553.           if (pkey==10 or 13 or 132)
  554.           {   @set_window 0; font on;
  555.               new_line; new_line; new_line;
  556.               menu_item=cl-6;
  557.               EntryR.call();
  558.               @erase_window $ffff;
  559.               @split_window 1;
  560.               i = 0->33; if (i==0) { i=80; }
  561.               @set_window 1; @set_cursor 1 1; style reverse; spaces(i);
  562.               j=i/2-item_width;
  563.               @set_cursor 1 j;
  564.               print (string) item_name;
  565.               style roman; @set_window 0; new_line;
  566.               i = ChoiceR.call();
  567.               if (i==2) jump ReDisplay;
  568.               if (i==3) break;
  569.               L__M(##Miscellany, 53);
  570.               @read_char 1 -> pkey; jump ReDisplay;
  571.           }
  572.       }
  573.       menu_nesting--; if (menu_nesting>0) rfalse;
  574.       font on; @set_cursor 1 1;
  575.       @erase_window $ffff; @set_window 0;
  576.       new_line; new_line; new_line;
  577.       if (deadflag==0) <<Look>>;
  578. #ENDIF;
  579. ! ----------------------------------------------------------------------------
  580. !   A cunning routine (which could have been a daemon, but isn't, for the
  581. !   sake of efficiency) to move objects which could be in many rooms about
  582. !   so that the player never catches one not in place
  583. ! ----------------------------------------------------------------------------
  584. [ MoveFloatingObjects i k l m address flag;
  585.   objectloop (i)
  586.   {   address=i.&found_in;
  587.       if (address~=0 && i hasnt absent)
  588.       {   if (ZRegion(address-->0)==2)
  589.           {   if (i.found_in() ~= 0) move i to location; else remove i;
  590.           }
  591.           else
  592.           {   k=i.#found_in;
  593.               for (l=0: l<k/2: l++)
  594.               {   m=address-->l;
  595.                   if (m==location || m in location)
  596.                   {   if (i notin location) move i to location;
  597.                       flag = true;
  598.                   }
  599.               }
  600.               if (flag == false) { if (parent(i)) remove i; }
  601.           }
  602.       }
  603. ! ----------------------------------------------------------------------------
  604. !   Two little routines for moving the player safely.
  605. ! ----------------------------------------------------------------------------
  606. [ PlayerTo newplace flag;
  607.   move player to newplace;
  608.   while (parent(newplace)~=0) newplace=parent(newplace);
  609.   location=newplace;
  610.   real_location=location; MoveFloatingObjects();
  611.   AdjustLight(1);
  612.   if (flag==0) <Look>;
  613.   if (flag==1) { NoteArrival(); ScoreArrival(); }
  614.   if (flag==2) LookSub(1);
  615. [ MovePlayer direc; <Go direc>; <Look>; ];
  616. ! ----------------------------------------------------------------------------
  617. !   The handy YesOrNo routine, and some "meta" verbs
  618. ! ----------------------------------------------------------------------------
  619. [ YesOrNo i;
  620.   for (::)
  621.    #IFV3; read buffer parse; #ENDIF;
  622.    #IFV5; read buffer parse DrawStatusLine; #ENDIF;
  623.       i=parse-->1;
  624.       if (i==YES1__WD or YES2__WD or YES3__WD) rtrue;
  625.       if (i==NO1__WD or NO2__WD or NO3__WD) rfalse;
  626.       L__M(##Quit,1); print "> ";
  627. [ QuitSub; L__M(##Quit,2); if (YesOrNo()~=0) quit; ];
  628. [ RestartSub; L__M(##Restart,1);
  629.   if (YesOrNo()~=0) { @restart; L__M(##Restart,2); }
  630. [ RestoreSub;
  631.   restore Rmaybe;
  632.   return L__M(##Restore,1);
  633.   .RMaybe; L__M(##Restore,2);
  634. [ SaveSub;
  635.   save Smaybe;
  636.   return L__M(##Save,1);
  637.   .SMaybe; L__M(##Save,2);
  638. [ VerifySub;
  639.   @verify ?Vmaybe;
  640.   jump Vwrong;
  641.   .Vmaybe; return L__M(##Verify,1);
  642.   .Vwrong;
  643.   L__M(##Verify,2);
  644. [ ScriptOnSub;
  645.   transcript_mode = ((0-->8) & 1);
  646.   if (transcript_mode) return L__M(##ScriptOn,1);
  647.   @output_stream 2;
  648.   if (((0-->8) & 1) == 0) return L__M(##ScriptOn,3);
  649.   L__M(##ScriptOn,2); VersionSub();
  650.   transcript_mode = true;
  651. [ ScriptOffSub;
  652.   transcript_mode = ((0-->8) & 1);
  653.   if (transcript_mode == false) return L__M(##ScriptOff,1);
  654.   L__M(##ScriptOff,2);
  655.   @output_stream -2;
  656.   if ((0-->8) & 1) return L__M(##ScriptOff,3);
  657.   transcript_mode = false;
  658. [ NotifyOnSub; notify_mode=1; L__M(##NotifyOn); ];
  659. [ NotifyOffSub; notify_mode=0; L__M(##NotifyOff); ];
  660. [ Places1Sub i j k;
  661.   L__M(##Places);
  662.   objectloop(i has visited) j++;
  663.   objectloop(i has visited)
  664.   {   print (name) i; k++;
  665.       if (k==j) ".";
  666.       if (k==j-1) print (string) AND__TX; else print ", ";
  667. [ Objects1Sub i j f;
  668.   L__M(##Objects,1);
  669.   objectloop(i has moved)
  670.   {   f=1; print (the) i; j=parent(i);
  671.       if (j)
  672.       {   if (j==player)
  673.           {   if (i has worn) L__M(##Objects, 3);
  674.               else L__M(##Objects, 4);
  675.               jump obj__ptd;
  676.           }
  677.           if (j has animate)   { L__M(##Objects, 5); jump obj__ptd; }
  678.           if (j has visited)   { L__M(##Objects, 6, j); jump obj__ptd; }
  679.           if (j has container) { L__M(##Objects, 8, j); jump obj__ptd; }
  680.           if (j has supporter) { L__M(##Objects, 9, j); jump obj__ptd; }
  681.           if (j has enterable) { L__M(##Objects, 7, j); jump obj__ptd; }
  682.       }
  683.       L__M(##Objects, 10);
  684.       .obj__ptd; new_line;
  685.   if (f==0) L__M(##Objects,2);
  686. ! ----------------------------------------------------------------------------
  687. !   The scoring system
  688. ! ----------------------------------------------------------------------------
  689. [ ScoreSub;
  690.   L__M(##Score);
  691.   PrintRank();
  692. [ Achieved num;
  693.   if (task_done->num==0)
  694.   {   task_done->num=1;
  695.       score = score + task_scores->num;
  696. [ PANum m n;
  697.   print "  ";
  698.   n=m;
  699.   if (n<0)    { n=-m; n=n*10; }
  700.   if (n<10)   { print "   "; jump panuml; }
  701.   if (n<100)  { print "  "; jump panuml; }
  702.   if (n<1000) { print " "; }
  703. .panuml;
  704.   print m, " ";
  705. [ FullScoreSub i;
  706.   ScoreSub();
  707.   if (score==0 || TASKS_PROVIDED==1) rfalse;
  708.   new_line;
  709.   L__M(##FullScore,1);
  710.   for (i=0:i<NUMBER_TASKS:i++)
  711.       if (task_done->i==1)
  712.       {   PANum(task_scores->i);
  713.           PrintTaskName(i);
  714.       }
  715.   if (things_score~=0)
  716.   {   PANum(things_score); L__M(##FullScore,2); }
  717.   if (places_score~=0)
  718.   {   PANum(places_score); L__M(##FullScore,3); }
  719.   new_line; PANum(score); L__M(##FullScore,4);
  720. ! ----------------------------------------------------------------------------
  721. !   Real verbs start here: Inventory
  722. ! ----------------------------------------------------------------------------
  723. [ InvWideSub;
  724.   inventory_style = FULLINV_BIT + ENGLISH_BIT + RECURSE_BIT;
  725.   <Inv>;
  726. [ InvTallSub;
  727.   inventory_style = FULLINV_BIT + INDENT_BIT + NEWLINE_BIT + RECURSE_BIT;
  728.   <Inv>;
  729. [ InvSub x;
  730.   if (child(player)==0) return L__M(##Inv,1);
  731.   if (inventory_style==0) return InvTallSub();
  732.   L__M(##Inv,2);
  733.   if (inventory_style & NEWLINE_BIT ~= 0) print ":^"; else print " ";
  734.   WriteListFrom(child(player), inventory_style, 1);
  735.   if (inventory_style & ENGLISH_BIT ~= 0) print ".^";
  736. #IFNDEF MANUAL_PRONOUNS;
  737.   objectloop(x in player) PronounNotice(x);
  738. #ENDIF;
  739.   x = 0; ! To prevent a "not used" error
  740.   AfterRoutines();
  741. ! ----------------------------------------------------------------------------
  742. !   The object tree and determining the possibility of moves
  743. ! ----------------------------------------------------------------------------
  744. [ CommonAncestor o1 o2 i j;
  745.   !  Find the nearest object indirectly containing o1 and o2,
  746.   !  or return 0 if there is no common ancestor.
  747.   i = o1;
  748.   while (i ~= 0)
  749.       j = o2;
  750.       while (j ~= 0)
  751.       {   if (j == i) return i;
  752.           j = parent(j);
  753.       }
  754.       i = parent(i);
  755.   return 0;
  756. [ IndirectlyContains o1 o2;
  757.   !  Does o1 indirectly contain o2?  (Same as testing if their common
  758.   !  ancestor is o1.)
  759.   while (o2~=0)
  760.   {   if (o1==o2) rtrue;
  761.       o2=parent(o2);
  762.   rfalse;
  763. [ ObjectScopedBySomething item i j k l m;
  764.   i = item;
  765.   while (parent(i) ~= 0) i=parent(i);
  766.   objectloop (j .& add_to_scope)
  767.   {   l = j.&add_to_scope;
  768.       k = (j.#add_to_scope)/2;
  769.       if (l-->0 ofclass Routine) continue;
  770.       for (m=0:m<k:m++)
  771.           if (l-->m == i)
  772.               return j;
  773.   rfalse;
  774. [ ObjectIsUntouchable item flag1 flag2 ancestor i;
  775.   ! Determine if there's any barrier preventing the player from moving
  776.   ! things to "item".  Return false if no barrier; otherwise print a
  777.   ! suitable message and return true.
  778.   ! If flag1 is set, do not print any message.
  779.   ! If flag2 is set, also apply Take/Remove restrictions.
  780.   ! If the item has been added to scope by something, it's first necessary
  781.   ! for that something to be touchable.
  782.   i = ObjectScopedBySomething(item);
  783.   if (i ~= 0)
  784.   {   if (ObjectIsUntouchable(i)) return;
  785.       ! An item immediately added to scope
  786.   ancestor = CommonAncestor(player, item);
  787.   ! First, a barrier between the player and the ancestor.  The player
  788.   ! can only be in a sequence of enterable objects, and only closed
  789.   ! containers form a barrier.
  790.   if (player ~= ancestor)
  791.   {   i = parent(player);
  792.       while (i~=ancestor)
  793.       {   if (i has container && i hasnt open)
  794.           {   if (flag1) rtrue;
  795.               return L__M(##Take,9,i);
  796.           }
  797.           i = parent(i);
  798.       }
  799.   ! Second, a barrier between the item and the ancestor.  The item can
  800.   ! be carried by someone, part of a piece of machinery, in or on top
  801.   ! of something and so on.
  802.   if (item ~= ancestor)
  803.   {   i = parent(item);
  804.       while (i~=ancestor)
  805.       {   if (flag2 && i hasnt container && i hasnt supporter)
  806.           {   if (i has animate)
  807.               {   if (flag1) rtrue;
  808.                   return L__M(##Take,6,i);
  809.               }
  810.               if (i has transparent)
  811.               {   if (flag1) rtrue;
  812.                   return L__M(##Take,7,i);
  813.               }
  814.               if (flag1) rtrue;
  815.               return L__M(##Take,8,item);
  816.           }
  817.           if (i has container && i hasnt open)
  818.           {   if (flag1) rtrue;
  819.               return L__M(##Take,9,i);
  820.           }
  821.           i = parent(i);
  822.       }
  823.   rfalse;
  824. [ AttemptToTakeObject item     ancestor after_recipient i j k;
  825.   ! Try to transfer the given item to the player: return false
  826.   ! if successful, true if unsuccessful, printing a suitable message
  827.   ! in the latter case.
  828.   ! People cannot ordinarily be taken.
  829.   if (item == player) return L__M(##Take,2);
  830.   if (item has animate) return L__M(##Take,3,item);
  831.   ancestor = CommonAncestor(player, item);
  832.   if (ancestor == 0)
  833.   {   i = ObjectScopedBySomething(item);
  834.       if (i ~= 0) ancestor = CommonAncestor(player, i);
  835.   ! Are player and item in totally different places?
  836.   if (ancestor == 0) return L__M(##Take,8,item);
  837.   ! Is the player indirectly inside the item?
  838.   if (ancestor == item) return L__M(##Take,4,item);
  839.   ! Does the player already directly contain the item?
  840.   if (item in player) return L__M(##Take,5,item);
  841.   ! Can the player touch the item, or is there (e.g.) a closed container
  842.   ! in the way?
  843.   if (ObjectIsUntouchable(item,false,true)) return;
  844.   ! The item is now known to be accessible.
  845.   ! Consult the immediate possessor of the item, if it's in a container
  846.   ! which the player is not in.
  847.   i=parent(item);
  848.   if (i ~= ancestor && (i has container || i has supporter))
  849.   {   after_recipient=i;
  850.       k=action; action=##LetGo;
  851.       if (RunRoutines(i,before)~=0) { action=k; rtrue; }
  852.       action=k;
  853.   if (item has scenery) return L__M(##Take,10,item);
  854.   if (item has static)  return L__M(##Take,11,item);
  855.   ! The item is now known to be available for taking.  Is the player
  856.   ! carrying too much?  If so, possibly juggle items into the rucksack
  857.   ! to make room.
  858.   k=0; objectloop (j in player) if (j hasnt worn) k++;
  859.   if (k >= ValueOrRun(player,capacity))
  860.   {   if (SACK_OBJECT~=0)
  861.       {   if (parent(SACK_OBJECT)~=player)
  862.               return L__M(##Take,12);
  863.           j=0;
  864.           objectloop (k in player) 
  865.               if (k~=SACK_OBJECT && k hasnt worn && k hasnt light) j=k;
  866.           if (j~=0)
  867.           {   L__M(##Take,13,j);
  868.               keep_silent = 1; <Insert j SACK_OBJECT>; keep_silent = 0;
  869.               if (j notin SACK_OBJECT) rtrue;
  870.           }
  871.           else return L__M(##Take,12);
  872.       }
  873.       else return L__M(##Take,12);
  874.   ! Transfer the item.
  875.   move item to player;
  876.   ! Send "after" message to the object letting go of the item, if any.
  877.   if (after_recipient~=0)
  878.   {   k=action; action=##LetGo;
  879.       if (RunRoutines(after_recipient,after)~=0) { action=k; rtrue; }
  880.       action=k;
  881.   rfalse;
  882. ! ----------------------------------------------------------------------------
  883. !   Object movement verbs
  884. ! ----------------------------------------------------------------------------
  885. [ TakeSub;
  886.   if (onotheld_mode==0 || noun notin player)
  887.       if (AttemptToTakeObject(noun)) rtrue;
  888.   if (AfterRoutines()==1) rtrue;
  889.   notheld_mode=onotheld_mode;
  890.   if (notheld_mode==1 || keep_silent==1) rtrue;
  891.   L__M(##Take,1);
  892. [ RemoveSub i;
  893.   i=parent(noun);
  894.   if (i has container && i hasnt open) return L__M(##Remove,1,noun);
  895.   if (i~=second) return L__M(##Remove,2,noun);
  896.   if (i has animate) return L__M(##Take,6,i);
  897.   if (AttemptToTakeObject(noun)) rtrue;
  898.   action=##Take;   if (AfterRoutines()==1) rtrue;
  899.   action=##Remove; if (AfterRoutines()==1) rtrue;
  900.   if (keep_silent==1) rtrue;
  901.   return L__M(##Remove,3,noun);
  902. [ DropSub;
  903.   if (noun == player) return L__M(##PutOn, 4);
  904.   if (noun in parent(player)) return L__M(##Drop,1,noun);
  905.   if (noun notin player) return L__M(##Drop,2,noun);
  906.   if (noun has worn)
  907.   {   L__M(##Drop,3,noun);
  908.       <Disrobe noun>;
  909.       if (noun has worn && noun in player) rtrue;
  910.   move noun to parent(player);
  911.   if (AfterRoutines()==1) rtrue;
  912.   if (keep_silent==1) rtrue;
  913.   return L__M(##Drop,4,noun);
  914. [ PutOnSub ancestor;
  915.   receive_action=##PutOn; 
  916.   if (second == d_obj || player in second) <<Drop noun>>;
  917.   if (parent(noun)~=player) return L__M(##PutOn,1,noun);
  918.   ancestor = CommonAncestor(noun, second);
  919.   if (ancestor == noun) return L__M(##PutOn,2,noun);
  920.   if (ObjectIsUntouchable(second)) return;
  921.   if (second ~= ancestor)
  922.   {   action=##Receive;
  923.       if (RunRoutines(second,before)~=0) { action=##PutOn; return; }
  924.       action=##PutOn;
  925.   if (second hasnt supporter) return L__M(##PutOn,3,second);
  926.   if (ancestor == player) return L__M(##PutOn,4);
  927.   if (noun has worn)
  928.   {   L__M(##PutOn,5,noun); <Disrobe noun>; if (noun has worn) return;
  929.   if (children(second)>=ValueOrRun(second,capacity))
  930.       return L__M(##PutOn,6,second);
  931.   move noun to second;
  932.   if (AfterRoutines()==1) return;
  933.   if (second ~= ancestor)
  934.   {   action=##Receive;
  935.       if (RunRoutines(second,after)~=0) { action=##PutOn; return; }
  936.       action=##PutOn;
  937.   if (keep_silent==1) return;
  938.   if (multiflag==1) return L__M(##PutOn,7);
  939.   L__M(##PutOn,8,noun);
  940. [ InsertSub ancestor;
  941.   receive_action = ##Insert;
  942.   if (second==d_obj || player in second) <<Drop noun>>;
  943.   if (parent(noun)~=player) return L__M(##Insert,1,noun);
  944.   ancestor = CommonAncestor(noun, second);
  945.   if (ancestor == noun) return L__M(##Insert, 5, noun);
  946.   if (ObjectIsUntouchable(second)) return;
  947.   if (second ~= ancestor)
  948.   {   action=##Receive;
  949.       if (RunRoutines(second,before)~=0) { action=##Insert; rtrue; }
  950.       action=##Insert;
  951.       if (second has container && second hasnt open)
  952.           return L__M(##Insert,3,second);
  953.   if (second hasnt container) return L__M(##Insert,2,second);
  954.   if (noun has worn)
  955.   {   L__M(##Insert,6,noun); <Disrobe noun>; if (noun has worn) return;
  956.   if (children(second) >= ValueOrRun(second,capacity))
  957.       return L__M(##Insert,7,second);
  958.   move noun to second;
  959.   if (AfterRoutines()==1) rtrue;
  960.   if (second ~= ancestor)
  961.   {   action=##Receive;
  962.       if (RunRoutines(second,after)~=0) { action=##Insert; rtrue; }
  963.       action=##Insert;
  964.   if (keep_silent==1) rtrue;
  965.   if (multiflag==1) return L__M(##Insert,8,noun);
  966.   L__M(##Insert,9,noun);
  967. ! ----------------------------------------------------------------------------
  968. !   Empties and transfers are routed through the actions above
  969. ! ----------------------------------------------------------------------------
  970. [ TransferSub;
  971.   if (noun notin player && AttemptToTakeObject(noun)) return;
  972.   if (second has supporter) <<PutOn noun second>>;
  973.   if (second == d_obj) <<Drop noun>>;
  974.   <<Insert noun second>>;
  975. [ EmptySub;
  976.   second=d_obj; EmptyTSub();
  977. [ EmptyTSub i j k flag;
  978.   if (noun == second) return L__M(##EmptyT,4);
  979.   if (ObjectIsUntouchable(noun)) return;
  980.   if (noun hasnt container) return L__M(##EmptyT,1,noun);
  981.   if (noun hasnt open) return L__M(##EmptyT,2,noun);
  982.   if (second~=d_obj)
  983.   {   if (second hasnt supporter)
  984.       {   if (second hasnt container) return L__M(##EmptyT,1,second);
  985.           if (second hasnt open) return L__M(##EmptyT,2,second);
  986.       }
  987.   i=child(noun); k = children(noun);
  988.   if (i==0) return L__M(##EmptyT,3,noun);
  989.   while (i~=0)
  990.   {   j=sibling(i);
  991.       flag = 0;
  992.       if (ObjectIsUntouchable(noun)) flag = 1;
  993.       if (noun hasnt container) flag = 1;
  994.       if (noun hasnt open) flag = 1;
  995.       if (second~=d_obj)
  996.       {   if (second hasnt supporter)
  997.           {   if (second hasnt container) flag = 1;
  998.               if (second hasnt open) flag = 1;
  999.           }
  1000.       }
  1001.       if (k-- == 0) flag = 1;
  1002.       if (flag) break;
  1003.       if (keep_silent == 0) print (name) i, ": ";
  1004.       <Transfer i second>;
  1005.       i=j;
  1006. ! ----------------------------------------------------------------------------
  1007. !   Gifts
  1008. ! ----------------------------------------------------------------------------
  1009. [ GiveSub;
  1010.   if (parent(noun)~=player) return L__M(##Give,1,noun);
  1011.   if (second==player)  return L__M(##Give,2,noun);
  1012.   if (RunLife(second,##Give)~=0) rfalse;
  1013.   L__M(##Give,3,second);
  1014. [ GiveRSub; <Give second noun>; ];
  1015. [ ShowSub;
  1016.   if (parent(noun)~=player) return L__M(##Show,1,noun);
  1017.   if (second==player) <<Examine noun>>;
  1018.   if (RunLife(second,##Show)~=0) rfalse;
  1019.   L__M(##Show,2,second);
  1020. [ ShowRSub; <Show second noun>; ];
  1021. ! ----------------------------------------------------------------------------
  1022. !   Travelling around verbs
  1023. ! ----------------------------------------------------------------------------
  1024. [ EnterSub ancestor j k;
  1025.   if (noun has door || noun in compass) <<Go noun>>;
  1026.   if (player in noun) return L__M(##Enter,1,noun);
  1027.   if (noun hasnt enterable) return L__M(##Enter,2,noun);
  1028.   if (noun has container && noun hasnt open) return L__M(##Enter,3,noun);
  1029.   if (parent(player) ~= parent(noun))
  1030.   {   ancestor = CommonAncestor(player, noun);
  1031.       if (ancestor == player or 0) return L__M(##Enter,4,noun);
  1032.       while (player notin ancestor)
  1033.       {   j = parent(player);
  1034.           k = keep_silent; 
  1035.           if (parent(j) ~= ancestor || noun ~= ancestor)
  1036.           {   L__M(##Enter,6,j);
  1037.               keep_silent = 1;
  1038.           }
  1039.           <Exit>;
  1040.           keep_silent = k;
  1041.           if (player in j) return;
  1042.       }
  1043.       if (player in noun) return;
  1044.       if (noun notin ancestor)
  1045.       {   j = parent(noun);
  1046.           while (parent(j) ~= ancestor) j = parent(j);
  1047.           L__M(##Enter,7,j);
  1048.           k = keep_silent; keep_silent = 1;
  1049.           <Enter j>;
  1050.           keep_silent = k;
  1051.           if (player notin j) return;
  1052.           <<Enter noun>>;
  1053.       }
  1054.   move player to noun;
  1055.   if (AfterRoutines()==1) rtrue;
  1056.   if (keep_silent==1) rtrue;
  1057.   L__M(##Enter,5,noun);
  1058.   Locale(noun);
  1059. [ GetOffSub;
  1060.   if (parent(player)==noun) <<Exit>>;
  1061.   L__M(##GetOff,1,noun);
  1062. [ ExitSub p;
  1063.   p=parent(player);
  1064.   if (p==location || (location==thedark && p==real_location))
  1065.   {   if ((location.out_to~=0)
  1066.           || (location==thedark && real_location.out_to~=0)) <<Go out_obj>>;
  1067.       return L__M(##Exit,1);
  1068.   if (p has container && p hasnt open)
  1069.       return L__M(##Exit,2,p);
  1070.   move player to parent(p);
  1071.   if (AfterRoutines()==1) rtrue;
  1072.   if (keep_silent==1) rtrue;
  1073.   L__M(##Exit,3,p); LookSub(1);
  1074. [ VagueGoSub; L__M(##VagueGo); ];
  1075. [ GoInSub;
  1076.   <<Go in_obj>>;
  1077. [ GoSub i j k df movewith thedir old_loc;
  1078.   if (second ~= 0 && second notin Compass
  1079.       && ObjectIsUntouchable(second)) return;
  1080.   old_loc = location;
  1081.   movewith=0;
  1082.   i=parent(player);
  1083.   if ((location~=thedark && i~=location)
  1084.       || (location==thedark && i~=real_location))
  1085.   {   j=location;
  1086.       if (location==thedark) location=real_location;
  1087.       k=RunRoutines(i,before); if (k~=3) location=j;
  1088.       if (k==1)
  1089.       {   movewith=i; i=parent(i);
  1090.       }
  1091.       else
  1092.       {   if (k==0) L__M(##Go,1,i);
  1093.           rtrue;
  1094.       }
  1095.   thedir=noun.door_dir;
  1096.   if (ZRegion(thedir)==2) thedir=RunRoutines(noun,door_dir);
  1097.   j=i.thedir; k=ZRegion(j);
  1098.   if (k==3) { print (string) j; new_line; rfalse; }
  1099.   if (k==2) { j=RunRoutines(i,thedir);
  1100.               if (j==1) rtrue;
  1101.             }
  1102.   if (k==0 || j==0)
  1103.   {   if (i.cant_go ~= 0) PrintOrRun(i, cant_go);
  1104.       rfalse;
  1105.   if (j has door)
  1106.   {   if (j has concealed) return L__M(##Go,2);
  1107.       if (j hasnt open)
  1108.       {   if (noun==u_obj) return L__M(##Go,3,j);
  1109.           if (noun==d_obj) return L__M(##Go,4,j);
  1110.           return L__M(##Go,5,j);
  1111.       }
  1112.       k=RunRoutines(j,door_to);
  1113.       if (k==0) return L__M(##Go,6,j);
  1114.       if (k==1) rtrue;
  1115.       j = k;
  1116.   if (movewith==0) move player to j; else move movewith to j;
  1117.   location=j; MoveFloatingObjects();
  1118.   df=OffersLight(j);
  1119.   if (df~=0) { location=j; lightflag=1; }
  1120.   else
  1121.   {   if (old_loc == thedark)
  1122.       {   DarkToDark();
  1123.           if (deadflag~=0) rtrue;
  1124.       }
  1125.       real_location=j;
  1126.       location=thedark; lightflag=0;
  1127.   if (AfterRoutines()==1) rtrue;
  1128.   if (keep_silent==1) rtrue;
  1129.   LookSub(1);
  1130. ! ----------------------------------------------------------------------------
  1131. !   Describing the world.  SayWhatsOn(object) does just that (producing
  1132. !   no text if nothing except possibly "scenery" and "concealed" items are).
  1133. !   Locale(object) runs through the "tail end" of a Look-style room
  1134. !   description for the contents of the object, printing up suitable
  1135. !   descriptions as it goes.
  1136. ! ----------------------------------------------------------------------------
  1137. [ SayWhatsOn descon j f;
  1138.   if (descon==parent(player)) rfalse;
  1139.   objectloop (j in descon)
  1140.       if (j hasnt concealed && j hasnt scenery) f=1;
  1141.   if (f==0) rfalse;
  1142.   L__M(##Look, 4, descon); rtrue;
  1143. [ NotSupportingThePlayer o i;
  1144.   i=parent(player);
  1145.   while (i~=0 && i~=visibility_ceiling)
  1146.   {   if (i==o) rfalse;
  1147.       i = parent(i);
  1148.       if (i~=0 && i hasnt supporter) rtrue;
  1149.   rtrue;
  1150. [ Locale descin text1 text2 o k p j f2 flag;
  1151.   objectloop (o in descin) give o ~workflag;
  1152.   k=0;
  1153.   objectloop (o in descin)
  1154.       if (o hasnt concealed && NotSupportingThePlayer(o))
  1155.       {  #IFNDEF MANUAL_PRONOUNS;
  1156.          PronounNotice(o);
  1157.          #ENDIF;
  1158.          if (o hasnt scenery)
  1159.          {   give o workflag; k++;
  1160.              p=initial; f2=0;
  1161.              if ((o has door || o has container)
  1162.                  && o has open && o provides when_open)
  1163.              {   p = when_open; f2 = 1; jump Prop_Chosen; }
  1164.              if ((o has door || o has container)
  1165.                  && o hasnt open && o provides when_closed)
  1166.              {   p = when_closed; f2 = 1; jump Prop_Chosen; }
  1167.              if (o has switchable
  1168.                  && o has on && o provides when_on)
  1169.              {   p = when_on; f2 = 1; jump Prop_Chosen; }
  1170.              if (o has switchable
  1171.                  && o hasnt on && o provides when_off)
  1172.              {   p = when_off; f2 = 1; }
  1173.              .Prop_Chosen;
  1174.              if (o hasnt moved || o.describe~=NULL || f2==1)
  1175.              {   if (o.describe~=NULL && RunRoutines(o,describe)~=0)
  1176.                  {   flag=1;
  1177.                      give o ~workflag; k--;
  1178.                  }    
  1179.                  else
  1180.                  {   j=o.p;
  1181.                      if (j~=0)
  1182.                      {   new_line;
  1183.                          PrintOrRun(o,p);
  1184.                          flag=1;
  1185.                          give o ~workflag; k--;
  1186.                          if (o has supporter && child(o)~=0) SayWhatsOn(o);
  1187.                      }
  1188.                  }
  1189.              }
  1190.          }
  1191.          else
  1192.              if (o has supporter && child(o)~=0) SayWhatsOn(o);
  1193.       }
  1194.   if (k==0) return 0;
  1195.   if (text1~=0)
  1196.   {   new_line;
  1197.       if (flag==1) text1=text2;
  1198.       print (string) text1, " ";
  1199.       WriteListFrom(child(descin),
  1200.           ENGLISH_BIT + WORKFLAG_BIT + RECURSE_BIT
  1201.           + PARTINV_BIT + TERSE_BIT + CONCEAL_BIT);
  1202.       return k;
  1203.            
  1204.   if (flag==1) L__M(##Look,5,descin); else L__M(##Look,6,descin);
  1205. ! ----------------------------------------------------------------------------
  1206. !   Looking.  LookSub(1) is allowed to abbreviate long descriptions, but
  1207. !     LookSub(0) (which is what happens when the Look action is generated)
  1208. !     isn't.  (Except that these are over-ridden by the player-set lookmode.)
  1209. ! ----------------------------------------------------------------------------
  1210. [ LMode1Sub; lookmode=1; print (string) Story; L__M(##LMode1); ];  ! Brief
  1211. [ LMode2Sub; lookmode=2; print (string) Story; L__M(##LMode2); ];  ! Verbose
  1212. [ LMode3Sub; lookmode=3; print (string) Story; L__M(##LMode3); ];  ! Superbrief
  1213. [ NoteArrival descin;
  1214.   if (location==thedark) { lastdesc = thedark; return; }
  1215.   if (location~=lastdesc)
  1216.   {   if (location.initial~=0) PrintOrRun(location, initial);
  1217.       descin = location;
  1218.       NewRoom();
  1219.       lastdesc = descin;
  1220. [ ScoreArrival;
  1221.   if (location hasnt visited)
  1222.   {   give location visited;
  1223.       if (location has scored)
  1224.       {   score = score + ROOM_SCORE;
  1225.           places_score = places_score + ROOM_SCORE;
  1226.       }
  1227. [ FindVisibilityLevels visibility_levels;
  1228.   visibility_levels = 1;
  1229.   visibility_ceiling = parent(player);
  1230.   while ((parent(visibility_ceiling) ~= 0)
  1231.          && (visibility_ceiling hasnt container
  1232.              || visibility_ceiling has open
  1233.              || visibility_ceiling has transparent))
  1234.   {   visibility_ceiling = parent(visibility_ceiling);
  1235.       visibility_levels++;
  1236.   }      
  1237.   return visibility_levels;
  1238. [ LookSub allow_abbrev  visibility_levels i j k;
  1239.   if (parent(player)==0) return RunTimeError(10);
  1240.   .MovedByInitial;
  1241.   if (location == thedark) { visibility_ceiling = thedark; NoteArrival(); }
  1242.   else
  1243.   {   visibility_levels = FindVisibilityLevels();
  1244.       if (visibility_ceiling == location)
  1245.       {   NoteArrival();
  1246.           if (visibility_ceiling ~= location) jump MovedByInitial;
  1247.       }
  1248.   !   Printing the top line: e.g.
  1249.   !   Octagonal Room (on the table) (as Frodo)
  1250.   new_line;
  1251.   style bold;
  1252.   if (visibility_levels == 0) print (name) thedark;
  1253.   else
  1254.   {   if (visibility_ceiling ~= location) print (The) visibility_ceiling;
  1255.       else print (name) visibility_ceiling;
  1256.   style roman;
  1257.   for (j=1, i=parent(player):j<visibility_levels:j++, i=parent(i))
  1258.       if (i has supporter) L__M(##Look,1,i);
  1259.                       else L__M(##Look,2,i);
  1260.   if (print_player_flag==1) L__M(##Look,3,player);
  1261.   new_line;
  1262.   !   The room description (if visible)
  1263.   if (lookmode<3 && visibility_ceiling==location)
  1264.   {   if ((allow_abbrev~=1) || (lookmode==2) || (location hasnt visited))
  1265.       {   if (location.describe~=NULL) RunRoutines(location,describe);
  1266.           else
  1267.           {   if (location.description==0) RunTimeError(11,location);
  1268.               else PrintOrRun(location,description);
  1269.           }
  1270.       }
  1271.   if (visibility_levels == 0) Locale(thedark);
  1272.   else
  1273.   {   for (i=player, j=visibility_levels: j>0: j--, i=parent(i))
  1274.           give i workflag;
  1275.       
  1276.       for (j=visibility_levels: j>0: j--)
  1277.       {   for (i=player, k=0: k<j: k++) i=parent(i);
  1278.           if (i.inside_description~=0)
  1279.           {   new_line; PrintOrRun(i,inside_description); }
  1280.           Locale(i);
  1281.       }
  1282.   LookRoutine();
  1283.   ScoreArrival();
  1284.   action=##Look;
  1285.   if (AfterRoutines()==1) rtrue;
  1286. [ ExamineSub i;
  1287.   if (location==thedark) return L__M(##Examine,1);
  1288.   i=noun.description;
  1289.   if (i==0)
  1290.   {   if (noun has container) <<Search noun>>;
  1291.       if (noun has switchable) { L__M(##Examine,3,noun); rfalse; }
  1292.       return L__M(##Examine,2,noun);
  1293.   PrintOrRun(noun, description);
  1294.   if (noun has switchable) L__M(##Examine,3,noun);
  1295.   if (AfterRoutines()==1) rtrue;
  1296. [ LookUnderSub;
  1297.   if (location==thedark) return L__M(##LookUnder,1);
  1298.   L__M(##LookUnder,2);
  1299. [ SearchSub i f;
  1300.   if (location==thedark) return L__M(##Search,1,noun);
  1301.   if (ObjectIsUntouchable(noun)) return;
  1302.   objectloop (i in noun) if (i hasnt concealed && i hasnt scenery) f=1;
  1303.   if (noun has supporter)
  1304.   {   if (f==0) return L__M(##Search,2,noun);
  1305.       return L__M(##Search,3,noun);
  1306.   if (noun hasnt container) return L__M(##Search,4,noun);
  1307.   if (noun hasnt transparent && noun hasnt open)
  1308.       return L__M(##Search,5,noun);
  1309.   if (AfterRoutines()==1) rtrue;
  1310.   i=children(noun);
  1311.   if (f==0) return L__M(##Search,6,noun);
  1312.   L__M(##Search,7,noun);
  1313. ! ----------------------------------------------------------------------------
  1314. !   Verbs which change the state of objects without moving them
  1315. ! ----------------------------------------------------------------------------
  1316. [ UnlockSub;
  1317.   if (ObjectIsUntouchable(noun)) return;
  1318.   if (noun hasnt lockable) return L__M(##Unlock,1,noun);
  1319.   if (noun hasnt locked)   return L__M(##Unlock,2,noun);
  1320.   if (noun.with_key~=second) return L__M(##Unlock,3,second);
  1321.   give noun ~locked;
  1322.   if (AfterRoutines()==1) rtrue;
  1323.   if (keep_silent==1) rtrue;
  1324.   L__M(##Unlock,4,noun);
  1325. [ LockSub;
  1326.   if (ObjectIsUntouchable(noun)) return;
  1327.   if (noun hasnt lockable) return L__M(##Lock,1,noun);
  1328.   if (noun has locked)     return L__M(##Lock,2,noun);
  1329.   if (noun has open)       return L__M(##Lock,3,noun);
  1330.   if (noun.with_key~=second) return L__M(##Lock,4,second);
  1331.   give noun locked;
  1332.   if (AfterRoutines()==1) rtrue;
  1333.   if (keep_silent==1) rtrue;
  1334.   L__M(##Lock,5,noun);
  1335. [ SwitchonSub;
  1336.   if (ObjectIsUntouchable(noun)) return;
  1337.   if (noun hasnt switchable) return L__M(##SwitchOn,1,noun);
  1338.   if (noun has on) return L__M(##SwitchOn,2,noun);
  1339.   give noun on;
  1340.   if (AfterRoutines()==1) rtrue;
  1341.   if (keep_silent==1) rtrue;
  1342.   L__M(##SwitchOn,3,noun);
  1343. [ SwitchoffSub;
  1344.   if (ObjectIsUntouchable(noun)) return;
  1345.   if (noun hasnt switchable) return L__M(##SwitchOff,1,noun);
  1346.   if (noun hasnt on) return L__M(##SwitchOff,2,noun);
  1347.   give noun ~on;
  1348.   if (AfterRoutines()==1) rtrue;
  1349.   if (keep_silent==1) rtrue;
  1350.   L__M(##SwitchOff,3,noun);
  1351. [ OpenSub;
  1352.   if (ObjectIsUntouchable(noun)) return;
  1353.   if (noun hasnt openable) return L__M(##Open,1,noun);
  1354.   if (noun has locked)     return L__M(##Open,2,noun);
  1355.   if (noun has open)       return L__M(##Open,3,noun);
  1356.   give noun open;
  1357.   if (AfterRoutines()==1) rtrue;
  1358.   if (keep_silent==1) rtrue;
  1359.   if (noun has container && noun hasnt transparent && child(noun)~=0
  1360.       && IndirectlyContains(noun,player)==0)
  1361.       return L__M(##Open,4,noun);
  1362.   L__M(##Open,5,noun);
  1363. [ CloseSub;
  1364.   if (ObjectIsUntouchable(noun)) return;
  1365.   if (noun hasnt openable) return L__M(##Close,1,noun);
  1366.   if (noun hasnt open)     return L__M(##Close,2,noun);
  1367.   give noun ~open;
  1368.   if (AfterRoutines()==1) rtrue;
  1369.   if (keep_silent==1) rtrue;
  1370.   L__M(##Close,3,noun);
  1371. [ DisrobeSub;
  1372.   if (ObjectIsUntouchable(noun)) return;
  1373.   if (noun hasnt worn) return L__M(##Disrobe,1,noun);
  1374.   give noun ~worn;
  1375.   if (AfterRoutines()==1) rtrue;
  1376.   if (keep_silent==1) rtrue;
  1377.   L__M(##Disrobe,2,noun);
  1378. [ WearSub;
  1379.   if (ObjectIsUntouchable(noun)) return;
  1380.   if (noun hasnt clothing)  return L__M(##Wear,1,noun);
  1381.   if (parent(noun)~=player) return L__M(##Wear,2,noun);
  1382.   if (noun has worn)        return L__M(##Wear,3,noun);
  1383.   give noun worn;
  1384.   if (AfterRoutines()==1) rtrue;
  1385.   if (keep_silent==1) rtrue;
  1386.   L__M(##Wear,4,noun);
  1387. [ EatSub;
  1388.   if (ObjectIsUntouchable(noun)) return;
  1389.   if (noun hasnt edible) return L__M(##Eat,1,noun);
  1390.   if (noun has worn)
  1391.   {   L__M(##Drop,3,noun);
  1392.       <Disrobe noun>;
  1393.       if (noun has worn && noun in player) rtrue;
  1394.   remove noun;
  1395.   if (AfterRoutines()==1) rtrue;
  1396.   if (keep_silent==1) rtrue;
  1397.   L__M(##Eat,2,noun);
  1398. ! ----------------------------------------------------------------------------
  1399. !   Verbs which are really just stubs (anything which happens for these
  1400. !   actions must happen in before rules)
  1401. ! ----------------------------------------------------------------------------
  1402. [ YesSub; L__M(##Yes); ];
  1403. [ NoSub; L__M(##No); ];
  1404. [ BurnSub; L__M(##Burn,1,noun); ];
  1405. [ PraySub; L__M(##Pray,1,noun); ];
  1406. [ WakeSub; L__M(##Wake,1,noun); ];
  1407. [ WakeOtherSub;
  1408.   if (ObjectIsUntouchable(noun)) return;
  1409.   if (RunLife(noun,##WakeOther)~=0) rfalse;
  1410.   L__M(##WakeOther,1,noun);
  1411. [ ThinkSub; L__M(##Think,1,noun); ];
  1412. [ SmellSub; L__M(##Smell,1,noun); ];
  1413. [ ListenSub; L__M(##Listen,1,noun); ];
  1414. [ TasteSub; L__M(##Taste,1,noun); ];
  1415. [ DigSub; L__M(##Dig,1,noun); ];
  1416. [ CutSub; L__M(##Cut,1,noun); ];
  1417. [ JumpSub; L__M(##Jump,1,noun); ];
  1418. [ JumpOverSub; L__M(##JumpOver,1,noun); ];
  1419. [ TieSub; L__M(##Tie,1,noun); ];
  1420. [ DrinkSub; L__M(##Drink,1,noun); ];
  1421. [ FillSub; L__M(##Fill,1,noun); ];
  1422. [ SorrySub; L__M(##Sorry,1,noun); ];
  1423. [ StrongSub; L__M(##Strong,1,noun); ];
  1424. [ MildSub; L__M(##Mild,1,noun); ];
  1425. [ SwimSub; L__M(##Swim,1,noun); ];
  1426. [ SwingSub; L__M(##Swing,1,noun); ];
  1427. [ BlowSub; L__M(##Blow,1,noun); ];
  1428. [ RubSub; L__M(##Rub,1,noun); ];
  1429. [ SetSub; L__M(##Set,1,noun); ];
  1430. [ SetToSub; L__M(##SetTo,1,noun); ];
  1431. [ WaveHandsSub; L__M(##WaveHands,1,noun); ];
  1432. [ BuySub; L__M(##Buy,1,noun); ];
  1433. [ SingSub; L__M(##Sing,1,noun); ];
  1434. [ ClimbSub; L__M(##Climb,1,noun); ];
  1435. [ SleepSub; L__M(##Sleep,1,noun); ];
  1436. [ ConsultSub; L__M(##Consult,1,noun); ];
  1437. [ TouchSub;
  1438.   if (noun==player) return L__M(##Touch,3,noun);
  1439.   if (ObjectIsUntouchable(noun)) return;
  1440.   if (noun has animate) return L__M(##Touch,1,noun);
  1441.   L__M(##Touch,2,noun); ];
  1442. [ WaveSub;
  1443.   if (parent(noun)~=player) return L__M(##Wave,1,noun);
  1444.   L__M(##Wave,2,noun); ];
  1445. [ PullSub;
  1446.   if (ObjectIsUntouchable(noun)) return;
  1447.   if (noun has static)   return L__M(##Pull,1,noun);
  1448.   if (noun has scenery)  return L__M(##Pull,2,noun);
  1449.   if (noun has animate)  return L__M(##Pull,4,noun);
  1450.   L__M(##Pull,3,noun);
  1451. [ PushSub;
  1452.   if (ObjectIsUntouchable(noun)) return;
  1453.   if (noun has static)   return L__M(##Push,1,noun);
  1454.   if (noun has scenery)  return L__M(##Push,2,noun);
  1455.   if (noun has animate)  return L__M(##Pull,4,noun);
  1456.   L__M(##Push,3,noun);
  1457. [ TurnSub;
  1458.   if (ObjectIsUntouchable(noun)) return;
  1459.   if (noun has static)   return L__M(##Turn,1,noun);
  1460.   if (noun has scenery)  return L__M(##Turn,2,noun);
  1461.   if (noun has animate)  return L__M(##Pull,4,noun);
  1462.   L__M(##Turn,3,noun);
  1463. [ WaitSub;
  1464.   if (AfterRoutines()==1) rtrue;
  1465.   L__M(##Wait,1,noun);
  1466. [ PushDirSub; L__M(##PushDir,1,noun); ];
  1467. [ AllowPushDir i;
  1468.   if (parent(second)~=compass) return L__M(##PushDir,2,noun);
  1469.   if (second==u_obj or d_obj)  return L__M(##PushDir,3,noun);
  1470.   AfterRoutines(); i=noun; move i to player;
  1471.   <Go second>;
  1472.   if (location==thedark) move i to real_location;
  1473.   else move i to location;
  1474. [ SqueezeSub;
  1475.   if (ObjectIsUntouchable(noun)) return;
  1476.   if (noun has animate) return L__M(##Squeeze,1,noun);
  1477.   L__M(##Squeeze,2,noun);
  1478. [ ThrowAtSub;
  1479.   if (ObjectIsUntouchable(noun)) return;
  1480.   if (second>1)
  1481.   {   action=##ThrownAt;
  1482.       if (RunRoutines(second,before)~=0) { action=##ThrowAt; rtrue; }
  1483.       action=##ThrowAt;
  1484.   if (noun has worn)
  1485.   {   L__M(##Drop,3,noun);
  1486.       <Disrobe noun>;
  1487.       if (noun has worn && noun in player) rtrue;
  1488.   if (second hasnt animate) return L__M(##ThrowAt,1);
  1489.   if (RunLife(second,##ThrowAt)~=0) rfalse;
  1490.   L__M(##ThrowAt,2,noun);
  1491. [ AttackSub;
  1492.   if (ObjectIsUntouchable(noun)) return;
  1493.   if (noun has animate && RunLife(noun,##Attack)~=0) rfalse;
  1494.   L__M(##Attack,1,noun); ];
  1495. [ KissSub;
  1496.   if (ObjectIsUntouchable(noun)) return;
  1497.   if (RunLife(noun,##Kiss)~=0) rfalse;
  1498.   if (noun==player) return L__M(##Touch,3,noun);
  1499.   L__M(##Kiss,1,noun);
  1500. [ AnswerSub;
  1501.   if (second~=0 && RunLife(second,##Answer)~=0) rfalse;
  1502.   L__M(##Answer,1,noun);
  1503. [ TellSub;
  1504.   if (noun==player) return L__M(##Tell,1,noun);
  1505.   if (RunLife(noun,##Tell)~=0) rfalse;
  1506.   L__M(##Tell,2,noun);
  1507. [ AskSub;
  1508.   if (RunLife(noun,##Ask)~=0) rfalse;
  1509.   L__M(##Ask,1,noun);
  1510. [ AskForSub;
  1511.   if (noun==player) <<Inv>>;
  1512.   L__M(##Order,1,noun);
  1513. ! ----------------------------------------------------------------------------
  1514. !   Debugging verbs
  1515. ! ----------------------------------------------------------------------------
  1516. #IFDEF DEBUG;
  1517. [ TraceOnSub; parser_trace=1; "[Trace on.]"; ];
  1518. [ TraceLevelSub; parser_trace=noun;
  1519.   print "[Parser tracing set to level ", parser_trace, ".]^"; ];
  1520. [ TraceOffSub; parser_trace=0; "Trace off."; ];
  1521. [ RoutinesOnSub;  debug_flag=debug_flag | 1; "[Message listing on.]"; ];
  1522. [ RoutinesOffSub; debug_flag=debug_flag & 14; "[Message listing off.]"; ];
  1523. [ ActionsOnSub;  debug_flag=debug_flag | 2; "[Action listing on.]"; ];
  1524. [ ActionsOffSub; debug_flag=debug_flag & 13; "[Action listing off.]"; ];
  1525. [ TimersOnSub;  debug_flag=debug_flag | 4; "[Timers listing on.]"; ];
  1526. [ TimersOffSub; debug_flag=debug_flag & 11; "[Timers listing off.]"; ];
  1527. IFDEF VN_1610;
  1528. [ ChangesOnSub;  debug_flag=debug_flag | 8; "[Changes listing on.]"; ];
  1529. [ ChangesOffSub; debug_flag=debug_flag & 7; "[Changes listing off.]"; ];
  1530. IFNOT;
  1531. [ ChangesOnSub; "[Changes listing only available under Inform 6.2.]"; ];
  1532. [ ChangesOffSub; "[Changes listing only available under Inform 6.2.]"; ];
  1533. ENDIF;
  1534. [ CommandsOnSub;
  1535.   @output_stream 4; xcommsdir=1; "[Command recording on.]"; ];
  1536. [ CommandsOffSub;
  1537.   if (xcommsdir==1) @output_stream -4;
  1538.   xcommsdir=0;
  1539.   "[Command recording off.]"; ];
  1540. [ CommandsReadSub;
  1541.   @input_stream 1; xcommsdir=2; "[Replaying commands.]"; ];
  1542. [ PredictableSub i; i=random(-100);
  1543.   "[Random number generator now predictable.]"; ];
  1544. [ XTestMove obj dest;
  1545.   if ((obj<=InformLibrary) || (obj == LibraryMessages) || (obj in 1))
  1546.      "[Can't move ", (name) obj, ": it's a system object.]";
  1547.   while (dest ~= 0)
  1548.   {   if (dest == obj)
  1549.           "[Can't move ", (name) obj, ": it would contain itself.]";
  1550.       dest = parent(dest);
  1551.   rfalse;
  1552. [ XPurloinSub;
  1553.   if (XTestMove(noun,player)) return;
  1554.   move noun to player; give noun moved ~concealed;
  1555.   "[Purloined.]"; ];
  1556. [ XAbstractSub;
  1557.   if (XTestMove(noun,second)) return;
  1558.   move noun to second; "[Abstracted.]"; ];
  1559. [ XObj obj f;
  1560.   if (parent(obj) == 0) print (name) obj; else print (a) obj;
  1561.   print " (", obj, ") ";
  1562.   if (f==1 && parent(obj) ~= 0)
  1563.       print "(in ", (name) parent(obj), " ", parent(obj), ")";
  1564.   new_line;
  1565.   if (child(obj)==0) rtrue;
  1566.   if (obj == Class)
  1567.       WriteListFrom(child(obj),
  1568.       NOARTICLE_BIT + INDENT_BIT + NEWLINE_BIT + ALWAYS_BIT, 1);
  1569.   else
  1570.       WriteListFrom(child(obj),
  1571.       FULLINV_BIT + INDENT_BIT + NEWLINE_BIT + ALWAYS_BIT, 1);
  1572. [ XTreeSub i;
  1573.   if (noun==0)
  1574.   {   objectloop(i) if (i ofclass Object && parent(i)==0) XObj(i);
  1575.   else XObj(noun,1);
  1576. [ GotoSub;
  1577.   if (~~(noun ofclass Object) || (parent(noun)~=0)) "[Not a safe place.]";
  1578.   PlayerTo(noun);
  1579. [ GonearSub x; x=noun; while (parent(x)~=0) x=parent(x); PlayerTo(x); ];
  1580. [ Print_ScL obj; print_ret ++x_scope_count, ": ", (a) obj, " (", obj, ")"; ];
  1581. [ ScopeSub; x_scope_count=0; LoopOverScope(#r$Print_ScL, noun);
  1582.   if (x_scope_count==0) "Nothing is in scope.";
  1583. #ENDIF;
  1584. ! ----------------------------------------------------------------------------
  1585. !   Finally: the mechanism for library text (the text is in the language defn)
  1586. ! ----------------------------------------------------------------------------
  1587. [ L__M act n x1 s;
  1588.   s=sw__var; sw__var=act; if (n==0) n=1;
  1589.   L___M(n,x1);
  1590.   sw__var=s;
  1591. [ L___M n x1 s;
  1592.   s=action;
  1593.   lm_n=n; lm_o=x1;
  1594.   action=sw__var;
  1595.   if (RunRoutines(LibraryMessages,before)~=0) { action=s; rfalse; }
  1596.   action=s;
  1597.   LanguageLM(n, x1);
  1598. ! ----------------------------------------------------------------------------
  1599. ! ----------------------------------------------------------------------------
  1600. !  VERBLIB:  Front end to standard verbs library.
  1601. !  Supplied for use with Inform 6                         Serial number 990428
  1602. !                                                                  Release 6/9
  1603. !  (c) Graham Nelson 1993, 1994, 1995, 1996, 1997, 1998, 1999
  1604. !      but freely usable (see manuals)
  1605. ! ----------------------------------------------------------------------------
  1606. System_file;
  1607. Default MAX_CARRIED  100;
  1608. Default MAX_SCORE    0;
  1609. Default NUMBER_TASKS 1;
  1610. Default OBJECT_SCORE 4;
  1611. Default ROOM_SCORE   5;
  1612. Default SACK_OBJECT  0;   
  1613. Default AMUSING_PROVIDED 1;
  1614. Default TASKS_PROVIDED   1;
  1615. #IFNDEF task_scores; Constant MAKE__TS; #ENDIF;
  1616. #IFDEF MAKE__TS;
  1617. Array  task_scores --> 0 0;
  1618. #ENDIF;
  1619. Array  task_done --> NUMBER_TASKS;
  1620. #IFNDEF LibraryMessages;
  1621. Object LibraryMessages;
  1622. #ENDIF;
  1623. #IFNDEF NO_PLACES;
  1624. [ PlacesSub; Places1Sub(); ];
  1625. [ ObjectsSub; Objects1Sub(); ];
  1626. #ENDIF;
  1627. #IFDEF USE_MODULES;
  1628. Link "verblibm";
  1629. #IFNOT;
  1630. Include "verblibm";
  1631. #ENDIF;
  1632. ! ----------------------------------------------------------------------------
  1633. !  PARSERM:  Core of parser.
  1634. !  Supplied for use with Inform 6                         Serial number 990428
  1635. !                                                                  Release 6/9
  1636. !  (c) Graham Nelson 1993, 1994, 1995, 1996, 1997, 1998, 1999
  1637. !      but freely usable (see manuals)
  1638. ! ----------------------------------------------------------------------------
  1639. !  Inclusion of "linklpa"
  1640. !                   (which defines properties and attributes)
  1641. !  Global variables, constants and arrays
  1642. !                1: outside of the parser
  1643. !                2: used within the parser
  1644. !  Inclusion of natural language definition file
  1645. !                   (which creates a compass and direction-objects)
  1646. !  Darkness and player objects
  1647. !  Definition of grammar token numbering system used by Inform
  1648. !  The InformParser object
  1649. !          keyboard reading
  1650. !          level 0: outer shell, conversation, errors
  1651. !                1: grammar lines
  1652. !                2: tokens
  1653. !                3: object lists
  1654. !                4: scope and ambiguity resolving
  1655. !                5: object comparisons
  1656. !                6: word comparisons
  1657. !                7: reading words and moving tables about
  1658. !          pronoun management
  1659. !  The InformLibrary object
  1660. !          main game loop
  1661. !          action processing
  1662. !          end of turn sequence
  1663. !          scope looping, before/after sequence, sending messages out
  1664. !          timers, daemons, time of day, score notification
  1665. !          light and darkness
  1666. !          changing player personality
  1667. !          tracing code (only present if DEBUG is set)
  1668. !  Status line printing, menu display
  1669. !  Printing object names with articles
  1670. !  Miscellaneous utility routines
  1671. !  Game banner, "version" verb, run-time errors
  1672. ! ----------------------------------------------------------------------------
  1673. System_file;
  1674. Constant NULL = $ffff;
  1675. IFDEF MODULE_MODE;
  1676. Constant DEBUG;
  1677. Constant Grammar__Version 2;
  1678. Include "linklpa";
  1679. ENDIF;
  1680. ! ============================================================================
  1681. !   Global variables and their associated Constant and Array declarations
  1682. ! ----------------------------------------------------------------------------
  1683. Global location = InformLibrary;     ! Must be first global defined
  1684. Global sline1;                       ! Must be second
  1685. Global sline2;                       ! Must be third
  1686.                                      ! (for status line display)
  1687. ! ------------------------------------------------------------------------------
  1688. !   Z-Machine and interpreter issues
  1689. ! ------------------------------------------------------------------------------
  1690. Global top_object;                   ! Largest valid number of any tree object
  1691. Global standard_interpreter;         ! The version number of the Z-Machine
  1692.                                      ! Standard which the interpreter claims
  1693.                                      ! to support, in form (upper byte).(lower)
  1694. Global undo_flag;                    ! Can the interpreter provide "undo"?
  1695. Global just_undone;                  ! Can't have two successive UNDOs
  1696. Global transcript_mode;              ! true when game scripting is on
  1697. IFDEF DEBUG;
  1698. Global xcommsdir;                    ! true if command recording is on
  1699. ENDIF;
  1700. ! ------------------------------------------------------------------------------
  1701. !   Time and score
  1702. ! (for linkage reasons, the task_* arrays are created not here but in verblib.h)
  1703. ! ------------------------------------------------------------------------------
  1704. Global turns = 1;                    ! Number of turns of play so far
  1705. Global the_time = NULL;              ! Current time (in minutes since midnight)
  1706. Global time_rate = 1;                ! How often time is updated
  1707. Global time_step;                    ! By how much
  1708. #ifndef MAX_TIMERS;
  1709. Constant MAX_TIMERS  32;             ! Max number timers/daemons active at once
  1710. #endif;
  1711. Array  the_timers  --> MAX_TIMERS;
  1712. Global active_timers;                ! Number of timers/daemons actives
  1713. Global score;                        ! The current score
  1714. Global last_score;                   ! Score last turn (for testing for changes)
  1715. Global notify_mode = true;           ! Score notification
  1716. Global places_score;                 ! Contribution to score made by visiting
  1717. Global things_score;                 ! Contribution made by acquisition
  1718. ! ------------------------------------------------------------------------------
  1719. !   The player
  1720. ! ------------------------------------------------------------------------------
  1721. Global player;                       ! Which object the human is playing through
  1722. Global deadflag;                     ! Normally 0, or false; 1 for dead;
  1723.                                      ! 2 for victorious, and higher numbers
  1724.                                      ! represent exotic forms of death
  1725. ! ------------------------------------------------------------------------------
  1726. !   Light and room descriptions
  1727. ! ------------------------------------------------------------------------------
  1728. Global lightflag = true;             ! Is there currently light to see by?
  1729. Global real_location;                ! When in darkness, location = thedark
  1730.                                      ! and this holds the real location
  1731. Global visibility_ceiling;           ! Highest object in tree visible from
  1732.                                      ! the player's point of view (usually
  1733.                                      ! the room, sometimes darkness, sometimes
  1734.                                      ! a closed non-transparent container).
  1735. Global lookmode = 1;                 ! 1=standard, 2=verbose, 3=brief room descs
  1736. Global print_player_flag;            ! If set, print something like "(as Fred)"
  1737.                                      ! in room descriptions, to reveal whom
  1738.                                      ! the human is playing through
  1739. Global lastdesc;                     ! Value of location at time of most recent
  1740.                                      ! room description printed out
  1741. ! ------------------------------------------------------------------------------
  1742. !   List writing  (style bits are defined as Constants in "verblibm.h")
  1743. ! ------------------------------------------------------------------------------
  1744. Global c_style;                      ! Current list-writer style
  1745. Global lt_value;                     ! Common value of list_together
  1746. Global listing_together;             ! Object number of one member of a group
  1747.                                      ! being listed together
  1748. Global listing_size;                 ! Size of such a group
  1749. Global wlf_indent;                   ! Current level of indentation printed by
  1750.                                      ! WriteListFrom routine
  1751. Global inventory_stage = 1;          ! 1 or 2 according to the context in which
  1752.                                      ! "invent" routines of objects are called
  1753. Global inventory_style;              ! List-writer style currently used while
  1754.                                      ! printing inventories
  1755. ! ------------------------------------------------------------------------------
  1756. !   Menus and printing
  1757. ! ------------------------------------------------------------------------------
  1758. Global pretty_flag = true;           ! Use character graphics, or plain text?
  1759. Global menu_nesting;                 ! Level of nesting (0 = root menu)
  1760. Global menu_item;                    ! These are used in communicating
  1761. Global item_width = 8;               ! with the menu-creating routines
  1762. Global item_name = "---";
  1763. Global lm_n;                         ! Parameters used by LibraryMessages
  1764. Global lm_o;                         ! mechanism
  1765. IFDEF DEBUG;
  1766. Global debug_flag;                   ! Bitmap of flags for tracing actions,
  1767.                                      ! calls to object routines, etc.
  1768. Global x_scope_count;                ! Used in printing a list of everything
  1769.                                      ! in scope
  1770. ENDIF;
  1771. ! ------------------------------------------------------------------------------
  1772. !   Action processing
  1773. ! ------------------------------------------------------------------------------
  1774. Global action;                       ! Action currently being asked to perform
  1775. Global inp1;                         ! 0 (nothing), 1 (number) or first noun
  1776. Global inp2;                         ! 0 (nothing), 1 (number) or second noun
  1777. Global noun;                         ! First noun or numerical value
  1778. Global second;                       ! Second noun or numerical value
  1779. Global keep_silent;                  ! If true, attempt to perform the action
  1780.                                      ! silently (e.g. for implicit takes,
  1781.                                      ! implicit opening of unlocked doors)
  1782. Global reason_code;                  ! Reason for calling a "life" rule
  1783.                                      ! (an action or fake such as ##Kiss)
  1784. Global receive_action;               ! Either ##PutOn or ##Insert, whichever
  1785.                                      ! is action being tried when an object's
  1786.                                      ! "before" rule is checking "Receive"
  1787. ! ==============================================================================
  1788. !   Parser variables: first, for communication to the parser
  1789. ! ------------------------------------------------------------------------------
  1790. Global parser_trace = 0;             ! Set this to 1 to make the parser trace
  1791.                                      ! tokens and lines
  1792. Global parser_action;                ! For the use of the parser when calling
  1793. Global parser_one;                   ! user-supplied routines
  1794. Global parser_two;                   !
  1795. Array  inputobjs       --> 16;       ! For parser to write its results in
  1796. Global parser_inflection;            ! A property (usually "name") to find
  1797.                                      ! object names in
  1798. ! ------------------------------------------------------------------------------
  1799. !   Parser output
  1800. ! ------------------------------------------------------------------------------
  1801. Global actor;                        ! Person asked to do something
  1802. Global actors_location;              ! Like location, but for the actor
  1803. Global meta;                         ! Verb is a meta-command (such as "save")
  1804. Array  multiple_object --> 64;       ! List of multiple parameters
  1805. Global multiflag;                    ! Multiple-object flag
  1806. Global toomany_flag;                 ! Flag for "multiple match too large"
  1807.                                      ! (e.g. if "take all" took over 100 things)
  1808. Global special_word;                 ! Dictionary address for "special" token
  1809. Global special_number;               ! Number typed for "special" token
  1810. Global parsed_number;                ! For user-supplied parsing routines
  1811. Global consult_from;                 ! Word that a "consult"
  1812. topic starts on
  1813. Global consult_words;                ! ...and number of words in topic
  1814. ! ------------------------------------------------------------------------------
  1815. !   Implicit taking
  1816. ! ------------------------------------------------------------------------------
  1817. Global notheld_mode;                 ! To do with implicit taking
  1818. Global onotheld_mode;                !     "old copy of notheld_mode", ditto
  1819. Global not_holding;                  ! Object to be automatically taken as an
  1820.                                      ! implicit command
  1821. Array  kept_results --> 16;          ! Delayed command (while the take happens)
  1822. ! ------------------------------------------------------------------------------
  1823. !   Error numbers when parsing a grammar line
  1824. ! ------------------------------------------------------------------------------
  1825. Global etype;                        ! Error number on current line
  1826. Global best_etype;                   ! Preferred error number so far
  1827. Global nextbest_etype;               ! Preferred one, if ASKSCOPE_PE disallowed
  1828. Constant STUCK_PE     = 1;
  1829. Constant UPTO_PE      = 2;
  1830. Constant NUMBER_PE    = 3;
  1831. Constant CANTSEE_PE   = 4;
  1832. Constant TOOLIT_PE    = 5;
  1833. Constant NOTHELD_PE   = 6;
  1834. Constant MULTI_PE     = 7;
  1835. Constant MMULTI_PE    = 8;
  1836. Constant VAGUE_PE     = 9;
  1837. Constant EXCEPT_PE    = 10;
  1838. Constant ANIMA_PE     = 11;
  1839. Constant VERB_PE      = 12;
  1840. Constant SCENERY_PE   = 13;
  1841. Constant ITGONE_PE    = 14;
  1842. Constant JUNKAFTER_PE = 15;
  1843. Constant TOOFEW_PE    = 16;
  1844. Constant NOTHING_PE   = 17;
  1845. Constant ASKSCOPE_PE  = 18;
  1846. ! ------------------------------------------------------------------------------
  1847. !   Pattern-matching against a single grammar line
  1848. ! ------------------------------------------------------------------------------
  1849. Array pattern --> 32;                ! For the current pattern match
  1850. Global pcount;                       ! and a marker within it
  1851. Array pattern2 --> 32;               ! And another, which stores the best match
  1852. Global pcount2;                      ! so far
  1853. Constant PATTERN_NULL = $ffff;       ! Entry for a token producing no text
  1854. Array  line_ttype-->32;              ! For storing an analysed grammar line
  1855. Array  line_tdata-->32;
  1856. Array  line_token-->32;
  1857. Global parameters;                   ! Parameters (objects) entered so far
  1858. Global nsns;                         ! Number of special_numbers entered so far
  1859. Global special_number1;              ! First number, if one was typed
  1860. Global special_number2;              ! Second number, if two were typed
  1861. ! ------------------------------------------------------------------------------
  1862. !   Inferences and looking ahead
  1863. ! ------------------------------------------------------------------------------
  1864. Global params_wanted;                ! Number of parameters needed
  1865.                                      ! (which may change in parsing)
  1866. Global inferfrom;                    ! The point from which the rest of the
  1867.                                      ! command must be inferred
  1868. Global inferword;                    ! And the preposition inferred
  1869. Global dont_infer;                   ! Another dull flag
  1870. Global action_to_be;                 ! (If the current line were accepted.)
  1871. Global action_reversed;              ! (Parameters would be reversed in order.)
  1872. Global advance_warning;              ! What a later-named thing will be
  1873. ! ------------------------------------------------------------------------------
  1874. !   At the level of individual tokens now
  1875. ! ------------------------------------------------------------------------------
  1876. Global found_ttype;                  ! Used to break up tokens into type
  1877. Global found_tdata;                  ! and data (by AnalyseToken)
  1878. Global token_filter;                 ! For noun filtering by user routines
  1879. Global length_of_noun;               ! Set by NounDomain to no of words in noun
  1880. Constant REPARSE_CODE = 10000;       ! Signals "reparse the text" as a reply
  1881.                                      ! from NounDomain
  1882. Global lookahead;                    ! The token after the one now being matched
  1883. Global multi_mode;                   ! Multiple mode
  1884. Global multi_wanted;                 ! Number of things needed in multitude
  1885. Global multi_had;                    ! Number of things actually found
  1886. Global multi_context;                ! What token the multi-obj was accepted for
  1887. Global indef_mode;                   ! "Indefinite" mode - ie, "take a brick"
  1888.                                      ! is in this mode
  1889. Global indef_type;                   ! Bit-map holding types of specification
  1890. Global indef_wanted;                 ! Number of items wanted (100 for all)
  1891. Global indef_guess_p;                ! Plural-guessing flag
  1892. Global indef_owner;                  ! Object which must hold these items
  1893. Global indef_cases;                  ! Possible gender and numbers of them
  1894. Global indef_possambig;              ! Has a possibly dangerous assumption
  1895.                                      ! been made about meaning of a descriptor?
  1896. Global indef_nspec_at;               ! Word at which a number like "two" was
  1897.                                      ! parsed (for backtracking)
  1898. Global allow_plurals;                ! Whether plurals presently allowed or not
  1899. Global take_all_rule;                ! Slightly different rules apply to
  1900.                                      ! "take all" than other uses of multiple
  1901.                                      ! objects, to make adjudication produce
  1902.                                      ! more pragmatically useful results
  1903.                                      ! (Not a flag: possible values 0, 1, 2)
  1904. Global dict_flags_of_noun;           ! Of the noun currently being parsed
  1905.                                      ! (a bitmap in #dict_par1 format)
  1906. Global pronoun_word;                 ! Records which pronoun ("it", "them", ...)
  1907.                                      ! caused an error
  1908. Global pronoun_obj;                  ! And what obj it was thought to refer to
  1909. Global pronoun__word;                ! Saved value
  1910. Global pronoun__obj;                 ! Saved value
  1911. ! ------------------------------------------------------------------------------
  1912. !   Searching through scope and parsing "scope=Routine" grammar tokens
  1913. ! ------------------------------------------------------------------------------
  1914. Constant PARSING_REASON       = 0;   ! Possible reasons for searching scope
  1915. Constant TALKING_REASON       = 1;
  1916. Constant EACH_TURN_REASON     = 2;
  1917. Constant REACT_BEFORE_REASON  = 3;
  1918. Constant REACT_AFTER_REASON   = 4;
  1919. Constant LOOPOVERSCOPE_REASON = 5;
  1920. Constant TESTSCOPE_REASON     = 6;
  1921. Global scope_reason = PARSING_REASON; ! Current reason for searching scope
  1922. Global scope_token;                  ! For "scope=Routine" grammar tokens
  1923. Global scope_error;
  1924. Global scope_stage;                  ! 1, 2 then 3
  1925. Global ats_flag = 0;                 ! For AddToScope routines
  1926. Global ats_hls;                      !
  1927. Global placed_in_flag;               ! To do with PlaceInScope
  1928. ! ------------------------------------------------------------------------------
  1929. !   The match list of candidate objects for a given token
  1930. ! ------------------------------------------------------------------------------
  1931. Constant MATCH_LIST_SIZE = 128;
  1932. Array  match_list    --> 64;         ! An array of matched objects so far
  1933. Array  match_classes --> 64;         ! An array of equivalence classes for them
  1934. Array  match_scores --> 64;          ! An array of match scores for them
  1935. Global number_matched;               ! How many items in it?  (0 means none)
  1936. Global number_of_classes;            ! How many equivalence classes?
  1937. Global match_length;                 ! How many words long are these matches?
  1938. Global match_from;                   ! At what word of the input do they begin?
  1939. ! ------------------------------------------------------------------------------
  1940. !   Low level textual manipulation
  1941. ! ------------------------------------------------------------------------------
  1942. Array  buffer    -> 121;             ! Buffer for parsing main line of input
  1943. Array  parse     -> 65;              ! Parse table mirroring it
  1944. Array  buffer2   -> 121;             ! Buffers for supplementary questions
  1945. Array  parse2    -> 65;              !
  1946. Array  buffer3   -> 121;             ! Buffer retaining input for "again"
  1947. Constant comma_word = 'comma,';      ! An "untypeable word" used to substitute
  1948.                                      ! for commas in parse buffers
  1949. Global wn;                           ! Word number within "parse" (from 1)
  1950. Global num_words;                    ! Number of words typed
  1951. Global verb_word;                    ! Verb word (eg, take in "take all" or
  1952.                                      ! "dwarf, take all") - address in dict
  1953. Global verb_wordnum;                 ! its number in typing order (eg, 1 or 3)
  1954. Global usual_grammar_after;          ! Point from which usual grammar is parsed
  1955.                                      ! (it may vary from the above if user's
  1956.                                      ! routines match multi-word verbs)
  1957. Global oops_from;                    ! The "first mistake" word number
  1958. Global saved_oops;                   ! Used in working this out
  1959. Array  oops_workspace -> 64;         ! Used temporarily by "oops" routine
  1960. Global held_back_mode;               ! Flag: is there some input from last time
  1961. Global hb_wn;                        ! left over?  (And a save value for wn.)
  1962.                                      ! (Used for full stops and "then".)
  1963. ! ----------------------------------------------------------------------------
  1964. Array PowersOfTwo_TB                 ! Used in converting case numbers to
  1965.   --> $$100000000000                 ! case bitmaps
  1966.       $$010000000000
  1967.       $$001000000000
  1968.       $$000100000000
  1969.       $$000010000000
  1970.       $$000001000000
  1971.       $$000000100000
  1972.       $$000000010000
  1973.       $$000000001000
  1974.       $$000000000100
  1975.       $$000000000010
  1976.       $$000000000001;
  1977. ! ============================================================================
  1978. ! ============================================================================
  1979. !  Constants, and one variable, needed for the language definition file
  1980. ! ----------------------------------------------------------------------------
  1981. Constant POSSESS_PK  = $100;
  1982. Constant DEFART_PK   = $101;
  1983. Constant INDEFART_PK = $102;
  1984. Global short_name_case;
  1985. ! ----------------------------------------------------------------------------
  1986. Include "language__";                !  The natural language definition,
  1987.                                      !  whose filename is taken from the ICL
  1988.                                      !  language_name variable
  1989. ! ----------------------------------------------------------------------------
  1990. #ifndef LanguageCases;
  1991. Constant LanguageCases = 1;
  1992. #endif;
  1993. ! ------------------------------------------------------------------------------
  1994. !   Pronouns support for the cruder (library 6/2 and earlier) version:
  1995. !   only needed in English
  1996. ! ------------------------------------------------------------------------------
  1997. #ifdef EnglishNaturalLanguage;
  1998. Global itobj = NULL;                 ! The object which is currently "it"
  1999. Global himobj = NULL;                ! The object which is currently "him"
  2000. Global herobj = NULL;                ! The object which is currently "her"
  2001. Global old_itobj = NULL;             ! The object which is currently "it"
  2002. Global old_himobj = NULL;            ! The object which is currently "him"
  2003. Global old_herobj = NULL;            ! The object which is currently "her"
  2004. #endif;
  2005. ! ============================================================================
  2006. ! ============================================================================
  2007. ! "Darkness" is not really a place: but it has to be an object so that the
  2008. !  location-name on the status line can be "Darkness".
  2009. ! ----------------------------------------------------------------------------
  2010. Object thedark "(darkness object)"
  2011.   with initial 0,
  2012.        short_name DARKNESS__TX,
  2013.        description
  2014.        [;  return L__M(##Miscellany, 17);
  2015.        ];
  2016. Object selfobj "(self object)"
  2017.   with short_name
  2018.        [;  return L__M(##Miscellany, 18);
  2019.        ],
  2020.        description
  2021.        [;  return L__M(##Miscellany, 19);
  2022.        ],
  2023.        before NULL,   after NULL,    life NULL,    each_turn NULL,
  2024.        time_out NULL, describe NULL,
  2025.        capacity 100, parse_name 0,
  2026.        orders 0, number 0,
  2027.   has  concealed animate proper transparent;
  2028. ! ============================================================================
  2029. !  The definition of the token-numbering system used by Inform.
  2030. ! ----------------------------------------------------------------------------
  2031. Constant ILLEGAL_TT        = 0;      ! Types of grammar token: illegal
  2032. Constant ELEMENTARY_TT     = 1;      !     (one of those below)
  2033. Constant PREPOSITION_TT    = 2;      !     e.g. 'into'
  2034. Constant ROUTINE_FILTER_TT = 3;      !     e.g. noun=CagedCreature
  2035. Constant ATTR_FILTER_TT    = 4;      !     e.g. edible
  2036. Constant SCOPE_TT          = 5;      !     e.g. scope=Spells
  2037. Constant GPR_TT            = 6;      !     a general parsing routine
  2038. Constant NOUN_TOKEN        = 0;      ! The elementary grammar tokens, and
  2039. Constant HELD_TOKEN        = 1;      ! the numbers compiled by Inform to
  2040. Constant MULTI_TOKEN       = 2;      ! encode them
  2041. Constant MULTIHELD_TOKEN   = 3;
  2042. Constant MULTIEXCEPT_TOKEN = 4;
  2043. Constant MULTIINSIDE_TOKEN = 5;
  2044. Constant CREATURE_TOKEN    = 6;
  2045. Constant SPECIAL_TOKEN     = 7;
  2046. Constant NUMBER_TOKEN      = 8;
  2047. Constant TOPIC_TOKEN       = 9;
  2048. Constant GPR_FAIL          = -1;     ! Return values from General Parsing
  2049. Constant GPR_PREPOSITION   = 0;      ! Routines
  2050. Constant GPR_NUMBER        = 1;
  2051. Constant GPR_MULTIPLE      = 2;
  2052. Constant GPR_REPARSE       = REPARSE_CODE;
  2053. Constant GPR_NOUN          = $ff00;
  2054. Constant GPR_HELD          = $ff01;
  2055. Constant GPR_MULTI         = $ff02;
  2056. Constant GPR_MULTIHELD     = $ff03;
  2057. Constant GPR_MULTIEXCEPT   = $ff04;
  2058. Constant GPR_MULTIINSIDE   = $ff05;
  2059. Constant GPR_CREATURE      = $ff06;
  2060. Constant ENDIT_TOKEN       = 15;     ! Value used to mean "end of grammar line"
  2061. #Iftrue Grammar__Version == 1;
  2062. [ AnalyseToken token m;
  2063.     found_tdata = token;
  2064.     if (token < 0)   { found_ttype = ILLEGAL_TT; return; }
  2065.     if (token <= 8)  { found_ttype = ELEMENTARY_TT; return; }
  2066.     if (token < 15)  { found_ttype = ILLEGAL_TT; return; }
  2067.     if (token == 15) { found_ttype = ELEMENTARY_TT; return; }
  2068.     if (token < 48)  { found_ttype = ROUTINE_FILTER_TT;
  2069.                        found_tdata = token - 16;
  2070.                        return; }
  2071.     if (token < 80)  { found_ttype = GPR_TT;
  2072.                        found_tdata = #preactions_table-->(token-48);
  2073.                        return; }
  2074.     if (token < 128) { found_ttype = SCOPE_TT;
  2075.                        found_tdata = #preactions_table-->(token-80);
  2076.                        return; }
  2077.     if (token < 180) { found_ttype = ATTR_FILTER_TT;
  2078.                        found_tdata = token - 128;
  2079.                        return; }
  2080.     found_ttype = PREPOSITION_TT;
  2081.     m=#adjectives_table;
  2082.     for (::)
  2083.     {   if (token==m-->1) { found_tdata = m-->0; return; }
  2084.         m=m+4;
  2085.     }
  2086.     m=#adjectives_table; RunTimeError(1);
  2087.     found_tdata = m;
  2088. [ UnpackGrammarLine line_address i m;
  2089.   for (i = 0 : i < 32 : i++)
  2090.   {   line_token-->i = ENDIT_TOKEN;
  2091.       line_ttype-->i = ELEMENTARY_TT;
  2092.       line_tdata-->i = ENDIT_TOKEN;
  2093.   for (i = 0: i <= 5 :i++)
  2094.   {   line_token-->i = line_address->(i+1);
  2095.       AnalyseToken(line_token-->i);
  2096.       if ((found_ttype == ELEMENTARY_TT) && (found_tdata == NOUN_TOKEN)
  2097.           && (m == line_address->0))
  2098.       {   line_token-->i = ENDIT_TOKEN;
  2099.           break;
  2100.       }
  2101.       line_ttype-->i = found_ttype;
  2102.       line_tdata-->i = found_tdata;
  2103.       if (found_ttype ~= PREPOSITION_TT) m++;
  2104.   action_to_be = line_address->7;
  2105.   action_reversed = false;
  2106.   params_wanted = line_address->0;
  2107.   return line_address + 8;
  2108. #Ifnot;
  2109. [ AnalyseToken token;
  2110.     if (token == ENDIT_TOKEN)
  2111.     {   found_ttype = ELEMENTARY_TT;
  2112.         found_tdata = ENDIT_TOKEN;
  2113.         return;
  2114.     }
  2115.     found_ttype = (token->0) & $$1111;
  2116.     found_tdata = (token+1)-->0;
  2117. [ UnpackGrammarLine line_address i;
  2118.   for (i = 0 : i < 32 : i++)
  2119.   {   line_token-->i = ENDIT_TOKEN;
  2120.       line_ttype-->i = ELEMENTARY_TT;
  2121.       line_tdata-->i = ENDIT_TOKEN;
  2122.   action_to_be = 256*(line_address->0) + line_address->1;
  2123.   action_reversed = ((action_to_be & $400) ~= 0);
  2124.   action_to_be = action_to_be & $3ff;
  2125.   line_address--;
  2126.   params_wanted = 0;
  2127.   for (i=0::i++)
  2128.   {   line_address = line_address + 3;
  2129.       if (line_address->0 == ENDIT_TOKEN) break;
  2130.       line_token-->i = line_address;
  2131.       AnalyseToken(line_address);
  2132.       if (found_ttype ~= PREPOSITION_TT) params_wanted++;
  2133.       line_ttype-->i = found_ttype;
  2134.       line_tdata-->i = found_tdata;
  2135.   return line_address + 1;
  2136. #Endif;
  2137. !  To protect against a bug in early versions of the "Zip" interpreter:
  2138. [ Tokenise__ b p; b->(2 + b->1) = 0; @tokenise b p; ];
  2139. ! ============================================================================
  2140. !  The InformParser object abstracts the front end of the parser.
  2141. !  InformParser.parse_input(results)
  2142. !  returns only when a sensible request has been made, and puts into the
  2143. !  "results" buffer:
  2144. !  --> 0 = The action number
  2145. !  --> 1 = Number of parameters
  2146. !  --> 2, 3, ... = The parameters (object numbers), but
  2147. !                  0 means "put the multiple object list here"
  2148. !                  1 means "put one of the special numbers here"
  2149. ! ----------------------------------------------------------------------------
  2150. Object InformParser "(Inform Parser)"
  2151.   with parse_input
  2152.        [ results; Parser__parse(results);
  2153.        ], has proper;
  2154. ! ----------------------------------------------------------------------------
  2155. !  The Keyboard routine actually receives the player's words,
  2156. !  putting the words in "a_buffer" and their dictionary addresses in
  2157. !  "a_table".  It is assumed that the table is the same one on each
  2158. !  (standard) call.
  2159. !  It can also be used by miscellaneous routines in the game to ask
  2160. !  yes-no questions and the like, without invoking the rest of the parser.
  2161. !  Return the number of words typed
  2162. ! ----------------------------------------------------------------------------
  2163. [ KeyboardPrimitive  a_buffer a_table;
  2164.   read a_buffer a_table;
  2165. [ Keyboard  a_buffer a_table  nw i w w2 x1 x2;
  2166.     DisplayStatus();
  2167.     .FreshInput;
  2168. !  Save the start of the buffer, in case "oops" needs to restore it
  2169. !  to the previous time's buffer
  2170.     for (i=0:i<64:i++) oops_workspace->i = a_buffer->i;
  2171. !  In case of an array entry corruption that shouldn't happen, but would be
  2172. !  disastrous if it did:
  2173.    a_buffer->0 = 120;
  2174.    a_table->0 = 15;  ! Allow to split input into this many words
  2175. !  Print the prompt, and read in the words and dictionary addresses
  2176.     L__M(##Prompt);
  2177.     AfterPrompt();
  2178.     #IFV5; DrawStatusLine(); #ENDIF;
  2179.     KeyboardPrimitive(a_buffer, a_table);
  2180.     nw=a_table->1;
  2181. !  If the line was blank, get a fresh line
  2182.     if (nw == 0)
  2183.     { L__M(##Miscellany,10); jump FreshInput; }
  2184. !  Unless the opening word was "oops", return
  2185.     w=a_table-->1;
  2186.     if (w == OOPS1__WD or OOPS2__WD or OOPS3__WD) jump DoOops;
  2187. #IFV5;
  2188. !  Undo handling
  2189.     if ((w == UNDO1__WD or UNDO2__WD or UNDO3__WD) && (parse->1==1))
  2190.     {   if (turns==1)
  2191.         {   L__M(##Miscellany,11); jump FreshInput;
  2192.         }
  2193.         if (undo_flag==0)
  2194.         {   L__M(##Miscellany,6); jump FreshInput;
  2195.         }
  2196.         if (undo_flag==1) jump UndoFailed;
  2197.         if (just_undone==1)
  2198.         {   L__M(##Miscellany,12); jump FreshInput;
  2199.         }
  2200.         @restore_undo i;
  2201.         if (i==0)
  2202.         {   .UndoFailed;
  2203.             L__M(##Miscellany,7);
  2204.         }
  2205.         jump FreshInput;
  2206.     }
  2207.     @save_undo i;
  2208.     just_undone=0;
  2209.     undo_flag=2;
  2210.     if (i==-1) undo_flag=0;
  2211.     if (i==0) undo_flag=1;
  2212.     if (i==2)
  2213.     {   style bold;
  2214.         print (name) location, "^";
  2215.         style roman;
  2216.         L__M(##Miscellany,13);
  2217.         just_undone=1;
  2218.         jump FreshInput;
  2219.     }
  2220. #ENDIF;
  2221.     return nw;
  2222.     .DoOops;
  2223.     if (oops_from == 0)
  2224.     {   L__M(##Miscellany,14); jump FreshInput; }
  2225.     if (nw == 1)
  2226.     {   L__M(##Miscellany,15); jump FreshInput; }
  2227.     if (nw > 2)
  2228.     {   L__M(##Miscellany,16); jump FreshInput; }
  2229. !  So now we know: there was a previous mistake, and the player has
  2230. !  attempted to correct a single word of it.
  2231.     for (i=0:i<=120:i++) buffer2->i = a_buffer->i;
  2232.     x1 = a_table->9; ! Start of word following "oops"
  2233.     x2 = a_table->8; ! Length of word following "oops"
  2234. !  Repair the buffer to the text that was in it before the "oops"
  2235. !  was typed:
  2236.     for (i=0:i<64:i++) a_buffer->i = oops_workspace->i;
  2237.     Tokenise__(a_buffer,a_table);
  2238. !  Work out the position in the buffer of the word to be corrected:
  2239.     w = a_table->(4*oops_from + 1); ! Start of word to go
  2240.     w2 = a_table->(4*oops_from);    ! Length of word to go
  2241. !  Write spaces over the word to be corrected:
  2242.     for (i=0:i<w2:i++) a_buffer->(i+w) = ' ';
  2243.     if (w2 < x2)
  2244.     {   ! If the replacement is longer than the original, move up...
  2245.         for (i=120:i>=w+x2:i--)
  2246.             a_buffer->i = a_buffer->(i-x2+w2);
  2247.         ! ...increasing buffer size accordingly.
  2248.         a_buffer->1 = (a_buffer->1) + (x2-w2);
  2249.     }
  2250. !  Write the correction in:
  2251.     for (i=0:i<x2:i++) a_buffer->(i+w) = buffer2->(i+x1);
  2252.     Tokenise__(a_buffer,a_table);
  2253.     nw=a_table->1;
  2254.     return nw;
  2255. ! ----------------------------------------------------------------------------
  2256. !  To simplify the picture a little, a rough map of the main routine:
  2257. !  (A)    Get the input, do "oops" and "again"
  2258. !  (B)    Is it a direction, and so an implicit "go"?  If so go to (K)
  2259. !  (C)    Is anyone being addressed?
  2260. !  (D)    Get the verb: try all the syntax lines for that verb
  2261. !  (E)    Break down a syntax line into analysed tokens
  2262. !  (F)    Look ahead for advance warning for multiexcept/multiinside
  2263. !  (G)    Parse each token in turn (calling ParseToken to do most of the work)
  2264. !  (H)    Cheaply parse otherwise unrecognised conversation and return
  2265. !  (I)    Print best possible error message
  2266. !  (J)    Retry the whole lot
  2267. !  (K)    Last thing: check for "then" and further instructions(s), return.
  2268. !  The strategic points (A) to (K) are marked in the commentary.
  2269. !  Note that there are three different places where a return can happen.
  2270. ! ----------------------------------------------------------------------------
  2271. [ Parser__parse  results   syntax line num_lines line_address i j k
  2272.                            token l m;
  2273. !  **** (A) ****
  2274. !  Firstly, in "not held" mode, we still have a command left over from last
  2275. !  time (eg, the user typed "eat biscuit", which was parsed as "take biscuit"
  2276. !  last time, with "eat biscuit" tucked away until now).  So we return that.
  2277.     if (notheld_mode==1)
  2278.     {   for (i=0:i<8:i++) results-->i=kept_results-->i;
  2279.         notheld_mode=0; rtrue;
  2280.     }
  2281.     if (held_back_mode==1)
  2282.     {   held_back_mode=0;
  2283.         Tokenise__(buffer,parse);
  2284.         jump ReParse;
  2285.     }
  2286.   .ReType;
  2287.     Keyboard(buffer,parse);
  2288.   .ReParse;
  2289.     parser_inflection = name;
  2290. !  Initially assume the command is aimed at the player, and the verb
  2291. !  is the first word
  2292.     num_words=parse->1;
  2293.     wn=1;
  2294. #ifdef LanguageToInformese;
  2295.     LanguageToInformese();
  2296. #ifv5;
  2297. !   Re-tokenise:
  2298.     Tokenise__(buffer,parse);
  2299. #endif;
  2300. #endif;
  2301.     BeforeParsing();
  2302.     num_words=parse->1;
  2303.     k=0;
  2304. #ifdef DEBUG;
  2305.     if (parser_trace>=2)
  2306.     {   print "[ ";
  2307.         for (i=0:i<num_words:i++)
  2308.         {   j=parse-->(i*2 + 1);
  2309.             k=WordAddress(i+1);
  2310.             l=WordLength(i+1);
  2311.             print "~"; for (m=0:m<l:m++) print (char) k->m; print "~ ";
  2312.             if (j == 0) print "?";
  2313.             else
  2314.             {   if (UnsignedCompare(j, 0-->4)>=0
  2315.                     && UnsignedCompare(j, 0-->2)<0) print (address) j;
  2316.                 else print j;
  2317.             }
  2318.             if (i ~= num_words-1) print " / ";
  2319.         }
  2320.         print " ]^";
  2321.     }
  2322. #endif;
  2323.     verb_wordnum=1;
  2324.     actor=player;
  2325.     actors_location = ScopeCeiling(player);
  2326.     usual_grammar_after = 0;
  2327.   .AlmostReParse;
  2328.     scope_token = 0;
  2329.     action_to_be = NULL;
  2330. !  Begin from what we currently think is the verb word
  2331.   .BeginCommand;
  2332.     wn=verb_wordnum;
  2333.     verb_word = NextWordStopped();
  2334. !  If there's no input here, we must have something like
  2335. !  "person,".
  2336.     if (verb_word==-1)
  2337.     {   best_etype = STUCK_PE; jump GiveError; }
  2338. !  Now try for "again" or "g", which are special cases:
  2339. !  don't allow "again" if nothing has previously been typed;
  2340. !  simply copy the previous text across
  2341.     if (verb_word==AGAIN2__WD or AGAIN3__WD) verb_word=AGAIN1__WD;
  2342.     if (verb_word==AGAIN1__WD)
  2343.     {   if (actor~=player)
  2344.         {   L__M(##Miscellany,20); jump ReType; }
  2345.         if (buffer3->1==0)
  2346.         {   L__M(##Miscellany,21); jump ReType; }
  2347.         for (i=0:i<120:i++) buffer->i=buffer3->i;
  2348.         jump ReParse;
  2349.     }
  2350. !  Save the present input in case of an "again" next time
  2351.     if (verb_word~=AGAIN1__WD)
  2352.         for (i=0:i<120:i++) buffer3->i=buffer->i;
  2353.     if (usual_grammar_after==0)
  2354.     {   i = RunRoutines(actor, grammar);
  2355.         #ifdef DEBUG;
  2356.         if (parser_trace>=2 && actor.grammar~=0 or NULL)
  2357.             print " [Grammar property returned ", i, "]^";
  2358.         #endif;
  2359.         if (i<0) { usual_grammar_after = verb_wordnum; i=-i; }
  2360.         if (i==1)
  2361.         {   results-->0 = action;
  2362.             results-->1 = noun;
  2363.             results-->2 = second;
  2364.             rtrue;
  2365.         }
  2366.         if (i~=0) { verb_word = i; wn--; verb_wordnum--; }
  2367.         else
  2368.         {   wn = verb_wordnum; verb_word=NextWord();
  2369.         }
  2370.     }
  2371.     else usual_grammar_after=0;
  2372. !  **** (B) ****
  2373.     #ifdef LanguageIsVerb;
  2374.     if (verb_word==0)
  2375.     {   i = wn; verb_word=LanguageIsVerb(buffer, parse, verb_wordnum);
  2376.         wn = i;
  2377.     }
  2378.     #endif;
  2379. !  If the first word is not listed as a verb, it must be a direction
  2380. !  or the name of someone to talk to
  2381.     if (verb_word==0 || ((verb_word->#dict_par1) & 1) == 0)
  2382.     {   
  2383. !  So is the first word an object contained in the special object "compass"
  2384. !  (i.e., a direction)?  This needs use of NounDomain, a routine which
  2385. !  does the object matching, returning the object number, or 0 if none found,
  2386. !  or REPARSE_CODE if it has restructured the parse table so the whole parse
  2387. !  must be begun again...
  2388.         wn=verb_wordnum; indef_mode = false; token_filter = 0;
  2389.         l=NounDomain(compass,0,0); if (l==REPARSE_CODE) jump ReParse;
  2390. !  If it is a direction, send back the results:
  2391. !  action=GoSub, no of arguments=1, argument 1=the direction.
  2392.         if (l~=0)
  2393.         {   results-->0 = ##Go;
  2394.             results-->1 = 1;
  2395.             results-->2 = l;
  2396.             jump LookForMore;
  2397.         }
  2398. !  **** (C) ****
  2399. !  Only check for a comma (a "someone, do something" command) if we are
  2400. !  not already in the middle of one.  (This simplification stops us from
  2401. !  worrying about "robot, wizard, you are an idiot", telling the robot to
  2402. !  tell the wizard that she is an idiot.)
  2403.         if (actor==player)
  2404.         {   for (j=2:j<=num_words:j++)
  2405.             {   i=NextWord(); if (i==comma_word) jump Conversation;
  2406.             }
  2407.             verb_word=UnknownVerb(verb_word);
  2408.             if (verb_word~=0) jump VerbAccepted;
  2409.         }
  2410.         best_etype=VERB_PE; jump GiveError;
  2411. !  NextWord nudges the word number wn on by one each time, so we've now
  2412. !  advanced past a comma.  (A comma is a word all on its own in the table.)
  2413.       .Conversation;
  2414.         j=wn-1;
  2415.         if (j==1) { L__M(##Miscellany,22); jump ReType; }
  2416. !  Use NounDomain (in the context of "animate creature") to see if the
  2417. !  words make sense as the name of someone held or nearby
  2418.         wn=1; lookahead=HELD_TOKEN;
  2419.         scope_reason = TALKING_REASON;
  2420.         l=NounDomain(player,actors_location,6);
  2421.         scope_reason = PARSING_REASON;
  2422.         if (l==REPARSE_CODE) jump ReParse;
  2423.         if (l==0) { L__M(##Miscellany,23); jump ReType; }
  2424. !  The object addressed must at least be "talkable" if not actually "animate"
  2425. !  (the distinction allows, for instance, a microphone to be spoken to,
  2426. !  without the parser thinking that the microphone is human).
  2427.         if (l hasnt animate && l hasnt talkable)
  2428.         {   L__M(##Miscellany, 24, l); jump ReType; }
  2429. !  Check that there aren't any mystery words between the end of the person's
  2430. !  name and the comma (eg, throw out "dwarf sdfgsdgs, go north").
  2431.         if (wn~=j)
  2432.         {   L__M(##Miscellany, 25); jump ReType; }
  2433. !  The player has now successfully named someone.  Adjust "him", "her", "it":
  2434.         PronounNotice(l);
  2435. !  Set the global variable "actor", adjust the number of the first word,
  2436. !  and begin parsing again from there.
  2437.         verb_wordnum=j+1;
  2438. !  Stop things like "me, again":
  2439.         if (l == player)
  2440.         {   wn = verb_wordnum;
  2441.             if (NextWordStopped() == AGAIN1__WD or AGAIN2__WD or AGAIN3__WD)
  2442.             {   L__M(##Miscellany,20); jump ReType;
  2443.             }
  2444.         }
  2445.         actor=l;
  2446.         actors_location=ScopeCeiling(l);
  2447.         #ifdef DEBUG;
  2448.         if (parser_trace>=1)
  2449.             print "[Actor is ", (the) actor, " in ",
  2450.                 (name) actors_location, "]^";
  2451.         #endif;
  2452.         jump BeginCommand;
  2453.     }
  2454. !  **** (D) ****
  2455.    .VerbAccepted;
  2456. !  We now definitely have a verb, not a direction, whether we got here by the
  2457. !  "take ..." or "person, take ..." method.  Get the meta flag for this verb:
  2458.     meta=((verb_word->#dict_par1) & 2)/2;
  2459. !  You can't order other people to "full score" for you, and so on...
  2460.     if (meta==1 && actor~=player)
  2461.     {   best_etype=VERB_PE; meta=0; jump GiveError; }
  2462. !  Now let i be the corresponding verb number, stored in the dictionary entry
  2463. !  (in a peculiar 255-n fashion for traditional Infocom reasons)...
  2464.     i=$ff-(verb_word->#dict_par2);
  2465. !  ...then look up the i-th entry in the verb table, whose address is at word
  2466. !  7 in the Z-machine (in the header), so as to get the address of the syntax
  2467. !  table for the given verb...
  2468.     syntax=(0-->7)-->i;
  2469. !  ...and then see how many lines (ie, different patterns corresponding to the
  2470. !  same verb) are stored in the parse table...
  2471.     num_lines=(syntax->0)-1;
  2472. !  ...and now go through them all, one by one.
  2473. !  To prevent pronoun_word 0 being misunderstood,
  2474.    pronoun_word=NULL; pronoun_obj=NULL;
  2475.    #ifdef DEBUG;
  2476.    if (parser_trace>=1)
  2477.    {    print "[Parsing for the verb '", (address) verb_word,
  2478.               "' (", num_lines+1, " lines)]^";
  2479.    #endif;
  2480.    best_etype=STUCK_PE; nextbest_etype=STUCK_PE;
  2481. !  "best_etype" is the current failure-to-match error - it is by default
  2482. !  the least informative one, "don't understand that sentence".
  2483. !  "nextbest_etype" remembers the best alternative to having to ask a
  2484. !  scope token for an error message (i.e., the best not counting ASKSCOPE_PE).
  2485. !  **** (E) ****
  2486.     line_address = syntax + 1;
  2487.     for (line=0:line<=num_lines:line++)
  2488.     {   
  2489.         for (i = 0 : i < 32 : i++)
  2490.         {   line_token-->i = ENDIT_TOKEN;
  2491.             line_ttype-->i = ELEMENTARY_TT;
  2492.             line_tdata-->i = ENDIT_TOKEN;
  2493.         }
  2494. !  Unpack the syntax line from Inform format into three arrays; ensure that
  2495. !  the sequence of tokens ends in an ENDIT_TOKEN.
  2496.         line_address = UnpackGrammarLine(line_address);
  2497.             
  2498.         #ifdef DEBUG;
  2499.         if (parser_trace >= 1)
  2500.         {   if (parser_trace >= 2) new_line;
  2501.             print "[line ", line; DebugGrammarLine();
  2502.             print "]^";
  2503.         }
  2504.         #endif;
  2505. !  We aren't in "not holding" or inferring modes, and haven't entered
  2506. !  any parameters on the line yet, or any special numbers; the multiple
  2507. !  object is still empty.
  2508.         not_holding=0;
  2509.         inferfrom=0;
  2510.         parameters=0;
  2511.         nsns=0; special_word=0; special_number=0;
  2512.         multiple_object-->0 = 0;
  2513.         multi_context = 0;
  2514.         etype=STUCK_PE;
  2515. !  Put the word marker back to just after the verb
  2516.         wn=verb_wordnum+1;
  2517. !  **** (F) ****
  2518. !  There are two special cases where parsing a token now has to be
  2519. !  affected by the result of parsing another token later, and these
  2520. !  two cases (multiexcept and multiinside tokens) are helped by a quick
  2521. !  look ahead, to work out the future token now.  We can only carry this
  2522. !  out in the simple (but by far the most common) case:
  2523. !      multiexcept <one or more prepositions> noun
  2524. !  and similarly for multiinside.
  2525.         advance_warning = NULL; indef_mode = false;
  2526.         for (i=0,m=false,pcount=0:line_token-->pcount ~= ENDIT_TOKEN:pcount++)
  2527.         {   scope_token = 0;
  2528.             if (line_ttype-->pcount ~= PREPOSITION_TT) i++;
  2529.             if (line_ttype-->pcount == ELEMENTARY_TT)
  2530.             {   if (line_tdata-->pcount == MULTI_TOKEN) m=true;
  2531.                 if (line_tdata-->pcount
  2532.                     == MULTIEXCEPT_TOKEN or MULTIINSIDE_TOKEN  && i==1)
  2533.                 {   !   First non-preposition is "multiexcept" or
  2534.                     !   "multiinside", so look ahead.
  2535.                     #ifdef DEBUG;
  2536.                     if (parser_trace>=2) print " [Trying look-ahead]^";
  2537.                     #endif;
  2538.                     !   We need this to be followed by 1 or more prepositions.
  2539.                     pcount++;
  2540.                     if (line_ttype-->pcount == PREPOSITION_TT)
  2541.                     {   while (line_ttype-->pcount == PREPOSITION_TT)
  2542.                             pcount++;
  2543.                         if ((line_ttype-->pcount == ELEMENTARY_TT)
  2544.                             && (line_tdata-->pcount == NOUN_TOKEN))
  2545.                         {
  2546.                             !  Advance past the last preposition
  2547.                             while (wn <= num_words)
  2548.                             {   if (NextWord() == line_tdata-->(pcount-1))
  2549.                                 {   l = NounDomain(actors_location, actor,
  2550.                                             NOUN_TOKEN);
  2551.                                     #ifdef DEBUG;
  2552.                                     if (parser_trace>=2)
  2553.                                     {   print " [Advanced to ~noun~ token: ";
  2554.                                         if (l==REPARSE_CODE)
  2555.                                             print "re-parse request]^";
  2556.                                         if (l==1) print "but multiple found]^";
  2557.                                         if (l==0) print "error ", etype, "]^";
  2558.                                         if (l>=2) print (the) l, "]^";
  2559.                                     }
  2560.                                     #endif;
  2561.                                     if (l==REPARSE_CODE) jump ReParse;
  2562.                                     if (l>=2) advance_warning = l;
  2563.                                 }
  2564.                             }
  2565.                         }
  2566.                     }
  2567.                     break;
  2568.                 }
  2569.             }
  2570.         }
  2571. !  Slightly different line-parsing rules will apply to "take multi", to
  2572. !  prevent "take all" behaving correctly but misleadingly when there's
  2573. !  nothing to take.
  2574.         take_all_rule = 0;
  2575.         if (m && params_wanted==1 && action_to_be==##Take)
  2576.             take_all_rule = 1;
  2577. !  And now start again, properly, forearmed or not as the case may be.
  2578. !  As a precaution, we clear all the variables again (they may have been
  2579. !  disturbed by the call to NounDomain, which may have called outside
  2580. !  code, which may have done anything!).
  2581.         not_holding=0;
  2582.         inferfrom=0;
  2583.         parameters=0;
  2584.         nsns=0; special_word=0; special_number=0;
  2585.         multiple_object-->0 = 0;
  2586.         etype=STUCK_PE;
  2587.         wn=verb_wordnum+1;
  2588. !  **** (G) ****
  2589. !  "Pattern" gradually accumulates what has been recognised so far,
  2590. !  so that it may be reprinted by the parser later on
  2591.         for (pcount=1::pcount++)
  2592.         {   pattern-->pcount = PATTERN_NULL; scope_token=0;
  2593.             token = line_token-->(pcount-1);
  2594.             lookahead = line_token-->pcount;
  2595.             #ifdef DEBUG;
  2596.             if (parser_trace >= 2)
  2597.                print " [line ", line, " token ", pcount, " word ", wn, " : ",
  2598.                      (DebugToken) token, "]^";
  2599.             #endif;
  2600.             if (token ~= ENDIT_TOKEN)
  2601.             {   scope_reason = PARSING_REASON;
  2602.                 AnalyseToken(token);
  2603.                 l = ParseToken(found_ttype, found_tdata, pcount-1, token);
  2604.                 while (l<-200) l = ParseToken(ELEMENTARY_TT, l + 256);
  2605.                 scope_reason = PARSING_REASON;
  2606.                 if (l==GPR_PREPOSITION)
  2607.                 {   if (found_ttype~=PREPOSITION_TT
  2608.                         && (found_ttype~=ELEMENTARY_TT
  2609.                             || found_tdata~=TOPIC_TOKEN)) params_wanted--;
  2610.                     l = true;
  2611.                 }
  2612.                 else
  2613.                 if (l<0) l = false;
  2614.                 else
  2615.                 if (l~=GPR_REPARSE)
  2616.                 {   if (l==GPR_NUMBER)
  2617.                     {   if (nsns==0) special_number1=parsed_number;
  2618.                         else special_number2=parsed_number;
  2619.                         nsns++; l = 1;
  2620.                     }
  2621.                     if (l==GPR_MULTIPLE) l = 0;
  2622.                     results-->(parameters+2) = l;
  2623.                     parameters++;
  2624.                     pattern-->pcount = l;
  2625.                     l = true;
  2626.                 }
  2627.                 #ifdef DEBUG;
  2628.                 if (parser_trace >= 3)
  2629.                 {   print "  [token resulted in ";
  2630.                     if (l==REPARSE_CODE) print "re-parse request]^";
  2631.                     if (l==0) print "failure with error type ", etype, "]^";
  2632.                     if (l==1) print "success]^";
  2633.                 }
  2634.                 #endif;
  2635.                 if (l==REPARSE_CODE) jump ReParse;
  2636.                 if (l==false) break;
  2637.             }
  2638.             else
  2639.             {
  2640. !  If the player has entered enough already but there's still
  2641. !  text to wade through: store the pattern away so as to be able to produce
  2642. !  a decent error message if this turns out to be the best we ever manage,
  2643. !  and in the mean time give up on this line
  2644. !  However, if the superfluous text begins with a comma or "then" then
  2645. !  take that to be the start of another instruction
  2646.                 if (wn <= num_words)
  2647.                 {   l=NextWord();
  2648.                     if (l==THEN1__WD or THEN2__WD or THEN3__WD or comma_word)
  2649.                     {   held_back_mode=1; hb_wn=wn-1; }
  2650.                     else
  2651.                     {   for (m=0:m<32:m++) pattern2-->m=pattern-->m;
  2652.                         pcount2=pcount;
  2653.                         etype=UPTO_PE; break;
  2654.                     }
  2655.                 }
  2656. !  Now, we may need to revise the multiple object because of the single one
  2657. !  we now know (but didn't when the list was drawn up).
  2658.                 if (parameters>=1 && results-->2 == 0)
  2659.                 {   l=ReviseMulti(results-->3);
  2660.                     if (l~=0) { etype=l; break; }
  2661.                 }
  2662.                 if (parameters>=2 && results-->3 == 0)
  2663.                 {   l=ReviseMulti(results-->2);
  2664.                     if (l~=0) { etype=l; break; }
  2665.                 }
  2666. !  To trap the case of "take all" inferring only "yourself" when absolutely
  2667. !  nothing else is in the vicinity...
  2668.                 if (take_all_rule==2 && results-->2 == actor)
  2669.                 {   best_etype = NOTHING_PE; jump GiveError;
  2670.                 }
  2671.                 #ifdef DEBUG;
  2672.                 if (parser_trace>=1)
  2673.                     print "[Line successfully parsed]^";
  2674.                 #endif;
  2675. !  The line has successfully matched the text.  Declare the input error-free...
  2676.                 oops_from = 0;
  2677. !  ...explain any inferences made (using the pattern)...
  2678.                 if (inferfrom~=0)
  2679.                 {   print "("; PrintCommand(inferfrom); print ")^";
  2680.                 }
  2681. !  ...copy the action number, and the number of parameters...
  2682.                 results-->0 = action_to_be;
  2683.                 results-->1 = parameters;
  2684. !  ...reverse first and second parameters if need be...
  2685.                 if (action_reversed && parameters==2)
  2686.                 {   i = results-->2; results-->2 = results-->3;
  2687.                     results-->3 = i;
  2688.                     if (nsns == 2)
  2689.                     {   i = special_number1; special_number1=special_number2;
  2690.                         special_number2=i;
  2691.                     }
  2692.                 }
  2693. !  ...and to reset "it"-style objects to the first of these parameters, if
  2694. !  there is one (and it really is an object)...
  2695.                 if (parameters > 0 && results-->2 >= 2)
  2696.                     PronounNotice(results-->2);
  2697. !  ...and worry about the case where an object was allowed as a parameter
  2698. !  even though the player wasn't holding it and should have been: in this
  2699. !  event, keep the results for next time round, go into "not holding" mode,
  2700. !  and for now tell the player what's happening and return a "take" request
  2701. !  instead...
  2702.                 if (not_holding~=0 && actor==player)
  2703.                 {   notheld_mode=1;
  2704.                     for (i=0:i<8:i++) kept_results-->i = results-->i;
  2705.                     results-->0 = ##Take;
  2706.                     results-->1 = 1;
  2707.                     results-->2 = not_holding;
  2708.                     L__M(##Miscellany, 26, not_holding);
  2709.                 }
  2710. !  (Notice that implicit takes are only generated for the player, and not
  2711. !  for other actors.  This avoids entirely logical, but misleading, text
  2712. !  being printed.)
  2713. !  ...and return from the parser altogether, having successfully matched
  2714. !  a line.
  2715.                 if (held_back_mode==1) { wn=hb_wn; jump LookForMore; }
  2716.                 rtrue;
  2717.             }
  2718.         }
  2719. !  The line has failed to match.
  2720. !  We continue the outer "for" loop, trying the next line in the grammar.
  2721.         if (etype>best_etype) best_etype=etype;
  2722.         if (etype~=ASKSCOPE_PE && etype>nextbest_etype) nextbest_etype=etype;
  2723. !  ...unless the line was something like "take all" which failed because
  2724. !  nothing matched the "all", in which case we stop and give an error now.
  2725.         if (take_all_rule == 2 && etype==NOTHING_PE) break;
  2726. !  The grammar is exhausted: every line has failed to match.
  2727. !  **** (H) ****
  2728.   .GiveError;
  2729.         etype=best_etype;
  2730. !  Errors are handled differently depending on who was talking.
  2731. !  If the command was addressed to somebody else (eg, "dwarf, sfgh") then
  2732. !  it is taken as conversation which the parser has no business in disallowing.
  2733.     if (actor~=player)
  2734.     {   if (usual_grammar_after>0)
  2735.         {   verb_wordnum = usual_grammar_after;
  2736.             jump AlmostReParse;
  2737.         }
  2738.         wn=verb_wordnum;
  2739.         special_word=NextWord();
  2740.         if (special_word==comma_word)
  2741.         {   special_word=NextWord();
  2742.             verb_wordnum++;
  2743.         }
  2744.         special_number=TryNumber(verb_wordnum);
  2745.         results-->0=##NotUnderstood;
  2746.         results-->1=2;
  2747.         results-->2=1; special_number1=special_word;
  2748.         results-->3=actor;
  2749.         consult_from = verb_wordnum; consult_words = num_words-consult_from+1;
  2750.         rtrue;
  2751.     }
  2752. !  **** (I) ****
  2753. !  If the player was the actor (eg, in "take dfghh") the error must be printed,
  2754. !  and fresh input called for.  In three cases the oops word must be jiggled.
  2755.     if (ParserError(etype)~=0) jump ReType;
  2756.     pronoun_word = pronoun__word; pronoun_obj = pronoun__obj;
  2757.     if (etype==STUCK_PE)   { L__M(##Miscellany, 27); oops_from=1; }
  2758.     if (etype==UPTO_PE)    { L__M(##Miscellany, 28);
  2759.                              for (m=0:m<32:m++) pattern-->m = pattern2-->m;
  2760.                              pcount=pcount2; PrintCommand(0); print ".^";
  2761.                            }
  2762.     if (etype==NUMBER_PE)  L__M(##Miscellany, 29);
  2763.     if (etype==CANTSEE_PE) { L__M(##Miscellany, 30); oops_from=saved_oops; }
  2764.     if (etype==TOOLIT_PE)  L__M(##Miscellany, 31);
  2765.     if (etype==NOTHELD_PE) { L__M(##Miscellany, 32); oops_from=saved_oops; }
  2766.     if (etype==MULTI_PE)   L__M(##Miscellany, 33);
  2767.     if (etype==MMULTI_PE)  L__M(##Miscellany, 34);
  2768.     if (etype==VAGUE_PE)   L__M(##Miscellany, 35);
  2769.     if (etype==EXCEPT_PE)  L__M(##Miscellany, 36);
  2770.     if (etype==ANIMA_PE)   L__M(##Miscellany, 37);
  2771.     if (etype==VERB_PE)    L__M(##Miscellany, 38);
  2772.     if (etype==SCENERY_PE) L__M(##Miscellany, 39);
  2773.     if (etype==ITGONE_PE)
  2774.     {   if (pronoun_obj == NULL) L__M(##Miscellany, 35);
  2775.                             else L__M(##Miscellany, 40);
  2776.     }
  2777.     if (etype==JUNKAFTER_PE) L__M(##Miscellany, 41);
  2778.     if (etype==TOOFEW_PE)  L__M(##Miscellany, 42, multi_had);
  2779.     if (etype==NOTHING_PE) { if (multi_wanted==100) L__M(##Miscellany, 43);
  2780.                              else L__M(##Miscellany, 44);  }
  2781.     if (etype==ASKSCOPE_PE)
  2782.     {   scope_stage=3;
  2783.         if (indirect(scope_error)==-1)
  2784.         {   best_etype=nextbest_etype; jump GiveError;  }
  2785.     }
  2786. !  **** (J) ****
  2787. !  And go (almost) right back to square one...
  2788.     jump ReType;
  2789. !  ...being careful not to go all the way back, to avoid infinite repetition
  2790. !  of a deferred command causing an error.
  2791. !  **** (K) ****
  2792. !  At this point, the return value is all prepared, and we are only looking
  2793. !  to see if there is a "then" followed by subsequent instruction(s).
  2794.    .LookForMore;
  2795.    if (wn>num_words) rtrue;
  2796.    i=NextWord();
  2797.    if (i==THEN1__WD or THEN2__WD or THEN3__WD or comma_word)
  2798.    {   if (wn>num_words)
  2799.        {   held_back_mode = false; return; }
  2800.        i = WordAddress(verb_wordnum);
  2801.        j = WordAddress(wn);
  2802.        for (:i<j:i++) i->0 = ' ';
  2803.        i = NextWord();
  2804.        if (i==AGAIN1__WD or AGAIN2__WD or AGAIN3__WD)
  2805.        {   !   Delete the words "then again" from the again buffer,
  2806.            !   in which we have just realised that it must occur:
  2807.            !   prevents an infinite loop on "i. again"
  2808.            i = WordAddress(wn-2)-buffer;
  2809.            if (wn > num_words) j = 119; else j = WordAddress(wn)-buffer;
  2810.            for (:i<j:i++) buffer3->i = ' ';
  2811.        }
  2812.        Tokenise__(buffer,parse); held_back_mode = true; return;
  2813.    best_etype=UPTO_PE; jump GiveError;
  2814. [ ScopeCeiling person act;
  2815.   act = parent(person); if (act == 0) return person;
  2816.   if (person == player && location == thedark) return thedark;
  2817.   while (parent(act)~=0
  2818.          && (act has transparent || act has supporter
  2819.              || (act has container && act has open)))
  2820.       act = parent(act);
  2821.   return act;
  2822. ! ----------------------------------------------------------------------------
  2823. !  Descriptors()
  2824. !  Handles descriptive words like "my", "his", "another" and so on.
  2825. !  Skips "the", and leaves wn pointing to the first misunderstood word.
  2826. !  Allowed to set up for a plural only if allow_p is set
  2827. !  Returns error number, or 0 if no error occurred
  2828. ! ----------------------------------------------------------------------------
  2829. Constant OTHER_BIT  =   1;     !  These will be used in Adjudicate()
  2830. Constant MY_BIT     =   2;     !  to disambiguate choices
  2831. Constant THAT_BIT   =   4;
  2832. Constant PLURAL_BIT =   8;
  2833. Constant LIT_BIT    =  16;
  2834. Constant UNLIT_BIT  =  32;
  2835. [ ResetDescriptors;
  2836.    indef_mode=0; indef_type=0; indef_wanted=0; indef_guess_p=0;
  2837.    indef_possambig = false;
  2838.    indef_owner = nothing;
  2839.    indef_cases = $$111111111111;
  2840.    indef_nspec_at = 0;
  2841. [ Descriptors allow_multiple  o x flag cto type n;
  2842.    ResetDescriptors();
  2843.    if (wn > num_words) return 0;
  2844.    for (flag=true:flag:)
  2845.    {   o=NextWordStopped(); flag=false;
  2846.        for (x=1:x<=LanguageDescriptors-->0:x=x+4)
  2847.            if (o == LanguageDescriptors-->x)
  2848.            {   flag = true;
  2849.                type = LanguageDescriptors-->(x+2);
  2850.                if (type ~= DEFART_PK) indef_mode = true;
  2851.                indef_possambig = true;
  2852.                indef_cases = indef_cases & (LanguageDescriptors-->(x+1));
  2853.                if (type == POSSESS_PK)
  2854.                {   cto = LanguageDescriptors-->(x+3);
  2855.                    switch(cto)
  2856.                    {  0: indef_type = indef_type | MY_BIT;
  2857.                       1: indef_type = indef_type | THAT_BIT;
  2858.                       default: indef_owner = PronounValue(cto);
  2859.                         if (indef_owner == NULL) indef_owner = InformParser;
  2860.                    }
  2861.                }
  2862.                if (type == light)
  2863.                    indef_type = indef_type | LIT_BIT;
  2864.                if (type == -light)
  2865.                    indef_type = indef_type | UNLIT_BIT;
  2866.            }
  2867.        if (o==OTHER1__WD or OTHER2__WD or OTHER3__WD)
  2868.                             { indef_mode=1; flag=1;
  2869.                               indef_type = indef_type | OTHER_BIT; }
  2870.        if (o==ALL1__WD or ALL2__WD or ALL3__WD or ALL4__WD or ALL5__WD)
  2871.                             { indef_mode=1; flag=1; indef_wanted=100;
  2872.                               if (take_all_rule == 1)
  2873.                                   take_all_rule = 2;
  2874.                               indef_type = indef_type | PLURAL_BIT; }
  2875.        if (allow_plurals && allow_multiple)
  2876.        {   n=NumberWord(o);
  2877.            if (n==1)        { indef_mode=1; flag=1; }
  2878.            if (n>1)         { indef_guess_p=1;
  2879.                               indef_mode=1; flag=1; indef_wanted=n;
  2880.                               indef_nspec_at=wn-1;
  2881.                               indef_type = indef_type | PLURAL_BIT; }
  2882.        }
  2883.        if (flag==1
  2884.            && NextWordStopped() ~= OF1__WD or OF2__WD or OF3__WD or OF4__WD)
  2885.            wn--;  ! Skip 'of' after these
  2886.    wn--;
  2887.    if ((indef_wanted > 0) && (~~allow_multiple)) return MULTI_PE;
  2888.    return 0;
  2889. ! ----------------------------------------------------------------------------
  2890. !  CreatureTest: Will this person do for a "creature" token?
  2891. ! ----------------------------------------------------------------------------
  2892. [ CreatureTest obj;
  2893.   if (obj has animate) rtrue;
  2894.   if (obj hasnt talkable) rfalse;
  2895.   if (action_to_be == ##Ask or ##Answer or ##Tell or ##AskFor) rtrue;
  2896.   rfalse;
  2897. [ PrepositionChain wd index;
  2898.   if (line_tdata-->index == wd) return wd;
  2899.   if ((line_token-->index)->0 & $20 == 0) return -1;
  2900.   {   if (line_tdata-->index == wd) return wd;
  2901.       index++;
  2902.   until ((line_token-->index == ENDIT_TOKEN)
  2903.          || (((line_token-->index)->0 & $10) == 0));
  2904.   return -1;
  2905. ! ----------------------------------------------------------------------------
  2906. !  ParseToken(type, data):
  2907. !      Parses the given token, from the current word number wn, with exactly
  2908. !      the specification of a general parsing routine.
  2909. !      (Except that for "topic" tokens and prepositions, you need to supply
  2910. !      a position in a valid grammar line as third argument.)
  2911. !  Returns:
  2912. !    GPR_REPARSE  for "reconstructed input, please re-parse from scratch"
  2913. !    GPR_PREPOSITION  for "token accepted with no result"
  2914. !    $ff00 + x    for "please parse ParseToken(ELEMENTARY_TT, x) instead"
  2915. !    0            for "token accepted, result is the multiple object list"
  2916. !    1            for "token accepted, result is the number in parsed_number"
  2917. !    object num   for "token accepted with this object as result"
  2918. !    -1           for "token rejected"
  2919. !  (A)            Analyse the token; handle all tokens not involving
  2920. !                 object lists and break down others into elementary tokens
  2921. !  (B)            Begin parsing an object list
  2922. !  (C)            Parse descriptors (articles, pronouns, etc.) in the list
  2923. !  (D)            Parse an object name
  2924. !  (E)            Parse connectives ("and", "but", etc.) and go back to (C)
  2925. !  (F)            Return the conclusion of parsing an object list
  2926. ! ----------------------------------------------------------------------------
  2927. [ ParseToken given_ttype given_tdata token_n
  2928.              token l o i j k and_parity single_object desc_wn many_flag
  2929.              token_allows_multiple;
  2930. !  **** (A) ****
  2931.    token_filter = 0;
  2932.    parser_inflection = name;
  2933.    switch(given_ttype)
  2934.    {   ELEMENTARY_TT:
  2935.            switch(given_tdata)
  2936.            {   SPECIAL_TOKEN:
  2937.                    l=TryNumber(wn);
  2938.                    special_word=NextWord();
  2939.                    #ifdef DEBUG;
  2940.                    if (l~=-1000)
  2941.                        if (parser_trace>=3)
  2942.                            print "  [Read special as the number ", l, "]^";
  2943.                    #endif;
  2944.                    if (l==-1000)
  2945.                    {   #ifdef DEBUG;
  2946.                        if (parser_trace>=3)
  2947.                          print "  [Read special word at word number ", wn, "]^";
  2948.                        #endif;
  2949.                        l = special_word;
  2950.                    }
  2951.                    parsed_number = l; return 1;
  2952.                NUMBER_TOKEN:
  2953.                    l=TryNumber(wn++);
  2954.                    if (l==-1000) { etype=NUMBER_PE; rfalse; }
  2955.                    #ifdef DEBUG;
  2956.                    if (parser_trace>=3) print "  [Read number as ", l, "]^";
  2957.                    #endif;
  2958.                    parsed_number = l; return 1;
  2959.                CREATURE_TOKEN:
  2960.                    if (action_to_be==##Answer or ##Ask or ##AskFor or ##Tell)
  2961.                        scope_reason = TALKING_REASON;
  2962.                TOPIC_TOKEN:
  2963.                    consult_from = wn;
  2964.                    if ((line_ttype-->(token_n+1) ~= PREPOSITION_TT)
  2965.                        && (line_token-->(token_n+1) ~= ENDIT_TOKEN))
  2966.                        RunTimeError(13);
  2967.                    do o=NextWordStopped();
  2968.                    until (o==-1 || PrepositionChain(o, token_n+1) ~= -1);
  2969.                    wn--;
  2970.                    consult_words = wn-consult_from;
  2971.                    if (consult_words==0) return GPR_PREPOSITION;
  2972.                    if (action_to_be==##Ask or ##Answer or ##Tell)
  2973.                    {   o=wn; wn=consult_from; parsed_number=NextWord();
  2974.                        #IFDEF EnglishNaturalLanguage;
  2975.                        if (parsed_number=='the' && consult_words>1)
  2976.                            parsed_number=NextWord();
  2977.                        #ENDIF;
  2978.                        wn=o; return 1;
  2979.                    }
  2980.                    return GPR_PREPOSITION;
  2981.            }
  2982.        PREPOSITION_TT:
  2983.            #Iffalse Grammar__Version==1;
  2984. !  Is it an unnecessary alternative preposition, when a previous choice
  2985. !  has already been matched?
  2986.            if ((token->0) & $10) return GPR_PREPOSITION;
  2987.            #Endif;
  2988. !  If we've run out of the player's input, but still have parameters to
  2989. !  specify, we go into "infer" mode, remembering where we are and the
  2990. !  preposition we are inferring...
  2991.            if (wn > num_words)
  2992.            {   if (inferfrom==0 && parameters<params_wanted)
  2993.                {   inferfrom = pcount; inferword = token;
  2994.                    pattern-->pcount = REPARSE_CODE + Dword__No(given_tdata);
  2995.                }
  2996. !  If we are not inferring, then the line is wrong...
  2997.                if (inferfrom==0) return -1;
  2998. !  If not, then the line is right but we mark in the preposition...
  2999.                pattern-->pcount = REPARSE_CODE + Dword__No(given_tdata);
  3000.                return GPR_PREPOSITION;
  3001.            }
  3002.            o = NextWord();
  3003.            pattern-->pcount = REPARSE_CODE + Dword__No(o);
  3004. !  Whereas, if the player has typed something here, see if it is the
  3005. !  required preposition... if it's wrong, the line must be wrong,
  3006. !  but if it's right, the token is passed (jump to finish this token).
  3007.            if (o == given_tdata) return GPR_PREPOSITION;
  3008.            #Iffalse Grammar__Version==1;
  3009.            if (PrepositionChain(o, token_n) ~= -1)
  3010.                return GPR_PREPOSITION;
  3011.            #Endif;
  3012.            return -1;
  3013.        GPR_TT:
  3014.            l=indirect(given_tdata);
  3015.            #ifdef DEBUG;
  3016.            if (parser_trace>=3)
  3017.                print "  [Outside parsing routine returned ", l, "]^";
  3018.            #endif;
  3019.            return l;
  3020.        SCOPE_TT:
  3021.            scope_token = given_tdata;
  3022.            scope_stage = 1;
  3023.            l = indirect(scope_token);
  3024.            #ifdef DEBUG;
  3025.            if (parser_trace>=3)
  3026.                print "  [Scope routine returned multiple-flag of ", l, "]^";
  3027.            #endif;
  3028.            if (l==1) given_tdata = MULTI_TOKEN; else given_tdata = NOUN_TOKEN;
  3029.        ATTR_FILTER_TT:
  3030.            token_filter = 1 + given_tdata;
  3031.            given_tdata = NOUN_TOKEN;
  3032.        ROUTINE_FILTER_TT:
  3033.            token_filter = given_tdata;
  3034.            given_tdata = NOUN_TOKEN;
  3035.    token = given_tdata;
  3036. !  **** (B) ****
  3037. !  There are now three possible ways we can be here:
  3038. !      parsing an elementary token other than "special" or "number";
  3039. !      parsing a scope token;
  3040. !      parsing a noun-filter token (either by routine or attribute).
  3041. !  In each case, token holds the type of elementary parse to
  3042. !  perform in matching one or more objects, and
  3043. !  token_filter is 0 (default), an attribute + 1 for an attribute filter
  3044. !  or a routine address for a routine filter.
  3045.    token_allows_multiple = false;
  3046.    if (token == MULTI_TOKEN or MULTIHELD_TOKEN or MULTIEXCEPT_TOKEN
  3047.                 or MULTIINSIDE_TOKEN) token_allows_multiple = true;
  3048.    many_flag = false; and_parity = true; dont_infer = false;
  3049. !  **** (C) ****
  3050. !  We expect to find a list of objects next in what the player's typed.
  3051.   .ObjectList;
  3052.    #ifdef DEBUG;
  3053.    if (parser_trace>=3) print "  [Object list from word ", wn, "]^";
  3054.    #endif;
  3055. !  Take an advance look at the next word: if it's "it" or "them", and these
  3056. !  are unset, set the appropriate error number and give up on the line
  3057. !  (if not, these are still parsed in the usual way - it is not assumed
  3058. !  that they still refer to something in scope)
  3059.     o=NextWord(); wn--;
  3060.     pronoun_word = NULL; pronoun_obj = NULL;
  3061.     l = PronounValue(o);
  3062.     if (l ~= 0)
  3063.     {   pronoun_word = o; pronoun_obj = l;
  3064.         if (l == NULL)
  3065.         {   !   Don't assume this is a use of an unset pronoun until the
  3066.             !   descriptors have been checked, because it might be an
  3067.             !   article (or some such) instead
  3068.             for (l=1:l<=LanguageDescriptors-->0:l=l+4)
  3069.                 if (o == LanguageDescriptors-->l) jump AssumeDescriptor;
  3070.             pronoun__word=pronoun_word; pronoun__obj=pronoun_obj;
  3071.             etype=VAGUE_PE; return 0;
  3072.         }
  3073.     }
  3074.     .AssumeDescriptor;
  3075.     if (o==ME1__WD or ME2__WD or ME3__WD)
  3076.     {   pronoun_word = o; pronoun_obj = player;
  3077.     }
  3078.     allow_plurals = true; desc_wn = wn;
  3079.     .TryAgain;
  3080. !   First, we parse any descriptive words (like "the", "five" or "every"):
  3081.     l = Descriptors(token_allows_multiple); if (l~=0) { etype=l; return 0; }
  3082.     .TryAgain2;
  3083. !  **** (D) ****
  3084. !  This is an actual specified object, and is therefore where a typing error
  3085. !  is most likely to occur, so we set:
  3086.     oops_from = wn;
  3087. !  So, two cases.  Case 1: token not equal to "held" (so, no implicit takes)
  3088. !  but we may well be dealing with multiple objects
  3089. !  In either case below we use NounDomain, giving it the token number as
  3090. !  context, and two places to look: among the actor's possessions, and in the
  3091. !  present location.  (Note that the order depends on which is likeliest.)
  3092.     if (token ~= HELD_TOKEN)
  3093.     {   i=multiple_object-->0;
  3094.         #ifdef DEBUG;
  3095.         if (parser_trace>=3)
  3096.             print "  [Calling NounDomain on location and actor]^";
  3097.         #endif;
  3098.         l=NounDomain(actors_location, actor, token);
  3099.         if (l==REPARSE_CODE) return l;                  ! Reparse after Q&A
  3100.         if (l==0) {   if (indef_possambig)
  3101.                       {   ResetDescriptors(); wn = desc_wn; jump TryAgain2; }
  3102.                       etype=CantSee(); jump FailToken; } ! Choose best error
  3103.         #ifdef DEBUG;
  3104.         if (parser_trace>=3)
  3105.         {   if (l>1)
  3106.                 print "  [ND returned ", (the) l, "]^";
  3107.             else
  3108.             {   print "  [ND appended to the multiple object list:^";
  3109.                 k=multiple_object-->0;
  3110.                 for (j=i+1:j<=k:j++)
  3111.                     print "  Entry ", j, ": ", (The) multiple_object-->j,
  3112.                           " (", multiple_object-->j, ")^";
  3113.                 print "  List now has size ", k, "]^";
  3114.             }
  3115.         }
  3116.         #endif;
  3117.         if (l==1)
  3118.         {   if (~~many_flag)
  3119.             {   many_flag = true;
  3120.             }
  3121.             else                                  ! Merge with earlier ones
  3122.             {   k=multiple_object-->0;            ! (with either parity)
  3123.                 multiple_object-->0 = i;
  3124.                 for (j=i+1:j<=k:j++)
  3125.                 {   if (and_parity) MultiAdd(multiple_object-->j);
  3126.                     else MultiSub(multiple_object-->j);
  3127.                 }
  3128.                 #ifdef DEBUG;
  3129.                 if (parser_trace>=3)
  3130.                     print "  [Merging ", k-i, " new objects to the ",
  3131.                         i, " old ones]^";
  3132.                 #endif;
  3133.             }
  3134.         }
  3135.         else
  3136.         {   ! A single object was indeed found
  3137.             if (match_length == 0 && indef_possambig)
  3138.             {   !   So the answer had to be inferred from no textual data,
  3139.                 !   and we know that there was an ambiguity in the descriptor
  3140.                 !   stage (such as a word which could be a pronoun being
  3141.                 !   parsed as an article or possessive).  It's worth having
  3142.                 !   another go.
  3143.                 ResetDescriptors(); wn = desc_wn; jump TryAgain2;
  3144.             }
  3145.         
  3146.             if (token==CREATURE_TOKEN && CreatureTest(l)==0)
  3147.             {   etype=ANIMA_PE; jump FailToken; } !  Animation is required
  3148.             if (~~many_flag)
  3149.                 single_object = l;
  3150.             else
  3151.             {   if (and_parity) MultiAdd(l); else MultiSub(l);
  3152.                 #ifdef DEBUG;
  3153.                 if (parser_trace>=3)
  3154.                     print "  [Combining ", (the) l, " with list]^";
  3155.                 #endif;
  3156.             }
  3157.         }
  3158.     }
  3159. !  Case 2: token is "held" (which fortunately can't take multiple objects)
  3160. !  and may generate an implicit take
  3161.     else
  3162.     {   l=NounDomain(actor,actors_location,token);       ! Same as above...
  3163.         if (l==REPARSE_CODE) return l;
  3164.         if (l==0)
  3165.         {   if (indef_possambig)
  3166.             {   ResetDescriptors(); wn = desc_wn; jump TryAgain2; }
  3167.             etype=CantSee(); return l;                   ! Choose best error
  3168.         }
  3169. !  ...until it produces something not held by the actor.  Then an implicit
  3170. !  take must be tried.  If this is already happening anyway, things are too
  3171. !  confused and we have to give up (but saving the oops marker so as to get
  3172. !  it on the right word afterwards).
  3173. !  The point of this last rule is that a sequence like
  3174. !      > read newspaper
  3175. !      (taking the newspaper first)
  3176. !      The dwarf unexpectedly prevents you from taking the newspaper!
  3177. !  should not be allowed to go into an infinite repeat - read becomes
  3178. !  take then read, but take has no effect, so read becomes take then read...
  3179. !  Anyway for now all we do is record the number of the object to take.
  3180.         o=parent(l);
  3181.         if (o~=actor)
  3182.         {   if (notheld_mode==1)
  3183.             {   saved_oops=oops_from; etype=NOTHELD_PE; jump FailToken;
  3184.             }
  3185.             not_holding = l;
  3186.             #ifdef DEBUG;
  3187.             if (parser_trace>=3)
  3188.                 print "  [Allowing object ", (the) l, " for now]^";
  3189.             #endif;
  3190.         }
  3191.         single_object = l;
  3192.     }
  3193. !  The following moves the word marker to just past the named object...
  3194.     wn = oops_from + match_length;
  3195. !  **** (E) ****
  3196. !  Object(s) specified now: is that the end of the list, or have we reached
  3197. !  "and", "but" and so on?  If so, create a multiple-object list if we
  3198. !  haven't already (and are allowed to).
  3199.     .NextInList;
  3200.     o=NextWord();
  3201.     if (o==AND1__WD or AND2__WD or AND3__WD or BUT1__WD or BUT2__WD or BUT3__WD
  3202.            or comma_word)
  3203.     {
  3204.         #ifdef DEBUG;
  3205.         if (parser_trace>=3) print "  [Read connective '", (address) o, "']^";
  3206.         #endif;
  3207.         if (~~token_allows_multiple)
  3208.         {   etype=MULTI_PE; jump FailToken;
  3209.         }
  3210.         if (o==BUT1__WD or BUT2__WD or BUT3__WD) and_parity = 1-and_parity;
  3211.         if (~~many_flag)
  3212.         {   multiple_object-->0 = 1;
  3213.             multiple_object-->1 = single_object;
  3214.             many_flag = true;
  3215.             #ifdef DEBUG;
  3216.             if (parser_trace>=3)
  3217.                 print "  [Making new list from ", (the) single_object, "]^";
  3218.             #endif;
  3219.         }
  3220.         dont_infer = true; inferfrom=0;           ! Don't print (inferences)
  3221.         jump ObjectList;                          ! And back around
  3222.     }
  3223.     wn--;   ! Word marker back to first not-understood word
  3224. !  **** (F) ****
  3225. !  Happy or unhappy endings:
  3226.     .PassToken;
  3227.     if (many_flag)
  3228.     {   single_object = GPR_MULTIPLE;
  3229.         multi_context = token;
  3230.     }
  3231.     else
  3232.     {   if (indef_mode==1 && indef_type & PLURAL_BIT ~= 0)
  3233.         {   if (indef_wanted<100 && indef_wanted>1)
  3234.             {   multi_had=1; multi_wanted=indef_wanted;
  3235.                 etype=TOOFEW_PE;
  3236.                 jump FailToken;
  3237.             }
  3238.         }
  3239.     }
  3240.     return single_object;
  3241.     .FailToken;
  3242. !  If we were only guessing about it being a plural, try again but only
  3243. !  allowing singulars (so that words like "six" are not swallowed up as
  3244. !  Descriptors)
  3245.     if (allow_plurals && indef_guess_p==1)
  3246.     {   allow_plurals=false; wn=desc_wn; jump TryAgain;
  3247.     }
  3248.     return -1;
  3249. ! ----------------------------------------------------------------------------
  3250. !  NounDomain does the most substantial part of parsing an object name.
  3251. !  It is given two "domains" - usually a location and then the actor who is
  3252. !  looking - and a context (i.e. token type), and returns:
  3253. !   0    if no match at all could be made,
  3254. !   1    if a multiple object was made,
  3255. !   k    if object k was the one decided upon,
  3256. !   REPARSE_CODE if it asked a question of the player and consequently rewrote
  3257. !        the player's input, so that the whole parser should start again
  3258. !        on the rewritten input.
  3259. !   In the case when it returns 1<k<REPARSE_CODE, it also sets the variable
  3260. !   length_of_noun to the number of words in the input text matched to the
  3261. !   noun.
  3262. !   In the case k=1, the multiple objects are added to multiple_object by
  3263. !   hand (not by MultiAdd, because we want to allow duplicates).
  3264. ! ----------------------------------------------------------------------------
  3265. [ NounDomain domain1 domain2 context    first_word i j k l
  3266.                                         answer_words marker;
  3267. #ifdef DEBUG;
  3268.   if (parser_trace>=4)
  3269.   {   print "   [NounDomain called at word ", wn, "^";
  3270.       print "   ";
  3271.       if (indef_mode)
  3272.       {   print "seeking indefinite object: ";
  3273.           if (indef_type & OTHER_BIT)  print "other ";
  3274.           if (indef_type & MY_BIT)     print "my ";
  3275.           if (indef_type & THAT_BIT)   print "that ";
  3276.           if (indef_type & PLURAL_BIT) print "plural ";
  3277.           if (indef_type & LIT_BIT)    print "lit ";
  3278.           if (indef_type & UNLIT_BIT)  print "unlit ";
  3279.           if (indef_owner ~= 0) print "owner:", (name) indef_owner;
  3280.           new_line;
  3281.           print "   number wanted: ";
  3282.           if (indef_wanted == 100) print "all"; else print indef_wanted;
  3283.           new_line;
  3284.           print "   most likely GNAs of names: ", indef_cases, "^";
  3285.       }
  3286.       else print "seeking definite object^";
  3287. #endif;
  3288.   match_length=0; number_matched=0; match_from=wn; placed_in_flag=0;
  3289.   SearchScope(domain1, domain2, context);
  3290. #ifdef DEBUG;
  3291.   if (parser_trace>=4) print "   [ND made ", number_matched, " matches]^";
  3292. #endif;
  3293.   wn=match_from+match_length;
  3294. !  If nothing worked at all, leave with the word marker skipped past the
  3295. !  first unmatched word...
  3296.   if (number_matched==0) { wn++; rfalse; }
  3297. !  Suppose that there really were some words being parsed (i.e., we did
  3298. !  not just infer).  If so, and if there was only one match, it must be
  3299. !  right and we return it...
  3300.   if (match_from <= num_words)
  3301.   {   if (number_matched==1) { i=match_list-->0; return i; }
  3302. !  ...now suppose that there was more typing to come, i.e. suppose that
  3303. !  the user entered something beyond this noun.  If nothing ought to follow,
  3304. !  then there must be a mistake, (unless what does follow is just a full
  3305. !  stop, and or comma)
  3306.       if (wn<=num_words)
  3307.       {   i=NextWord(); wn--;
  3308.           if (i ~=  AND1__WD or AND2__WD or AND3__WD or comma_word
  3309.                  or THEN1__WD or THEN2__WD or THEN3__WD
  3310.                  or BUT1__WD or BUT2__WD or BUT3__WD)
  3311.           {   if (lookahead==ENDIT_TOKEN) rfalse;
  3312.           }
  3313.       }
  3314. !  Now look for a good choice, if there's more than one choice...
  3315.   number_of_classes=0;
  3316.   if (number_matched==1) i=match_list-->0;
  3317.   if (number_matched>1)
  3318.   {   i=Adjudicate(context);
  3319.       if (i==-1) rfalse;
  3320.       if (i==1) rtrue;       !  Adjudicate has made a multiple
  3321.                              !  object, and we pass it on
  3322. !  If i is non-zero here, one of two things is happening: either
  3323. !  (a) an inference has been successfully made that object i is
  3324. !      the intended one from the user's specification, or
  3325. !  (b) the user finished typing some time ago, but we've decided
  3326. !      on i because it's the only possible choice.
  3327. !  In either case we have to keep the pattern up to date,
  3328. !  note that an inference has been made and return.
  3329. !  (Except, we don't note which of a pile of identical objects.)
  3330.   if (i~=0)
  3331.   {   if (dont_infer) return i;
  3332.       if (inferfrom==0) inferfrom=pcount;
  3333.       pattern-->pcount = i;
  3334.       return i;
  3335. !  If we get here, there was no obvious choice of object to make.  If in
  3336. !  fact we've already gone past the end of the player's typing (which
  3337. !  means the match list must contain every object in scope, regardless
  3338. !  of its name), then it's foolish to give an enormous list to choose
  3339. !  from - instead we go and ask a more suitable question...
  3340.   if (match_from > num_words) jump Incomplete;
  3341. !  Now we print up the question, using the equivalence classes as worked
  3342. !  out by Adjudicate() so as not to repeat ourselves on plural objects...
  3343.   if (context==CREATURE_TOKEN)
  3344.       L__M(##Miscellany, 45); else L__M(##Miscellany, 46);
  3345.   j=number_of_classes; marker=0;
  3346.   for (i=1:i<=number_of_classes:i++)
  3347.   {   
  3348.       while (((match_classes-->marker) ~= i)
  3349.              && ((match_classes-->marker) ~= -i)) marker++;
  3350.       k=match_list-->marker;
  3351.       if (match_classes-->marker > 0) print (the) k; else print (a) k;
  3352.       if (i<j-1)  print ", ";
  3353.       if (i==j-1) print (string) OR__TX;
  3354.   print "?^";
  3355. !  ...and get an answer:
  3356.   .WhichOne;
  3357.   for (i=2:i<120:i++) buffer2->i=' ';
  3358.   answer_words=Keyboard(buffer2, parse2);
  3359.   first_word=(parse2-->1);
  3360. !  Take care of "all", because that does something too clever here to do
  3361. !  later on:
  3362.   if (first_word == ALL1__WD or ALL2__WD or ALL3__WD or ALL4__WD or ALL5__WD)
  3363.   {   
  3364.       if (context == MULTI_TOKEN or MULTIHELD_TOKEN or MULTIEXCEPT_TOKEN
  3365.                      or MULTIINSIDE_TOKEN)
  3366.       {   l=multiple_object-->0;
  3367.           for (i=0:i<number_matched && l+i<63:i++)
  3368.           {   k=match_list-->i;
  3369.               multiple_object-->(i+1+l) = k;
  3370.           }
  3371.           multiple_object-->0 = i+l;
  3372.           rtrue;
  3373.       }
  3374.       L__M(##Miscellany, 47);
  3375.       jump WhichOne;
  3376. !  If the first word of the reply can be interpreted as a verb, then
  3377. !  assume that the player has ignored the question and given a new
  3378. !  command altogether.
  3379. !  (This is one time when it's convenient that the directions are
  3380. !  not themselves verbs - thus, "north" as a reply to "Which, the north
  3381. !  or south door" is not treated as a fresh command but as an answer.)
  3382.   #ifdef LanguageIsVerb;
  3383.   if (first_word==0)
  3384.   {   j = wn; first_word=LanguageIsVerb(buffer2, parse2, 1); wn = j;
  3385.   #endif;
  3386.   if (first_word ~= 0)
  3387.   {   j=first_word->#dict_par1;
  3388.       if ((0~=j&1) && (first_word ~= 'long' or 'short' or 'normal'
  3389.                                      or 'brief' or 'full' or 'verbose'))
  3390.       {   CopyBuffer(buffer, buffer2);
  3391.           return REPARSE_CODE;
  3392.       }
  3393. !  Now we insert the answer into the original typed command, as
  3394. !  words additionally describing the same object
  3395. !  (eg, > take red button
  3396. !       Which one, ...
  3397. !       > music
  3398. !  becomes "take music red button".  The parser will thus have three
  3399. !  words to work from next time, not two.)
  3400.   k = WordAddress(match_from) - buffer; l=buffer2->1+1;
  3401.   for (j=buffer + buffer->0 - 1: j>= buffer+k+l: j--)
  3402.       j->0 = 0->(j-l);
  3403.   for (i=0:i<l:i++) buffer->(k+i) = buffer2->(2+i);
  3404.   buffer->(k+l-1) = ' ';
  3405.   buffer->1 = buffer->1 + l;
  3406.   if (buffer->1 >= (buffer->0 - 1)) buffer->1 = buffer->0;
  3407. !  Having reconstructed the input, we warn the parser accordingly
  3408. !  and get out.
  3409.   return REPARSE_CODE;
  3410. !  Now we come to the question asked when the input has run out
  3411. !  and can't easily be guessed (eg, the player typed "take" and there
  3412. !  were plenty of things which might have been meant).
  3413.   .Incomplete;
  3414.   if (context==CREATURE_TOKEN)
  3415.       L__M(##Miscellany, 48); else L__M(##Miscellany, 49);
  3416.   for (i=2:i<120:i++) buffer2->i=' ';
  3417.   answer_words=Keyboard(buffer2, parse2);
  3418.   first_word=(parse2-->1);
  3419.   #ifdef LanguageIsVerb;
  3420.   if (first_word==0)
  3421.   {   j = wn; first_word=LanguageIsVerb(buffer2, parse2, 1); wn = j;
  3422.   #endif;
  3423. !  Once again, if the reply looks like a command, give it to the
  3424. !  parser to get on with and forget about the question...
  3425.   if (first_word ~= 0)
  3426.   {   j=first_word->#dict_par1;
  3427.       if (0~=j&1)
  3428.       {   CopyBuffer(buffer, buffer2);
  3429.           return REPARSE_CODE;
  3430.       }
  3431. !  ...but if we have a genuine answer, then:
  3432. !  (1) we must glue in text suitable for anything that's been inferred.
  3433.   if (inferfrom ~= 0)
  3434.   {   for (j = inferfrom: j<pcount: j++)
  3435.       {   if (pattern-->j == PATTERN_NULL) continue;
  3436.           i=2+buffer->1; (buffer->1)++; buffer->(i++) = ' ';
  3437.           if (parser_trace >= 5)
  3438.           print "[Gluing in inference with pattern code ", pattern-->j, "]^";
  3439.           parse2-->1 = 0;
  3440.           ! An inferred object.  Best we can do is glue in a pronoun.
  3441.           ! (This is imperfect, but it's very seldom needed anyway.)
  3442.           if (pattern-->j >= 2 && pattern-->j < REPARSE_CODE)
  3443.           {   PronounNotice(pattern-->j);
  3444.               for (k=1: k<=LanguagePronouns-->0: k=k+3)
  3445.                   if (pattern-->j == LanguagePronouns-->(k+2))
  3446.                   {   parse2-->1 = LanguagePronouns-->k;
  3447.                       if (parser_trace >= 5)
  3448.                       print "[Using pronoun '", (address) parse2-->1, "']^";
  3449.                       break;
  3450.                   }
  3451.           }
  3452.           else
  3453.           {   ! An inferred preposition.
  3454.               parse2-->1 = No__Dword(pattern-->j - REPARSE_CODE);
  3455.               if (parser_trace >= 5)
  3456.                   print "[Using preposition '", (address) parse2-->1, "']^";
  3457.           }
  3458.           ! parse2-->1 now holds the dictionary address of the word to glue in.
  3459.           if (parse2-->1 ~= 0)
  3460.           {   k = buffer + i;
  3461.               @output_stream 3 k;
  3462.               print (address) parse2-->1;
  3463.               @output_stream -3;
  3464.               k = k-->0;
  3465.               for (l=i:l<i+k:l++) buffer->l = buffer->(l+2);
  3466.               i = i + k; buffer->1 = i-2;
  3467.           }
  3468.       }
  3469. !  (2) we must glue the newly-typed text onto the end.
  3470.   i=2+buffer->1; (buffer->1)++; buffer->(i++) = ' ';
  3471.   for (j=0: j<buffer2->1: i++, j++)
  3472.   {   buffer->i = buffer2->(j+2);
  3473.       (buffer->1)++;
  3474.       if (buffer->1 == 120) break;
  3475.   }    
  3476. !  (3) we fill up the buffer with spaces, which is unnecessary, but may
  3477. !      help incorrectly-written interpreters to cope.
  3478.   for (:i<120:i++) buffer->i = ' ';
  3479.   return REPARSE_CODE;
  3480. ! ----------------------------------------------------------------------------
  3481. !  The Adjudicate routine tries to see if there is an obvious choice, when
  3482. !  faced with a list of objects (the match_list) each of which matches the
  3483. !  player's specification equally well.
  3484. !  To do this it makes use of the context (the token type being worked on).
  3485. !  It counts up the number of obvious choices for the given context
  3486. !  (all to do with where a candidate is, except for 6 (animate) which is to
  3487. !  do with whether it is animate or not);
  3488. !  if only one obvious choice is found, that is returned;
  3489. !  if we are in indefinite mode (don't care which) one of the obvious choices
  3490. !    is returned, or if there is no obvious choice then an unobvious one is
  3491. !    made;
  3492. !  at this stage, we work out whether the objects are distinguishable from
  3493. !    each other or not: if they are all indistinguishable from each other,
  3494. !    then choose one, it doesn't matter which;
  3495. !  otherwise, 0 (meaning, unable to decide) is returned (but remember that
  3496. !    the equivalence classes we've just worked out will be needed by other
  3497. !    routines to clear up this mess, so we can't economise on working them
  3498. !    out).
  3499. !  Returns -1 if an error occurred
  3500. ! ----------------------------------------------------------------------------
  3501. [ Adjudicate context i j k good_ones last n ultimate flag offset;
  3502. #ifdef DEBUG;
  3503.   if (parser_trace>=4)
  3504.   {   print "   [Adjudicating match list of size ", number_matched,
  3505.           " in context ", context, "^";
  3506.       print "   ";
  3507.       if (indef_mode)
  3508.       {   print "indefinite type: ";
  3509.           if (indef_type & OTHER_BIT)  print "other ";
  3510.           if (indef_type & MY_BIT)     print "my ";
  3511.           if (indef_type & THAT_BIT)   print "that ";
  3512.           if (indef_type & PLURAL_BIT) print "plural ";
  3513.           if (indef_type & LIT_BIT)    print "lit ";
  3514.           if (indef_type & UNLIT_BIT)  print "unlit ";
  3515.           if (indef_owner ~= 0) print "owner:", (name) indef_owner;
  3516.           new_line;
  3517.           print "   number wanted: ";
  3518.           if (indef_wanted == 100) print "all"; else print indef_wanted;
  3519.           new_line;
  3520.           print "   most likely GNAs of names: ", indef_cases, "^";
  3521.       }
  3522.       else print "definite object^";
  3523. #endif;
  3524.   j=number_matched-1; good_ones=0; last=match_list-->0;
  3525.   for (i=0:i<=j:i++)
  3526.   {   n=match_list-->i;
  3527.       match_scores-->i = good_ones;
  3528.       ultimate=ScopeCeiling(n);
  3529. !      if (context==NOUN_TOKEN && ultimate==ScopeCeiling(actor)
  3530. !          && n~=actor && n hasnt concealed && n hasnt scenery &&
  3531. !          (token_filter==0 || UserFilter(n)==1)) { good_ones++; last=n; }
  3532.       if (context==HELD_TOKEN && parent(n)==actor)
  3533.       {   good_ones++; last=n; }
  3534.       if (context==MULTI_TOKEN && ultimate==ScopeCeiling(actor)
  3535.           && n~=actor && n hasnt concealed && n hasnt scenery) 
  3536.       {   good_ones++; last=n; }
  3537.       if (context==MULTIHELD_TOKEN && parent(n)==actor)
  3538.       {   good_ones++; last=n; }
  3539.       if (context==MULTIEXCEPT_TOKEN or MULTIINSIDE_TOKEN)
  3540.       {   if (advance_warning==-1)
  3541.           {   if (context==MULTIEXCEPT_TOKEN)
  3542.               {   good_ones++; last=n;
  3543.               }
  3544.               if (context==MULTIINSIDE_TOKEN)
  3545.               {   if (parent(n)~=actor) { good_ones++; last=n; }
  3546.               }
  3547.           }
  3548.           else
  3549.           {   if (context==MULTIEXCEPT_TOKEN && n~=advance_warning)
  3550.               {   good_ones++; last=n; }
  3551.               if (context==MULTIINSIDE_TOKEN && n in advance_warning)
  3552.               {   good_ones++; last=n; }
  3553.           }
  3554.       }
  3555.       if (context==CREATURE_TOKEN && CreatureTest(n)==1)
  3556.       {   good_ones++; last=n; }
  3557.       match_scores-->i = 1000*(good_ones - match_scores-->i);
  3558.   if (good_ones==1) return last;
  3559.   ! If there is ambiguity about what was typed, but it definitely wasn't
  3560.   ! animate as required, then return anything; higher up in the parser
  3561.   ! a suitable error will be given.  (This prevents a question being asked.)
  3562.   if (context==CREATURE_TOKEN && good_ones==0) return match_list-->0;
  3563.   if (indef_mode==0) indef_type=0;
  3564.   ScoreMatchL();
  3565.   if (number_matched == 0) return -1;
  3566.   if (indef_mode == 0)
  3567.   {   !  Is there now a single highest-scoring object?
  3568.       i = SingleBestGuess();
  3569.       if (i >= 0)
  3570.       {   
  3571. #ifdef DEBUG;
  3572.           if (parser_trace>=4)
  3573.               print "   Single best-scoring object returned.]^";
  3574. #endif;
  3575.           return i;
  3576.       }
  3577.   if (indef_mode==1 && indef_type & PLURAL_BIT ~= 0)
  3578.   {   if (context ~= MULTI_TOKEN or MULTIHELD_TOKEN or MULTIEXCEPT_TOKEN
  3579.                      or MULTIINSIDE_TOKEN)
  3580.       {   etype=MULTI_PE; return -1; }
  3581.       i=0; offset=multiple_object-->0;
  3582.       for (j=BestGuess():j~=-1 && i<indef_wanted
  3583.            && i+offset<63:j=BestGuess())
  3584.       {   flag=0;
  3585.           if (j hasnt concealed && j hasnt worn) flag=1;
  3586.           if (context==MULTIHELD_TOKEN or MULTIEXCEPT_TOKEN
  3587.               && parent(j)~=actor) flag=0;
  3588.           k=ChooseObjects(j,flag);
  3589.           if (k==1) flag=1; else { if (k==2) flag=0; }
  3590.           if (flag==1)
  3591.           {   i++; multiple_object-->(i+offset) = j;
  3592. #ifdef DEBUG;
  3593.               if (parser_trace>=4) print "   Accepting it^";
  3594. #endif;
  3595.           }
  3596.           else
  3597.           {   i=i;
  3598. #ifdef DEBUG;
  3599.               if (parser_trace>=4) print "   Rejecting it^";
  3600. #endif;
  3601.           }
  3602.       }
  3603.       if (i<indef_wanted && indef_wanted<100)
  3604.       {   etype=TOOFEW_PE; multi_wanted=indef_wanted;
  3605.           multi_had=i;
  3606.           return -1;
  3607.       }
  3608.       multiple_object-->0 = i+offset;
  3609.       multi_context=context;
  3610. #ifdef DEBUG;
  3611.       if (parser_trace>=4)
  3612.           print "   Made multiple object of size ", i, "]^";
  3613. #endif;
  3614.       return 1;
  3615.   for (i=0:i<number_matched:i++) match_classes-->i=0;
  3616.   n=1;
  3617.   for (i=0:i<number_matched:i++)
  3618.       if (match_classes-->i==0)
  3619.       {   match_classes-->i=n++; flag=0;
  3620.           for (j=i+1:j<number_matched:j++)
  3621.               if (match_classes-->j==0
  3622.                   && Identical(match_list-->i, match_list-->j)==1)
  3623.               {   flag=1;
  3624.                   match_classes-->j=match_classes-->i;
  3625.               }
  3626.           if (flag==1) match_classes-->i = 1-n;
  3627.       }
  3628.   n--; number_of_classes = n;
  3629. #ifdef DEBUG;
  3630.   if (parser_trace>=4)
  3631.   {   print "   Grouped into ", n, " possibilities by name:^";
  3632.       for (i=0:i<number_matched:i++)
  3633.           if (match_classes-->i > 0)
  3634.               print "   ", (The) match_list-->i,
  3635.                   " (", match_list-->i, ")  ---  group ",
  3636.                   match_classes-->i, "^";
  3637. #endif;
  3638.   if (indef_mode == 0)
  3639.   {   if (n > 1)
  3640.       {   k = -1;
  3641.           for (i=0:i<number_matched:i++)
  3642.           {   if (match_scores-->i > k)
  3643.               {   k = match_scores-->i;
  3644.                   j = match_classes-->i; j=j*j;
  3645.                   flag = 0;
  3646.               }
  3647.               else
  3648.               if (match_scores-->i == k)
  3649.               {   if ((match_classes-->i) * (match_classes-->i) ~= j)
  3650.                       flag = 1;
  3651.               }
  3652.           }
  3653.           if (flag)
  3654.           {
  3655. #ifdef DEBUG;
  3656.               if (parser_trace>=4)
  3657.                   print "   Unable to choose best group, so ask player.]^";
  3658. #endif;
  3659.               return 0;
  3660.           }
  3661. #ifdef DEBUG;
  3662.           if (parser_trace>=4)
  3663.               print "   Best choices are all from the same group.^";
  3664. #endif;          
  3665.       }
  3666. !  When the player is really vague, or there's a single collection of
  3667. !  indistinguishable objects to choose from, choose the one the player
  3668. !  most recently acquired, or if the player has none of them, then
  3669. !  the one most recently put where it is.
  3670.   if (n==1) dont_infer = true;
  3671.   return BestGuess();
  3672. ! ----------------------------------------------------------------------------
  3673. !  ReviseMulti  revises the multiple object which already exists, in the
  3674. !    light of information which has come along since then (i.e., the second
  3675. !    parameter).  It returns a parser error number, or else 0 if all is well.
  3676. !    This only ever throws things out, never adds new ones.
  3677. ! ----------------------------------------------------------------------------
  3678. [ ReviseMulti second_p  i low;
  3679. #ifdef DEBUG;
  3680.   if (parser_trace>=4)
  3681.       print "   Revising multiple object list of size ", multiple_object-->0,
  3682.             " with 2nd ", (name) second_p, "^";
  3683. #endif;
  3684.   if (multi_context==MULTIEXCEPT_TOKEN or MULTIINSIDE_TOKEN)
  3685.   {   for (i=1, low=0:i<=multiple_object-->0:i++)
  3686.       {   if ( (multi_context==MULTIEXCEPT_TOKEN
  3687.                 && multiple_object-->i ~= second_p)
  3688.                || (multi_context==MULTIINSIDE_TOKEN
  3689.                    && multiple_object-->i in second_p))
  3690.           {   low++; multiple_object-->low = multiple_object-->i;
  3691.           }
  3692.       }
  3693.       multiple_object-->0 = low;
  3694.   if (multi_context==MULTI_TOKEN && action_to_be == ##Take)
  3695.   {   for (i=1, low=0:i<=multiple_object-->0:i++)
  3696.           if (ScopeCeiling(multiple_object-->i)==ScopeCeiling(actor))
  3697.               low++;
  3698. #ifdef DEBUG;
  3699.       if (parser_trace>=4)
  3700.           print "   Token 2 plural case: number with actor ", low, "^";
  3701. #endif;
  3702.       if (take_all_rule==2 || low>0)
  3703.       {   for (i=1, low=0:i<=multiple_object-->0:i++)
  3704.           {   if (ScopeCeiling(multiple_object-->i)==ScopeCeiling(actor))
  3705.               {   low++; multiple_object-->low = multiple_object-->i;
  3706.               }
  3707.           }
  3708.           multiple_object-->0 = low;
  3709.       }
  3710.   i=multiple_object-->0;
  3711. #ifdef DEBUG;
  3712.   if (parser_trace>=4)
  3713.       print "   Done: new size ", i, "^";
  3714. #endif;
  3715.   if (i==0) return NOTHING_PE;
  3716.   return 0;
  3717. ! ----------------------------------------------------------------------------
  3718. !  ScoreMatchL  scores the match list for quality in terms of what the
  3719. !  player has vaguely asked for.  Points are awarded for conforming with
  3720. !  requirements like "my", and so on.  Remove from the match list any
  3721. !  entries which fail the basic requirements of the descriptors.
  3722. ! ----------------------------------------------------------------------------
  3723. [ ScoreMatchL  its_owner its_score obj i j threshold a_s l_s;
  3724. !  if (indef_type & OTHER_BIT ~= 0) threshold=45;
  3725.   if (indef_type & MY_BIT ~= 0)    threshold=threshold+45;
  3726.   if (indef_type & THAT_BIT ~= 0)  threshold=threshold+45;
  3727.   if (indef_type & LIT_BIT ~= 0)   threshold=threshold+45;
  3728.   if (indef_type & UNLIT_BIT ~= 0) threshold=threshold+45;
  3729.   if (indef_owner ~= nothing)      threshold=threshold+45;
  3730. #ifdef DEBUG;
  3731.   if (parser_trace>=4) print "   Scoring match list: indef mode ", indef_mode,
  3732.       " type ", indef_type,
  3733.       ", threshold ", threshold, ":^";
  3734. #endif;
  3735.   a_s = 30; l_s = 20;
  3736.   if (action_to_be == ##Take or ##Remove) { a_s=20; l_s=30; }
  3737.   for (i=0:i<number_matched:i++)
  3738.   {   obj = match_list-->i; its_owner = parent(obj); its_score=0;
  3739. !      if (indef_type & OTHER_BIT ~=0
  3740. !          &&  obj~=itobj or himobj or herobj)
  3741. !          its_score=its_score+45;
  3742.       if (indef_type & MY_BIT ~=0  &&  its_owner==actor)
  3743.           its_score=its_score+45;
  3744.       if (indef_type & THAT_BIT ~=0  &&  its_owner==actors_location)
  3745.           its_score=its_score+45;
  3746.       if (indef_type & LIT_BIT ~=0  &&  obj has light)
  3747.           its_score=its_score+45;
  3748.       if (indef_type & UNLIT_BIT ~=0  &&  obj hasnt light)
  3749.           its_score=its_score+45;
  3750.       if (indef_owner~=0 && its_owner == indef_owner)
  3751.           its_score=its_score+45;
  3752.       if (its_score < threshold)
  3753.       {
  3754. #ifdef DEBUG;
  3755.           if (parser_trace >= 4)
  3756.               print "   ", (The) match_list-->i,
  3757.                     " (", match_list-->i, ") in ", (the) its_owner,
  3758.                     " is rejected (doesn't match descriptors)^";
  3759. #endif;
  3760.           match_list-->i=-1;
  3761.       }
  3762.       else
  3763.       {   !   Now forget all of that: the object passes descriptors
  3764.           !   and we can score it properly.
  3765.           its_score = 0;
  3766.           if (obj hasnt concealed) its_score=50;
  3767.           if (its_owner==actor)   its_score = its_score+a_s;
  3768.           else
  3769.           if (its_owner==actors_location) its_score = its_score+l_s;
  3770.           else
  3771.           if (its_score==0 && its_owner~=compass) its_score = its_score+10;
  3772.           !   The entry point "ChooseObjects" can contribute 0 to 9 points
  3773.           !   to refine the score
  3774.           its_score = its_score + ChooseObjects(obj,2);
  3775.           !   A small bonus for having the correct GNA,
  3776.           !   for sorting out ambiguous articles and the like.
  3777.           its_score = 2*its_score;
  3778.           if (indef_cases & (PowersOfTwo_TB-->(GetGNAOfObject(obj))))
  3779.               its_score++;
  3780.           match_scores-->i = match_scores-->i + its_score;
  3781. #ifdef DEBUG;
  3782.           if (parser_trace >= 4)
  3783.               print "     ", (The) match_list-->i,
  3784.                     " (", match_list-->i, ") in ", (the) its_owner,
  3785.                     " : ", match_scores-->i, " points^";
  3786. #endif;
  3787.       }
  3788.   for (i=0:i<number_matched:i++)
  3789.   {   while (match_list-->i == -1)
  3790.       {   if (i == number_matched-1) { number_matched--; break; }
  3791.           for (j=i:j<number_matched:j++)
  3792.           {   match_list-->j = match_list-->(j+1);
  3793.               match_scores-->j = match_scores-->(j+1);              
  3794.           }
  3795.           number_matched--;
  3796.       }
  3797. ! ----------------------------------------------------------------------------
  3798. !  BestGuess makes the best guess it can out of the match list, assuming that
  3799. !  everything in the match list is textually as good as everything else;
  3800. !  however it ignores items marked as -1, and so marks anything it chooses.
  3801. !  It returns -1 if there are no possible choices.
  3802. ! ----------------------------------------------------------------------------
  3803. [ BestGuess  earliest its_score best i;
  3804.   earliest=0; best=-1;
  3805.   for (i=0:i<number_matched:i++)
  3806.   {   if (match_list-->i >= 0)
  3807.       {   its_score=match_scores-->i;
  3808.           if (its_score>best) { best=its_score; earliest=i; }
  3809.       }
  3810. #ifdef DEBUG;
  3811.   if (parser_trace>=4)
  3812.   {   if (best<0)
  3813.           print "   Best guess ran out of choices^";
  3814.       else
  3815.           print "   Best guess ", (the) match_list-->earliest,
  3816.                 " (", match_list-->earliest, ")^";
  3817. #endif;
  3818.   if (best<0) return -1;
  3819.   i=match_list-->earliest;
  3820.   match_list-->earliest=-1;
  3821.   return i;
  3822. ! ----------------------------------------------------------------------------
  3823. !  SingleBestGuess returns the highest-scoring object in the match list
  3824. !  if it is the clear winner, or returns -1 if there is no clear winner
  3825. ! ----------------------------------------------------------------------------
  3826. [ SingleBestGuess  earliest its_score best i;
  3827.   earliest=-1; best=-1000;
  3828.   for (i=0:i<number_matched:i++)
  3829.   {   its_score=match_scores-->i;
  3830.       if (its_score==best) { earliest = -1; }
  3831.       if (its_score>best) { best=its_score; earliest=match_list-->i; }
  3832.   return earliest;
  3833. ! ----------------------------------------------------------------------------
  3834. !  Identical decides whether or not two objects can be distinguished from
  3835. !  each other by anything the player can type.  If not, it returns true.
  3836. ! ----------------------------------------------------------------------------
  3837. [ Identical o1 o2 p1 p2 n1 n2 i j flag;
  3838.   if (o1==o2) rtrue;  ! This should never happen, but to be on the safe side
  3839.   if (o1==0 || o2==0) rfalse;  ! Similarly
  3840.   if (parent(o1)==compass || parent(o2)==compass) rfalse; ! Saves time
  3841. !  What complicates things is that o1 or o2 might have a parsing routine,
  3842. !  so the parser can't know from here whether they are or aren't the same.
  3843. !  If they have different parsing routines, we simply assume they're
  3844. !  different.  If they have the same routine (which they probably got from
  3845. !  a class definition) then the decision process is as follows:
  3846. !     the routine is called (with self being o1, not that it matters)
  3847. !       with noun and second being set to o1 and o2, and action being set
  3848. !       to the fake action TheSame.  If it returns -1, they are found
  3849. !       identical; if -2, different; and if >=0, then the usual method
  3850. !       is used instead.
  3851.   if (o1.parse_name~=0 || o2.parse_name~=0)
  3852.   {   if (o1.parse_name ~= o2.parse_name) rfalse;
  3853.       parser_action=##TheSame; parser_one=o1; parser_two=o2;
  3854.       j=wn; i=RunRoutines(o1,parse_name); wn=j;
  3855.       if (i==-1) rtrue; if (i==-2) rfalse;
  3856. !  This is the default algorithm: do they have the same words in their
  3857. !  "name" (i.e. property no. 1) properties.  (Note that the following allows
  3858. !  for repeated words and words in different orders.)
  3859.   p1 = o1.&1; n1 = (o1.#1)/2;
  3860.   p2 = o2.&1; n2 = (o2.#1)/2;
  3861. !  for (i=0:i<n1:i++) { print (address) p1-->i, " "; } new_line;
  3862. !  for (i=0:i<n2:i++) { print (address) p2-->i, " "; } new_line;
  3863.   for (i=0:i<n1:i++)
  3864.   {   flag=0;
  3865.       for (j=0:j<n2:j++)
  3866.           if (p1-->i == p2-->j) flag=1;
  3867.       if (flag==0) rfalse;
  3868.   for (j=0:j<n2:j++)
  3869.   {   flag=0;
  3870.       for (i=0:i<n1:i++)
  3871.           if (p1-->i == p2-->j) flag=1;
  3872.       if (flag==0) rfalse;
  3873. !  print "Which are identical!^";
  3874.   rtrue;
  3875. ! ----------------------------------------------------------------------------
  3876. !  PrintCommand reconstructs the command as it presently reads, from
  3877. !  the pattern which has been built up
  3878. !  If from is 0, it starts with the verb: then it goes through the pattern.
  3879. !  The other parameter is "emptyf" - a flag: if 0, it goes up to pcount:
  3880. !  if 1, it goes up to pcount-1.
  3881. !  Note that verbs and prepositions are printed out of the dictionary:
  3882. !  and that since the dictionary may only preserve the first six characters
  3883. !  of a word (in a V3 game), we have to hand-code the longer words needed.
  3884. !  (Recall that pattern entries are 0 for "multiple object", 1 for "special
  3885. !  word", 2 to REPARSE_CODE-1 are object numbers and REPARSE_CODE+n means the
  3886. !  preposition n)
  3887. ! ----------------------------------------------------------------------------
  3888. [ PrintCommand from i k spacing_flag;
  3889.   if (from==0)
  3890.   {   i=verb_word;
  3891.       if (LanguageVerb(i) == 0)
  3892.           if (PrintVerb(i) == 0)
  3893.               print (address) i;
  3894.       from++; spacing_flag = true;
  3895.   for (k=from:k<pcount:k++)
  3896.   {   i=pattern-->k;
  3897.       if (i == PATTERN_NULL) continue;
  3898.       if (spacing_flag) print (char) ' ';
  3899.       if (i==0) { print (string) THOSET__TX; jump TokenPrinted; }
  3900.       if (i==1) { print (string) THAT__TX; jump TokenPrinted; }
  3901.       if (i>=REPARSE_CODE) print (address) No__Dword(i-REPARSE_CODE);
  3902.       else print (the) i;
  3903.       .TokenPrinted;
  3904.       spacing_flag = true;
  3905. ! ----------------------------------------------------------------------------
  3906. !  The CantSee routine returns a good error number for the situation where
  3907. !  the last word looked at didn't seem to refer to any object in context.
  3908. !  The idea is that: if the actor is in a location (but not inside something
  3909. !  like, for instance, a tank which is in that location) then an attempt to
  3910. !  refer to one of the words listed as meaningful-but-irrelevant there
  3911. !  will cause "you don't need to refer to that in this game" rather than
  3912. !  "no such thing" or "what's 'it'?".
  3913. !  (The advantage of not having looked at "irrelevant" local nouns until now
  3914. !  is that it stops them from clogging up the ambiguity-resolving process.
  3915. !  Thus game objects always triumph over scenery.)
  3916. ! ----------------------------------------------------------------------------
  3917. [ CantSee  i w e;
  3918.     saved_oops=oops_from;
  3919.     if (scope_token~=0) { scope_error = scope_token; return ASKSCOPE_PE; }
  3920.     wn--; w=NextWord();
  3921.     e=CANTSEE_PE;
  3922.     if (w==pronoun_word)
  3923.     {   pronoun__word=pronoun_word; pronoun__obj=pronoun_obj;
  3924.         e=ITGONE_PE;
  3925.     }
  3926.     i=actor; while (parent(i) ~= 0) i = parent(i);
  3927.     if (i has visited && Refers(i,wn-1)==1) e=SCENERY_PE;
  3928.     if (etype>e) return etype;
  3929.     return e;
  3930. ! ----------------------------------------------------------------------------
  3931. !  The MultiAdd routine adds object "o" to the multiple-object-list.
  3932. !  This is only allowed to hold 63 objects at most, at which point it ignores
  3933. !  any new entries (and sets a global flag so that a warning may later be
  3934. !  printed if need be).
  3935. ! ----------------------------------------------------------------------------
  3936. [ MultiAdd o i j;
  3937.   i=multiple_object-->0;
  3938.   if (i==63) { toomany_flag=1; rtrue; }
  3939.   for (j=1:j<=i:j++)
  3940.       if (o==multiple_object-->j) 
  3941.           rtrue;
  3942.   i++;
  3943.   multiple_object-->i = o;
  3944.   multiple_object-->0 = i;
  3945. ! ----------------------------------------------------------------------------
  3946. !  The MultiSub routine deletes object "o" from the multiple-object-list.
  3947. !  It returns 0 if the object was there in the first place, and 9 (because
  3948. !  this is the appropriate error number in Parser()) if it wasn't.
  3949. ! ----------------------------------------------------------------------------
  3950. [ MultiSub o i j k et;
  3951.   i=multiple_object-->0; et=0;
  3952.   for (j=1:j<=i:j++)
  3953.       if (o==multiple_object-->j)
  3954.       {   for (k=j:k<=i:k++)
  3955.               multiple_object-->k = multiple_object-->(k+1);
  3956.           multiple_object-->0 = --i;
  3957.           return et;
  3958.       }
  3959.   et=9; return et;
  3960. ! ----------------------------------------------------------------------------
  3961. !  The MultiFilter routine goes through the multiple-object-list and throws
  3962. !  out anything without the given attribute "attr" set.
  3963. ! ----------------------------------------------------------------------------
  3964. [ MultiFilter attr  i j o;
  3965.   .MFiltl;
  3966.   i=multiple_object-->0;
  3967.   for (j=1:j<=i:j++)
  3968.   {   o=multiple_object-->j;
  3969.       if (o hasnt attr) { MultiSub(o); jump Mfiltl; }
  3970. ! ----------------------------------------------------------------------------
  3971. !  The UserFilter routine consults the user's filter (or checks on attribute)
  3972. !  to see what already-accepted nouns are acceptable
  3973. ! ----------------------------------------------------------------------------
  3974. [ UserFilter obj;
  3975.   if (token_filter > 0 && token_filter < 49)
  3976.   {   if (obj has (token_filter-1)) rtrue;
  3977.       rfalse;
  3978.   noun = obj;
  3979.   return indirect(token_filter);
  3980. ! ----------------------------------------------------------------------------
  3981. !  MoveWord copies word at2 from parse buffer b2 to word at1 in "parse"
  3982. !  (the main parse buffer)
  3983. ! ----------------------------------------------------------------------------
  3984. [ MoveWord at1 b2 at2 x y;
  3985.   x=at1*2-1; y=at2*2-1;
  3986.   parse-->x++ = b2-->y++;
  3987.   parse-->x = b2-->y;
  3988. ! ----------------------------------------------------------------------------
  3989. !  SearchScope  domain1 domain2 context
  3990. !  Works out what objects are in scope (possibly asking an outside routine),
  3991. !  but does not look at anything the player has typed.
  3992. ! ----------------------------------------------------------------------------
  3993. [ SearchScope domain1 domain2 context i;
  3994.   i=0;
  3995. !  Everything is in scope to the debugging commands
  3996. #ifdef DEBUG;
  3997.   if (scope_reason==PARSING_REASON
  3998.       && verb_word == 'purloin' or 'tree' or 'abstract'
  3999.                        or 'gonear' or 'scope' or 'showobj')
  4000.   {   for (i=selfobj:i<=top_object:i++)
  4001.           if (i ofclass Object && (parent(i)==0 || parent(i) ofclass Object))
  4002.               PlaceInScope(i);
  4003.       rtrue;
  4004. #endif;
  4005. !  First, a scope token gets priority here:
  4006.   if (scope_token ~= 0)
  4007.   {   scope_stage=2;
  4008.       if (indirect(scope_token)~=0) rtrue;
  4009. !  Next, call any user-supplied routine adding things to the scope,
  4010. !  which may circumvent the usual routines altogether if they return true:
  4011.   if (actor==domain1 or domain2 && InScope(actor)~=0) rtrue;
  4012. !  Pick up everything in the location except the actor's possessions;
  4013. !  then go through those.  (This ensures the actor's possessions are in
  4014. !  scope even in Darkness.)
  4015.   if (context==MULTIINSIDE_TOKEN && advance_warning ~= -1)
  4016.   {   if (IsSeeThrough(advance_warning)==1)
  4017.           ScopeWithin(advance_warning, 0, context);
  4018.   else
  4019.   {   if (domain1~=0 && domain1 has supporter or container)
  4020.           ScopeWithin_O(domain1, domain1, context);
  4021.       ScopeWithin(domain1, domain2, context);
  4022.       if (domain2~=0 && domain2 has supporter or container)
  4023.           ScopeWithin_O(domain2, domain2, context);
  4024.       ScopeWithin(domain2, 0, context);
  4025. !  A special rule applies:
  4026. !  in Darkness as in light, the actor is always in scope to himself.
  4027.   if (thedark == domain1 or domain2)
  4028.   {   ScopeWithin_O(actor, actor, context);
  4029.       if (parent(actor) has supporter or container)
  4030.           ScopeWithin_O(parent(actor), parent(actor), context);
  4031. ! ----------------------------------------------------------------------------
  4032. !  IsSeeThrough is used at various places: roughly speaking, it determines
  4033. !  whether o being in scope means that the contents of o are in scope.
  4034. ! ----------------------------------------------------------------------------
  4035. [ IsSeeThrough o;
  4036.   if (o has supporter
  4037.       || (o has transparent)
  4038.       || (o has container && o has open))
  4039.       rtrue;
  4040.   rfalse;
  4041. ! ----------------------------------------------------------------------------
  4042. !  PlaceInScope is provided for routines outside the library, and is not
  4043. !  called within the parser (except for debugging purposes).
  4044. ! ----------------------------------------------------------------------------
  4045. [ PlaceInScope thing;
  4046.    if (scope_reason~=PARSING_REASON or TALKING_REASON)
  4047.    {   DoScopeAction(thing); rtrue; }
  4048.    wn=match_from; TryGivenObject(thing); placed_in_flag=1;
  4049. ! ----------------------------------------------------------------------------
  4050. !  DoScopeAction
  4051. ! ----------------------------------------------------------------------------
  4052. [ DoScopeAction thing s p1;
  4053.   s = scope_reason; p1=parser_one;
  4054. #ifdef DEBUG;
  4055.   if (parser_trace>=6)
  4056.   {   print "[DSA on ", (the) thing, " with reason = ", scope_reason,
  4057.       " p1 = ", parser_one, " p2 = ", parser_two, "]^";
  4058. #endif;
  4059.   switch(scope_reason)
  4060.   {   REACT_BEFORE_REASON:
  4061.           if (thing.react_before==0 or NULL) return;
  4062. #ifdef DEBUG;
  4063.           if (parser_trace>=2)
  4064.           {   print "[Considering react_before for ", (the) thing, "]^"; }
  4065. #endif;
  4066.           if (parser_one==0) parser_one = RunRoutines(thing,react_before);
  4067.       REACT_AFTER_REASON:
  4068.           if (thing.react_after==0 or NULL) return;
  4069. #ifdef DEBUG;
  4070.           if (parser_trace>=2)
  4071.           {   print "[Considering react_after for ", (the) thing, "]^"; }
  4072. #endif;
  4073.           if (parser_one==0) parser_one = RunRoutines(thing,react_after);
  4074.       EACH_TURN_REASON:
  4075.           if (thing.&each_turn==0) return;
  4076. #ifdef DEBUG;
  4077.           if (parser_trace>=2)
  4078.           {   print "[Considering each_turn for ", (the) thing, "]^"; }
  4079. #endif;
  4080.           PrintOrRun(thing, each_turn);
  4081.       TESTSCOPE_REASON:
  4082.           if (thing==parser_one) parser_two = 1;
  4083.       LOOPOVERSCOPE_REASON:
  4084.           indirect(parser_one,thing); parser_one=p1;
  4085.   scope_reason = s;
  4086. ! ----------------------------------------------------------------------------
  4087. !  ScopeWithin looks for objects in the domain which make textual sense
  4088. !  and puts them in the match list.  (However, it does not recurse through
  4089. !  the second argument.)
  4090. ! ----------------------------------------------------------------------------
  4091. [ ScopeWithin domain nosearch context x y;
  4092.    if (domain==0) rtrue;
  4093. !  Special rule: the directions (interpreted as the 12 walls of a room) are
  4094. !  always in context.  (So, e.g., "examine north wall" is always legal.)
  4095. !  (Unless we're parsing something like "all", because it would just slow
  4096. !  things down then, or unless the context is "creature".)
  4097.    if (indef_mode==0 && domain==actors_location
  4098.        && scope_reason==PARSING_REASON && context~=CREATURE_TOKEN)
  4099.            ScopeWithin(compass);
  4100. !  Look through the objects in the domain, avoiding "objectloop" in case
  4101. !  movements occur, e.g. when trying each_turn.
  4102.    x = child(domain);
  4103.    while (x ~= 0)
  4104.    {   y = sibling(x);
  4105.        ScopeWithin_O(x, nosearch, context);
  4106.        x = y;
  4107. [ ScopeWithin_O domain nosearch context i ad n;
  4108. !  multiexcept doesn't have second parameter in scope
  4109.    if (context==MULTIEXCEPT_TOKEN && domain==advance_warning) jump DontAccept;
  4110. !  If the scope reason is unusual, don't parse.
  4111.       if (scope_reason~=PARSING_REASON or TALKING_REASON)
  4112.       {   DoScopeAction(domain); jump DontAccept; }
  4113. !  "it" or "them" matches to the it-object only.  (Note that (1) this means
  4114. !  that "it" will only be understood if the object in question is still
  4115. !  in context, and (2) only one match can ever be made in this case.)
  4116.       if (match_from <= num_words)  ! If there's any text to match, that is
  4117.       {   wn=match_from;
  4118.           i=NounWord();
  4119.           if (i==1 && player==domain)  MakeMatch(domain, 1);
  4120.           if (i>=2 && i<128 && (LanguagePronouns-->i == domain))
  4121.               MakeMatch(domain, 1);
  4122.       }
  4123. !  Construing the current word as the start of a noun, can it refer to the
  4124. !  object?
  4125.       wn = match_from;
  4126.       if (TryGivenObject(domain) > 0)
  4127.           if (indef_nspec_at>0 && match_from~=indef_nspec_at)
  4128.           {   !  This case arises if the player has typed a number in
  4129.               !  which is hypothetically an indefinite descriptor:
  4130.               !  e.g. "take two clubs".  We have just checked the object
  4131.               !  against the word "clubs", in the hope of eventually finding
  4132.               !  two such objects.  But we also backtrack and check it
  4133.               !  against the words "two clubs", in case it turns out to
  4134.               !  be the 2 of Clubs from a pack of cards, say.  If it does
  4135.               !  match against "two clubs", we tear up our original
  4136.               !  assumption about the meaning of "two" and lapse back into
  4137.               !  definite mode.
  4138.           
  4139.               wn = indef_nspec_at;
  4140.               if (TryGivenObject(domain) > 0)
  4141.               {   match_from = indef_nspec_at;
  4142.                   ResetDescriptors();                  
  4143.               }
  4144.               wn = match_from;
  4145.           }
  4146.       .DontAccept;
  4147. !  Shall we consider the possessions of the current object, as well?
  4148. !  Only if it's a container (so, for instance, if a dwarf carries a
  4149. !  sword, then "drop sword" will not be accepted, but "dwarf, drop sword"
  4150. !  will).
  4151. !  Also, only if there are such possessions.
  4152. !  Notice that the parser can see "into" anything flagged as
  4153. !  transparent - such as a dwarf whose sword you can get at.
  4154.       if (child(domain)~=0 && domain ~= nosearch && IsSeeThrough(domain)==1)
  4155.           ScopeWithin(domain,nosearch,context);
  4156. !  Drag any extras into context
  4157.    ad = domain.&add_to_scope;
  4158.    if (ad ~= 0)
  4159.    {   if (UnsignedCompare(ad-->0,top_object) > 0)
  4160.        {   ats_flag = 2+context;
  4161.            RunRoutines(domain, add_to_scope);
  4162.            ats_flag = 0;
  4163.        }
  4164.        else
  4165.        {   n=domain.#add_to_scope;
  4166.            for (i=0:(2*i)<n:i++)
  4167.                ScopeWithin_O(ad-->i,0,context);
  4168.        }
  4169. [ AddToScope obj;
  4170.    if (ats_flag>=2)
  4171.        ScopeWithin_O(obj,0,ats_flag-2);
  4172.    if (ats_flag==1)
  4173.    {   if  (HasLightSource(obj)==1) ats_hls = 1;
  4174. ! ----------------------------------------------------------------------------
  4175. !  MakeMatch looks at how good a match is.  If it's the best so far, then
  4176. !  wipe out all the previous matches and start a new list with this one.
  4177. !  If it's only as good as the best so far, add it to the list.
  4178. !  If it's worse, ignore it altogether.
  4179. !  The idea is that "red panic button" is better than "red button" or "panic".
  4180. !  number_matched (the number of words matched) is set to the current level
  4181. !  of quality.
  4182. !  We never match anything twice, and keep at most 64 equally good items.
  4183. ! ----------------------------------------------------------------------------
  4184. [ MakeMatch obj quality i;
  4185. #ifdef DEBUG;
  4186.    if (parser_trace>=6) print "    Match with quality ",quality,"^";
  4187. #endif;
  4188.    if (token_filter~=0 && UserFilter(obj)==0)
  4189.    {   #ifdef DEBUG;
  4190.        if (parser_trace>=6)
  4191.        {   print "    Match filtered out: token filter ", token_filter, "^";
  4192.        }
  4193.        #endif;
  4194.        rtrue;
  4195.    if (quality < match_length) rtrue;
  4196.    if (quality > match_length) { match_length=quality; number_matched=0; }
  4197.    else
  4198.    {   if (2*number_matched>=MATCH_LIST_SIZE) rtrue;
  4199.        for (i=0:i<number_matched:i++)
  4200.            if (match_list-->i==obj) rtrue;
  4201.    match_list-->number_matched++ = obj;
  4202. #ifdef DEBUG;
  4203.    if (parser_trace>=6) print "    Match added to list^";
  4204. #endif;
  4205. ! ----------------------------------------------------------------------------
  4206. !  TryGivenObject tries to match as many words as possible in what has been
  4207. !  typed to the given object, obj.  If it manages any words matched at all,
  4208. !  it calls MakeMatch to say so, then returns the number of words (or 1
  4209. !  if it was a match because of inadequate input).
  4210. ! ----------------------------------------------------------------------------
  4211. [ TryGivenObject obj threshold k w j;
  4212. #ifdef DEBUG;
  4213.    if (parser_trace>=5)
  4214.        print "    Trying ", (the) obj, " (", obj, ") at word ", wn, "^";
  4215. #endif;
  4216.    dict_flags_of_noun = 0;
  4217. !  If input has run out then always match, with only quality 0 (this saves
  4218. !  time).
  4219.    if (wn > num_words)
  4220.    {   if (indef_mode ~= 0)
  4221.            dict_flags_of_noun = $$01110000;  ! Reject "plural" bit
  4222.        MakeMatch(obj,0);
  4223.        #ifdef DEBUG;
  4224.        if (parser_trace>=5)
  4225.        print "    Matched (0)^";
  4226.        #endif;
  4227.        return 1;
  4228. !  Ask the object to parse itself if necessary, sitting up and taking notice
  4229. !  if it says the plural was used:
  4230.    if (obj.parse_name~=0)
  4231.    {   parser_action = NULL; j=wn;
  4232.        k=RunRoutines(obj,parse_name);
  4233.        if (k>0)
  4234.        {   wn=j+k;
  4235.            .MMbyPN;
  4236.            if (parser_action == ##PluralFound)
  4237.                dict_flags_of_noun = dict_flags_of_noun | 4;
  4238.            if (dict_flags_of_noun & 4)
  4239.            {   if (~~allow_plurals) k=0;
  4240.                else
  4241.                {   if (indef_mode==0)
  4242.                    {   indef_mode=1; indef_type=0; indef_wanted=0; }
  4243.                    indef_type = indef_type | PLURAL_BIT;
  4244.                    if (indef_wanted==0) indef_wanted=100;
  4245.                }
  4246.            }
  4247.            #ifdef DEBUG;
  4248.                if (parser_trace>=5)
  4249.                {   print "    Matched (", k, ")^";
  4250.                }
  4251.            #endif;
  4252.            MakeMatch(obj,k);
  4253.            return k;
  4254.        }
  4255.        if (k==0) jump NoWordsMatch;
  4256. !  The default algorithm is simply to count up how many words pass the
  4257. !  Refers test:
  4258.    parser_action = NULL;
  4259.    w = NounWord();
  4260.    if (w==1 && player==obj) { k=1; jump MMbyPN; }
  4261.    if (w>=2 && w<128 && (LanguagePronouns-->w == obj))
  4262.    {   k=1; jump MMbyPN; }
  4263.    j=--wn;
  4264.    threshold = ParseNoun(obj);
  4265. #ifdef DEBUG;
  4266.    if (threshold>=0 && parser_trace>=5)
  4267.        print "    ParseNoun returned ", threshold, "^";
  4268. #endif;
  4269.    if (threshold<0) wn++;
  4270.    if (threshold>0) { k=threshold; jump MMbyPN; }
  4271.    if (threshold==0 || Refers(obj,wn-1)==0)
  4272.    {   .NoWordsMatch;
  4273.        if (indef_mode~=0)
  4274.        {   k=0; parser_action=NULL; jump MMbyPN;
  4275.        }
  4276.        rfalse;
  4277.    if (threshold<0)
  4278.    {   threshold=1;
  4279.        dict_flags_of_noun = (w->#dict_par1) & $$01110100;
  4280.        w = NextWord();
  4281.        while (Refers(obj, wn-1))
  4282.        {   threshold++;
  4283.            if (w)
  4284.                dict_flags_of_noun = dict_flags_of_noun
  4285.                                     | ((w->#dict_par1) & $$01110100);
  4286.            w = NextWord();
  4287.        }
  4288.    k = threshold; jump MMbyPN;
  4289. ! ----------------------------------------------------------------------------
  4290. !  Refers works out whether the word at number wnum can refer to the object
  4291. !  obj, returning true or false.  The standard method is to see if the
  4292. !  word is listed under "name" for the object, but this is more complex
  4293. !  in languages other than English.
  4294. ! ----------------------------------------------------------------------------
  4295. [ Refers obj wnum   wd k l m;
  4296.     if (obj==0) rfalse;
  4297.     #ifdef LanguageRefers;
  4298.     k = LanguageRefers(obj,wnum); if (k>=0) return k;
  4299.     #endif;
  4300.     k = wn; wn = wnum; wd = NextWordStopped(); wn = k;
  4301.     if (parser_inflection >= 256)
  4302.     {   k = indirect(parser_inflection, obj, wd);
  4303.         if (k>=0) return k;
  4304.         m = -k;
  4305.     } else m = parser_inflection;
  4306.     k=obj.&m; l=(obj.#m)/2-1;
  4307.     for (m=0:m<=l:m++)
  4308.         if (wd==k-->m) rtrue;
  4309.     rfalse;
  4310. [ WordInProperty wd obj prop k l m;
  4311.     k=obj.∝ l=(obj.#prop)/2-1;
  4312.     for (m=0:m<=l:m++)
  4313.         if (wd==k-->m) rtrue;
  4314.     rfalse;
  4315. [ DictionaryLookup b l i;
  4316.   for (i=0:i<l:i++) buffer2->(2+i) = b->i;
  4317.   buffer2->1 = l;
  4318.   Tokenise__(buffer2,parse2);
  4319.   return parse2-->1;
  4320. ! ----------------------------------------------------------------------------
  4321. !  NounWord (which takes no arguments) returns:
  4322. !   0  if the next word is unrecognised or does not carry the "noun" bit in
  4323. !      its dictionary entry,
  4324. !   1  if a word meaning "me",
  4325. !   the index in the pronoun table (plus 2) of the value field of a pronoun,
  4326. !      if the word is a pronoun,
  4327. !   the address in the dictionary if it is a recognised noun.
  4328. !  The "current word" marker moves on one.
  4329. ! ----------------------------------------------------------------------------
  4330. [ NounWord i j s;
  4331.    i=NextWord();
  4332.    if (i==0) rfalse;
  4333.    if (i==ME1__WD or ME2__WD or ME3__WD) return 1;
  4334.    s = LanguagePronouns-->0;
  4335.    for (j=1 : j<=s : j=j+3)
  4336.        if (i == LanguagePronouns-->j)
  4337.            return j+2;
  4338.    if ((i->#dict_par1)&128 == 0) rfalse;
  4339.    return i;
  4340. ! ----------------------------------------------------------------------------
  4341. !  NextWord (which takes no arguments) returns:
  4342. !  0            if the next word is unrecognised,
  4343. !  comma_word   if it is a comma character
  4344. !               (which is treated oddly by the Z-machine, hence the code)
  4345. !  or the dictionary address if it is recognised.
  4346. !  The "current word" marker is moved on.
  4347. !  NextWordStopped does the same, but returns -1 when input has run out
  4348. ! ----------------------------------------------------------------------------
  4349. [ NextWord i j k;
  4350.    if (wn > parse->1) { wn++; rfalse; }
  4351.    i=wn*2-1; wn++;
  4352.    j=parse-->i;
  4353.    if (j==0)
  4354.    {   k=wn*4-3; i=buffer->(parse->k);
  4355.        if (i==',') j=comma_word;
  4356.        if (i=='.') j=THEN1__WD;
  4357.    return j;
  4358. ];   
  4359. [ NextWordStopped;
  4360.    if (wn > parse->1) { wn++; return -1; }
  4361.    return NextWord();
  4362. [ WordAddress wordnum;
  4363.    return buffer + parse->(wordnum*4+1);
  4364. [ WordLength wordnum;
  4365.    return parse->(wordnum*4);
  4366. ! ----------------------------------------------------------------------------
  4367. !  TryNumber is the only routine which really does any character-level
  4368. !  parsing, since that's normally left to the Z-machine.
  4369. !  It takes word number "wordnum" and tries to parse it as an (unsigned)
  4370. !  decimal number, returning
  4371. !  -1000                if it is not a number
  4372. !  the number           if it has between 1 and 4 digits
  4373. !  10000                if it has 5 or more digits.
  4374. !  (The danger of allowing 5 digits is that Z-machine integers are only
  4375. !  16 bits long, and anyway this isn't meant to be perfect.)
  4376. !  Using NumberWord, it also catches "one" up to "twenty".
  4377. !  Note that a game can provide a ParseNumber routine which takes priority,
  4378. !  to enable parsing of odder numbers ("x45y12", say).
  4379. ! ----------------------------------------------------------------------------
  4380. [ TryNumber wordnum   i j c num len mul tot d digit;
  4381.    i=wn; wn=wordnum; j=NextWord(); wn=i;
  4382.    j=NumberWord(j); if (j>=1) return j;
  4383.    i=wordnum*4+1; j=parse->i; num=j+buffer; len=parse->(i-1);
  4384.    tot=ParseNumber(num, len);  if (tot~=0) return tot;
  4385.    if (len>=4) mul=1000;
  4386.    if (len==3) mul=100;
  4387.    if (len==2) mul=10;
  4388.    if (len==1) mul=1;
  4389.    tot=0; c=0; len=len-1;
  4390.    for (c=0:c<=len:c++)
  4391.    {   digit=num->c;
  4392.        if (digit=='0') { d=0; jump digok; }
  4393.        if (digit=='1') { d=1; jump digok; }
  4394.        if (digit=='2') { d=2; jump digok; }
  4395.        if (digit=='3') { d=3; jump digok; }
  4396.        if (digit=='4') { d=4; jump digok; }
  4397.        if (digit=='5') { d=5; jump digok; }
  4398.        if (digit=='6') { d=6; jump digok; }
  4399.        if (digit=='7') { d=7; jump digok; }
  4400.        if (digit=='8') { d=8; jump digok; }
  4401.        if (digit=='9') { d=9; jump digok; }
  4402.        return -1000;
  4403.      .digok;
  4404.        tot=tot+mul*d; mul=mul/10;
  4405.    if (len>3) tot=10000;
  4406.    return tot;
  4407. ! ----------------------------------------------------------------------------
  4408. !  GetGender returns 0 if the given animate object is female, and 1 if male
  4409. !  (not all games will want such a simple decision function!)
  4410. ! ----------------------------------------------------------------------------
  4411. [ GetGender person;
  4412.    if (person hasnt female) rtrue;
  4413.    rfalse;
  4414. [ GetGNAOfObject obj case gender;
  4415.    if (obj hasnt animate) case = 6;
  4416.    if (obj has male) gender = male;
  4417.    if (obj has female) gender = female;
  4418.    if (obj has neuter) gender = neuter;
  4419.    if (gender == 0)
  4420.    {   if (case == 0) gender = LanguageAnimateGender;
  4421.        else gender = LanguageInanimateGender;
  4422.    if (gender == female) case = case + 1;
  4423.    if (gender == neuter) case = case + 2;
  4424.    if (obj has pluralname) case = case + 3;
  4425.    return case;
  4426. ! ----------------------------------------------------------------------------
  4427. !  Converting between dictionary addresses and entry numbers
  4428. ! ----------------------------------------------------------------------------
  4429. [ Dword__No w; return (w-(0-->4 + 7))/9; ];
  4430. [ No__Dword n; return 0-->4 + 7 + 9*n; ];
  4431. ! ----------------------------------------------------------------------------
  4432. !  For copying buffers
  4433. ! ----------------------------------------------------------------------------
  4434. [ CopyBuffer bto bfrom i size;
  4435.    size=bto->0;
  4436.    for (i=1:i<=size:i++) bto->i=bfrom->i;
  4437. ! ----------------------------------------------------------------------------
  4438. !  Provided for use by language definition files
  4439. ! ----------------------------------------------------------------------------
  4440. [ LTI_Insert i ch  y;
  4441.   !   Insert character ch into buffer at point i.
  4442.   !   Being careful not to let the buffer possibly overflow:
  4443.       y = buffer->1;
  4444.       if (y > buffer->0) y = buffer->0;
  4445.   !   Move the subsequent text along one character:
  4446.       for (y=y+2: y>i : y--) buffer->y = buffer->(y-1);
  4447.       buffer->i = ch;
  4448.   !   And the text is now one character longer:
  4449.       if (buffer->1 < buffer->0)
  4450.           (buffer->1)++;
  4451. ! ============================================================================
  4452. [ PronounsSub x y c d;
  4453.   L__M(##Pronouns, 1);
  4454.   c = (LanguagePronouns-->0)/3;
  4455.   if (player ~= selfobj) c++;
  4456.   if (c==0) return L__M(##Pronouns, 4);
  4457.   for (x = 1, d = 0 : x <= LanguagePronouns-->0: x = x+3)
  4458.   {   print "~", (address) LanguagePronouns-->x, "~ ";
  4459.       y = LanguagePronouns-->(x+2);
  4460.       if (y == NULL) L__M(##Pronouns, 3);
  4461.       else { L__M(##Pronouns, 2); print (the) y; }
  4462.       d++;
  4463.       if (d < c-1) print ", ";
  4464.       if (d == c-1) print (string) AND__TX;
  4465.   if (player ~= selfobj)
  4466.   {   print "~", (address) ME1__WD, "~ "; L__M(##Pronouns, 2);
  4467.       c = player; player = selfobj;
  4468.       print (the) c; player = c;
  4469.   ".";
  4470. [ SetPronoun dword value x;
  4471.   for (x = 1 : x <= LanguagePronouns-->0: x = x+3)
  4472.       if (LanguagePronouns-->x == dword)
  4473.       {   LanguagePronouns-->(x+2) = value; return;
  4474.       }
  4475.   RunTimeError(14);
  4476. [ PronounValue dword x;
  4477.   for (x = 1 : x <= LanguagePronouns-->0: x = x+3)
  4478.       if (LanguagePronouns-->x == dword)
  4479.           return LanguagePronouns-->(x+2);
  4480.   return 0;
  4481. [ ResetVagueWords obj; PronounNotice(obj); ];
  4482. #ifdef EnglishNaturalLanguage;
  4483. [ PronounOldEnglish;
  4484.    if (itobj ~= old_itobj)   SetPronoun('it', itobj);
  4485.    if (himobj ~= old_himobj) SetPronoun('him', himobj);
  4486.    if (herobj ~= old_herobj) SetPronoun('her', herobj);
  4487.    old_itobj = itobj; old_himobj = himobj; old_herobj = herobj;
  4488. #endif;
  4489. [ PronounNotice obj x bm;
  4490.    if (obj == player) return;
  4491.    #ifdef EnglishNaturalLanguage;
  4492.    PronounOldEnglish();
  4493.    #endif;
  4494.    bm = PowersOfTwo_TB-->(GetGNAOfObject(obj));
  4495.    for (x = 1 : x <= LanguagePronouns-->0: x = x+3)
  4496.        if (bm & (LanguagePronouns-->(x+1)) ~= 0)
  4497.            LanguagePronouns-->(x+2) = obj;
  4498.    #ifdef EnglishNaturalLanguage;
  4499.    itobj  = PronounValue('it');  old_itobj  = itobj;
  4500.    himobj = PronounValue('him'); old_himobj = himobj;
  4501.    herobj = PronounValue('her'); old_herobj = herobj;
  4502.    #endif;
  4503. ! ============================================================================
  4504. !  End of the parser proper: the remaining routines are its front end.
  4505. ! ----------------------------------------------------------------------------
  4506. Object InformLibrary "(Inform Library)"
  4507.   with play
  4508.        [ i j k l;
  4509.        standard_interpreter = $32-->0;
  4510.        transcript_mode = ((0-->8) & 1);
  4511.        ChangeDefault(cant_go, CANTGO__TX);
  4512.        buffer->0 = 120;
  4513.        buffer2->0 = 120;
  4514.        buffer3->0 = 120;
  4515.        parse->0 = 64;
  4516.        parse2->0 = 64;
  4517.        
  4518.        real_location = thedark;
  4519.        player = selfobj; actor = player;
  4520.        top_object = #largest_object-255;
  4521.        selfobj.capacity = MAX_CARRIED;
  4522.        #ifdef LanguageInitialise;
  4523.        LanguageInitialise();
  4524.        #endif;
  4525.        new_line;
  4526.        j=Initialise();
  4527.        last_score = score;
  4528.        move player to location;
  4529.        while (parent(location)~=0) location=parent(location);
  4530.        real_location = location;
  4531.        objectloop (i in player) give i moved ~concealed;
  4532.        if (j~=2) Banner();
  4533.        MoveFloatingObjects();
  4534.        lightflag=OffersLight(parent(player));
  4535.        if (lightflag==0) { real_location=location; location=thedark; }
  4536.        <Look>;
  4537.        for (i=1:i<=100:i++) j=random(i);
  4538.        #ifdef EnglishNaturalLanguage;
  4539.        old_itobj = itobj; old_himobj = himobj; old_herobj = herobj;
  4540.        #endif;
  4541.        while (~~deadflag)
  4542.        {   
  4543.            #ifdef EnglishNaturalLanguage;
  4544.                PronounOldEnglish();
  4545.                old_itobj = PronounValue('it');
  4546.                old_himobj = PronounValue('him');
  4547.                old_herobj = PronounValue('her');
  4548.            #endif;
  4549.            .very__late__error;
  4550.            if (score ~= last_score)
  4551.            {   if (notify_mode==1) NotifyTheScore(); last_score=score; }
  4552.            .late__error;
  4553.            inputobjs-->0 = 0; inputobjs-->1 = 0;
  4554.            inputobjs-->2 = 0; inputobjs-->3 = 0; meta=false;
  4555.            !  The Parser writes its results into inputobjs and meta,
  4556.            !  a flag indicating a "meta-verb".  This can only be set for
  4557.            !  commands by the player, not for orders to others.
  4558.            InformParser.parse_input(inputobjs);
  4559.            action=inputobjs-->0;
  4560.            !  --------------------------------------------------------------
  4561.            !  Reverse "give fred biscuit" into "give biscuit to fred"
  4562.            if (action==##GiveR or ##ShowR)
  4563.            {   i=inputobjs-->2; inputobjs-->2=inputobjs-->3; inputobjs-->3=i;
  4564.                if (action==##GiveR) action=##Give; else action=##Show;
  4565.            }
  4566.            !  Convert "P, tell me about X" to "ask P about X"
  4567.            if (action==##Tell && inputobjs-->2==player && actor~=player)
  4568.            {   inputobjs-->2=actor; actor=player; action=##Ask;
  4569.            }
  4570.            !  Convert "ask P for X" to "P, give X to me"
  4571.            if (action==##AskFor && inputobjs-->2~=player && actor==player)
  4572.            {   actor=inputobjs-->2; inputobjs-->2=inputobjs-->3;
  4573.                inputobjs-->3=player; action=##Give;
  4574.            }
  4575.            !  For old, obsolete code: special_word contains the topic word
  4576.            !  in conversation
  4577.            if (action==##Ask or ##Tell or ##Answer)
  4578.                special_word = special_number1;
  4579.            !  --------------------------------------------------------------
  4580.            multiflag=false; onotheld_mode=notheld_mode; notheld_mode=false;
  4581.            !  For implicit taking and multiple object detection
  4582.           .begin__action;
  4583.            inp1 = 0; inp2 = 0; i=inputobjs-->1;
  4584.            if (i>=1) inp1=inputobjs-->2;
  4585.            if (i>=2) inp2=inputobjs-->3;
  4586.            !  inp1 and inp2 hold: object numbers, or 0 for "multiple object",
  4587.            !  or 1 for "a number or dictionary address"
  4588.            if (inp1 == 1) noun = special_number1; else noun = inp1;
  4589.            if (inp2 == 1)
  4590.            {   if (inp1 == 1) second = special_number2;
  4591.                else second = special_number1;
  4592.            } else second = inp2;
  4593.            !  --------------------------------------------------------------
  4594.            if (actor~=player)
  4595.            {   
  4596.            !  The player's "orders" property can refuse to allow conversation
  4597.            !  here, by returning true.  If not, the order is sent to the
  4598.            !  other person's "orders" property.  If that also returns false,
  4599.            !  then: if it was a misunderstood command anyway, it is converted
  4600.            !  to an Answer action (thus "floyd, grrr" ends up as
  4601.            !  "say grrr to floyd").  If it was a good command, it is finally
  4602.            !  offered to the Order: part of the other person's "life"
  4603.            !  property, the old-fashioned way of dealing with conversation.
  4604.                j=RunRoutines(player,orders);
  4605.                if (j==0)
  4606.                {   j=RunRoutines(actor,orders);
  4607.                    if (j==0)
  4608.                    {   if (action==##NotUnderstood)
  4609.                        {   inputobjs-->3=actor; actor=player; action=##Answer;
  4610.                            jump begin__action;
  4611.                        }
  4612.                        if (RunLife(actor,##Order)==0) L__M(##Order,1,actor);
  4613.                    }
  4614.                }
  4615.                jump turn__end;
  4616.            }
  4617.            !  --------------------------------------------------------------
  4618.            !  Generate the action...
  4619.            if ((i==0)
  4620.                || (i==1 && inp1 ~= 0)
  4621.                || (i==2 && inp1 ~= 0 && inp2 ~= 0))
  4622.            {   self.begin_action(action, noun, second, 0);
  4623.                jump turn__end;
  4624.            }
  4625.            !  ...unless a multiple object must be substituted.  First:
  4626.            !  (a) check the multiple list isn't empty;
  4627.            !  (b) warn the player if it has been cut short because too long;
  4628.            !  (c) generate a sequence of actions from the list
  4629.            !      (stopping in the event of death or movement away).
  4630.            multiflag = true;
  4631.            j=multiple_object-->0;
  4632.            if (j==0) { L__M(##Miscellany,2); jump late__error; }
  4633.            if (toomany_flag)
  4634.            {   toomany_flag = false; L__M(##Miscellany,1); }
  4635.            i=location;
  4636.            for (k=1:k<=j:k++)
  4637.            {   if (deadflag) break;
  4638.                if (location ~= i)
  4639.                {   L__M(##Miscellany, 51);
  4640.                    break;
  4641.                }
  4642.                l = multiple_object-->k;
  4643.                PronounNotice(l);
  4644.                print (name) l, ": ";
  4645.                if (inp1 == 0)
  4646.                {   inp1 = l; self.begin_action(action, l, second, 0); inp1 = 0;
  4647.                }
  4648.                else
  4649.                {   inp2 = l; self.begin_action(action, noun, l, 0); inp2 = 0;
  4650.                }
  4651.            }
  4652.            !  --------------------------------------------------------------
  4653.            .turn__end;
  4654.            !  No time passes if either (i) the verb was meta, or
  4655.            !  (ii) we've only had the implicit take before the "real"
  4656.            !  action to follow.
  4657.            if (notheld_mode==1) { NoteObjectAcquisitions(); continue; }
  4658.            if (meta) continue;
  4659.            if (~~deadflag) self.end_turn_sequence();
  4660.        }
  4661.            if (deadflag~=2) AfterLife();
  4662.            if (deadflag==0) jump very__late__error;
  4663.            print "^^    ";
  4664.            #IFV5; style bold; #ENDIF;
  4665.            print "***";
  4666.            if (deadflag==1) L__M(##Miscellany,3);
  4667.            if (deadflag==2) L__M(##Miscellany,4);
  4668.            if (deadflag>2)  { print " "; DeathMessage(); print " "; }
  4669.            print "***";
  4670.            #IFV5; style roman; #ENDIF;
  4671.            print "^^^";
  4672.            ScoreSub();
  4673.            DisplayStatus();
  4674.            AfterGameOver();
  4675.        ],
  4676.        end_turn_sequence
  4677.        [ i j;
  4678.            turns++;
  4679.            if (the_time~=NULL)
  4680.            {   if (time_rate>=0) the_time=the_time+time_rate;
  4681.                else
  4682.                {   time_step--;
  4683.                    if (time_step==0)
  4684.                    {   the_time++;
  4685.                        time_step = -time_rate;
  4686.                    }
  4687.                }
  4688.                the_time=the_time % 1440;
  4689.            }
  4690.            #IFDEF DEBUG;
  4691.            if (debug_flag & 4 ~= 0)
  4692.            {   for (i=0: i<active_timers: i++)
  4693.                {   j=the_timers-->i;
  4694.                    if (j~=0)
  4695.                    {   print (name) (j&$7fff), ": ";
  4696.                        if (j & $8000) print "daemon";
  4697.                        else
  4698.                        {   print "timer with ",
  4699.                                  j.time_left, " turns to go"; }
  4700.                        new_line;
  4701.                    }
  4702.                }
  4703.            }
  4704.            #ENDIF;
  4705.            for (i=0: i<active_timers: i++)
  4706.            {   if (deadflag) return;
  4707.                j=the_timers-->i;
  4708.                if (j~=0)
  4709.                {   if (j & $8000) RunRoutines(j&$7fff,daemon);
  4710.                    else
  4711.                    {   if (j.time_left==0)
  4712.                        {   StopTimer(j);
  4713.                            RunRoutines(j,time_out);
  4714.                        }
  4715.                        else
  4716.                            j.time_left=j.time_left-1;
  4717.                    }
  4718.                }
  4719.            }
  4720.            if (deadflag) return;
  4721.            scope_reason=EACH_TURN_REASON; verb_word=0;
  4722.            DoScopeAction(location);
  4723.            SearchScope(ScopeCeiling(player), player, 0);
  4724.            scope_reason=PARSING_REASON;
  4725.            if (deadflag) return;
  4726.            TimePasses();
  4727.            if (deadflag) return;
  4728.            AdjustLight();
  4729.            if (deadflag) return;
  4730.            NoteObjectAcquisitions();
  4731.        ],
  4732.        begin_action
  4733.        [ a n s source   sa sn ss;
  4734.            sa = action; sn = noun; ss = second;
  4735.            action = a; noun = n; second = s;
  4736.            #IFDEF DEBUG;
  4737.            if (debug_flag & 2 ~= 0) TraceAction(source);
  4738.            #IFNOT;
  4739.            source = 0;
  4740.            #ENDIF;
  4741.            #IFTRUE Grammar__Version == 1;
  4742.            if ((meta || BeforeRoutines()==false) && action<256)
  4743.                ActionPrimitive();
  4744.            #IFNOT;
  4745.            if ((meta || BeforeRoutines()==false) && action<4096)
  4746.                ActionPrimitive();
  4747.            #ENDIF;
  4748.            action = sa; noun = sn; second = ss;
  4749.        ],
  4750.   has  proper;
  4751. [ ActionPrimitive;
  4752.   indirect(#actions_table-->action);
  4753.        
  4754. [ AfterGameOver i;
  4755.    .RRQPL;
  4756.    L__M(##Miscellany,5);
  4757.    .RRQL;
  4758.    print "> ";
  4759.    #IFV3; read buffer parse; #ENDIF;
  4760.    temp_global=0;
  4761.    #IFV5; read buffer parse DrawStatusLine; #ENDIF;
  4762.    i=parse-->1;
  4763.    if (i==QUIT1__WD or QUIT2__WD) quit;
  4764.    if (i==RESTART__WD)      @restart;
  4765.    if (i==RESTORE__WD)      { RestoreSub(); jump RRQPL; }
  4766.    if (i==FULLSCORE1__WD or FULLSCORE2__WD && TASKS_PROVIDED==0)
  4767.    {   new_line; FullScoreSub(); jump RRQPL; }
  4768.    if (deadflag==2 && i==AMUSING__WD && AMUSING_PROVIDED==0)
  4769.    {   new_line; Amusing(); jump RRQPL; }
  4770.    #IFV5;
  4771.    if (i==UNDO1__WD or UNDO2__WD or UNDO3__WD)
  4772.    {   if (undo_flag==0)
  4773.        {   L__M(##Miscellany,6);
  4774.            jump RRQPL;
  4775.        }
  4776.        if (undo_flag==1) jump UndoFailed2;
  4777.        @restore_undo i;
  4778.        if (i==0)
  4779.        {   .UndoFailed2; L__M(##Miscellany,7);
  4780.        }
  4781.        jump RRQPL;
  4782.    #ENDIF;
  4783.    L__M(##Miscellany,8);
  4784.    jump RRQL;
  4785. [ R_Process a i j s1 s2;
  4786.    s1 = inp1; s2 = inp2;
  4787.    inp1 = i; inp2 = j; InformLibrary.begin_action(a, i, j, 1);
  4788.    inp1 = s1; inp2 = s2;
  4789. [ NoteObjectAcquisitions i;
  4790.   objectloop (i in player && i hasnt moved)
  4791.   {   give i moved;
  4792.       if (i has scored)
  4793.       {   score = score + OBJECT_SCORE;
  4794.           things_score = things_score + OBJECT_SCORE;
  4795.       }
  4796. ! ----------------------------------------------------------------------------
  4797. [ TestScope obj act a al sr x y;
  4798.   x=parser_one; y=parser_two;
  4799.   parser_one=obj; parser_two=0; a=actor; al=actors_location;
  4800.   sr=scope_reason; scope_reason=TESTSCOPE_REASON;
  4801.   if (act==0) actor=player; else actor=act;
  4802.   actors_location=ScopeCeiling(actor);
  4803.   SearchScope(actors_location,actor,0); scope_reason=sr; actor=a;
  4804.   actors_location=al; parser_one=x; x=parser_two; parser_two=y;
  4805.   return x;
  4806. [ LoopOverScope routine act x y a al;
  4807.   x = parser_one; y=scope_reason; a=actor; al=actors_location;
  4808.   parser_one=routine; if (act==0) actor=player; else actor=act;
  4809.   actors_location=ScopeCeiling(actor);
  4810.   scope_reason=LOOPOVERSCOPE_REASON;
  4811.   SearchScope(actors_location,actor,0);
  4812.   parser_one=x; scope_reason=y; actor=a; actors_location=al;
  4813. [ BeforeRoutines;
  4814.   if (GamePreRoutine()~=0) rtrue;
  4815.   if (RunRoutines(player,orders)~=0) rtrue;
  4816.   if (location~=0 && RunRoutines(location,before)~=0) rtrue;
  4817.   scope_reason=REACT_BEFORE_REASON; parser_one=0;
  4818.   SearchScope(ScopeCeiling(player),player,0); scope_reason=PARSING_REASON;
  4819.   if (parser_one~=0) rtrue;
  4820.   if (inp1>1 && RunRoutines(inp1,before)~=0) rtrue;
  4821.   rfalse;
  4822. [ AfterRoutines;
  4823.   scope_reason=REACT_AFTER_REASON; parser_one=0;
  4824.   SearchScope(ScopeCeiling(player),player,0); scope_reason=PARSING_REASON;
  4825.   if (parser_one~=0) rtrue;
  4826.   if (location~=0 && RunRoutines(location,after)~=0) rtrue;
  4827.   if (inp1>1 && RunRoutines(inp1,after)~=0) rtrue;
  4828.   return GamePostRoutine();
  4829. [ RunLife a j;
  4830. #IFDEF DEBUG;
  4831.    if (debug_flag & 2 ~= 0) TraceAction(2, j);
  4832. #ENDIF;
  4833.    reason_code = j; return RunRoutines(a,life);
  4834. [ ZRegion addr;
  4835.   switch(metaclass(addr))       ! Left over from Inform 5
  4836.   {   nothing: return 0;
  4837.       Object, Class: return 1;
  4838.       Routine: return 2;
  4839.       String: return 3;
  4840. [ PrintOrRun obj prop flag;
  4841.   if (obj.#prop > 2) return RunRoutines(obj,prop);
  4842.   if (obj.prop==NULL) rfalse;
  4843.   switch(metaclass(obj.prop))
  4844.   {   Class, Object, nothing: return RunTimeError(2,obj,prop);
  4845.       String: print (string) obj.prop; if (flag==0) new_line; rtrue;
  4846.       Routine: return RunRoutines(obj,prop);
  4847. [ ValueOrRun obj prop;
  4848.   if (obj.prop < 256) return obj.prop;
  4849.   return RunRoutines(obj, prop);
  4850. [ RunRoutines obj prop;
  4851.    if (obj == thedark
  4852.        && prop ~= initial or short_name or description) obj=real_location;
  4853.    if (obj.&prop == 0) rfalse;
  4854.    return obj.prop();
  4855. [ ChangeDefault prop val a b;
  4856.    ! Use assembly-language here because -S compilation won't allow this:
  4857.    @loadw 0 5 -> a;
  4858.    b = prop-1;
  4859.    @storew a b val;
  4860. ! ----------------------------------------------------------------------------
  4861. [ StartTimer obj timer i;
  4862.    for (i=0:i<active_timers:i++)
  4863.        if (the_timers-->i==obj) rfalse;
  4864.    for (i=0:i<active_timers:i++)
  4865.        if (the_timers-->i==0) jump FoundTSlot;
  4866.    i=active_timers++;
  4867.    if (i >= MAX_TIMERS) RunTimeError(4);
  4868.    .FoundTSlot;
  4869.    if (obj.&time_left==0) RunTimeError(5,obj);
  4870.    the_timers-->i=obj; obj.time_left=timer;
  4871. [ StopTimer obj i;
  4872.    for (i=0:i<active_timers:i++)
  4873.        if (the_timers-->i==obj) jump FoundTSlot2;
  4874.    rfalse;
  4875.    .FoundTSlot2;
  4876.    if (obj.&time_left==0) RunTimeError(5,obj);
  4877.    the_timers-->i=0; obj.time_left=0;
  4878. [ StartDaemon obj i;
  4879.    for (i=0:i<active_timers:i++)
  4880.        if (the_timers-->i == $8000 + obj)
  4881.            rfalse;
  4882.    for (i=0:i<active_timers:i++)
  4883.        if (the_timers-->i==0) jump FoundTSlot3;
  4884.    i=active_timers++;
  4885.    if (i >= MAX_TIMERS) RunTimeError(4);
  4886.    .FoundTSlot3;
  4887.    the_timers-->i = $8000 + obj;
  4888. [ StopDaemon obj i;
  4889.    for (i=0:i<active_timers:i++)
  4890.        if (the_timers-->i == $8000 + obj) jump FoundTSlot4;
  4891.    rfalse;
  4892.    .FoundTSlot4;
  4893.    the_timers-->i=0;
  4894. ! ----------------------------------------------------------------------------
  4895. [ DisplayStatus;
  4896.    if (the_time==NULL)
  4897.    {   sline1=score; sline2=turns; }
  4898.    else
  4899.    {   sline1=the_time/60; sline2=the_time%60; }
  4900. [ SetTime t s;
  4901.    the_time=t; time_rate=s; time_step=0;
  4902.    if (s<0) time_step=0-s;
  4903. [ NotifyTheScore;
  4904.    print "^[";  L__M(##Miscellany, 50, score-last_score);  print ".]^";
  4905. ! ----------------------------------------------------------------------------
  4906. [ AdjustLight flag i;
  4907.    i=lightflag;
  4908.    lightflag=OffersLight(parent(player));
  4909.    if (i==0 && lightflag==1)
  4910.    {   location=real_location; if (flag==0) <Look>;
  4911.    if (i==1 && lightflag==0)
  4912.    {   real_location=location; location=thedark;
  4913.        if (flag==0) { NoteArrival();
  4914.                       return L__M(##Miscellany, 9); }
  4915.    if (i==0 && lightflag==0) location=thedark;
  4916. [ OffersLight i j;
  4917.    if (i==0) rfalse;
  4918.    if (i has light) rtrue;
  4919.    objectloop (j in i)
  4920.        if (HasLightSource(j)==1) rtrue;
  4921.    if (i has container)
  4922.    {   if (i has open || i has transparent)
  4923.            return OffersLight(parent(i));
  4924.    else
  4925.    {   if (i has enterable || i has transparent || i has supporter)
  4926.            return OffersLight(parent(i));
  4927.    rfalse;
  4928. [ HidesLightSource obj;
  4929.     if (obj == player) rfalse;
  4930.     if (obj has transparent or supporter) rfalse;
  4931.     if (obj has container) return obj hasnt open;
  4932.     return obj hasnt enterable;
  4933. [ HasLightSource i j ad;
  4934.    if (i==0) rfalse;
  4935.    if (i has light) rtrue;
  4936.    if (i has enterable || IsSeeThrough(i)==1)
  4937.        if (~~(HidesLightSource(i)))
  4938.            objectloop (j in i)
  4939.                if (HasLightSource(j)==1) rtrue;
  4940.    ad = i.&add_to_scope;
  4941.    if (parent(i)~=0 && ad ~= 0)
  4942.    {   if (metaclass(ad-->0) == Routine)
  4943.        {   ats_hls = 0; ats_flag = 1;
  4944.            RunRoutines(i, add_to_scope);
  4945.            ats_flag = 0; if (ats_hls == 1) rtrue;
  4946.        }
  4947.        else
  4948.        {   for (j=0:(2*j)<i.#add_to_scope:j++)
  4949.                if (HasLightSource(ad-->j)==1) rtrue;
  4950.        }
  4951.    rfalse;
  4952. [ ChangePlayer obj flag i;
  4953. !  if (obj.&number==0) return RunTimeError(7,obj);
  4954.   if (actor==player) actor=obj;
  4955.   give player ~transparent ~concealed;
  4956.   i=obj; while(parent(i)~=0) { if (i has animate) give i transparent;
  4957.                                i=parent(i); }
  4958.   if (player==selfobj) player.short_name=FORMER__TX;
  4959.   player=obj;
  4960.   if (player==selfobj) player.short_name=NULL;
  4961.   give player transparent concealed animate proper;
  4962.   i=player; while(parent(i)~=0) i=parent(i); location=i;
  4963.   real_location=location;
  4964.   MoveFloatingObjects();
  4965.   lightflag=OffersLight(parent(player));
  4966.   if (lightflag==0) location=thedark;
  4967.   print_player_flag=flag;
  4968. ! ----------------------------------------------------------------------------
  4969. #IFDEF DEBUG;
  4970. [ DebugParameter w x n l;
  4971.   x=0-->4; x=x+(x->0)+1; l=x->0; n=(x+1)-->0; x=w-(x+3);
  4972.   print w;
  4973.   if (w>=1 && w<=top_object) print " (", (name) w, ")";
  4974.   if (x%l==0 && (x/l)<n) print " ('", (address) w, "')";
  4975. [ DebugAction a anames;
  4976. #iftrue Grammar__Version==1;
  4977.   if (a>=256) { print "<fake action ", a-256, ">"; return; }
  4978. #ifnot;
  4979.   if (a>=4096) { print "<fake action ", a-4096, ">"; return; }
  4980. #endif;
  4981.   anames = #identifiers_table;
  4982.   anames = anames + 2*(anames-->0) + 2*48;
  4983.   print (string) anames-->a;
  4984. [ DebugAttribute a anames;
  4985.   if (a<0 || a>=48) print "<invalid attribute ", a, ">";
  4986.   else
  4987.   {   anames = #identifiers_table; anames = anames + 2*(anames-->0);
  4988.       print (string) anames-->a;
  4989. [ TraceAction source ar;
  4990.   if (source<2) print "[ Action ", (DebugAction) action;
  4991.   else
  4992.   {   if (ar==##Order)
  4993.           print "[ Order to ", (name) actor, ": ", (DebugAction) action;
  4994.       else
  4995.           print "[ Life rule ", (DebugAction) ar;
  4996.   if (noun~=0)   print " with noun ", (DebugParameter) noun;
  4997.   if (second~=0) print " and second ", (DebugParameter) second;
  4998.   if (source==0) print " ";
  4999.   if (source==1) print " (from < > statement) ";
  5000.   print "]^";
  5001. [ DebugToken token;
  5002.   AnalyseToken(token);
  5003.   switch(found_ttype)
  5004.   {   ILLEGAL_TT: print "<illegal token number ", token, ">";
  5005.       ELEMENTARY_TT:
  5006.       switch(found_tdata)
  5007.       {   NOUN_TOKEN:        print "noun";
  5008.           HELD_TOKEN:        print "held";
  5009.           MULTI_TOKEN:       print "multi";
  5010.           MULTIHELD_TOKEN:   print "multiheld";
  5011.           MULTIEXCEPT_TOKEN: print "multiexcept";
  5012.           MULTIINSIDE_TOKEN: print "multiinside";
  5013.           CREATURE_TOKEN:    print "creature";
  5014.           SPECIAL_TOKEN:     print "special";
  5015.           NUMBER_TOKEN:      print "number";
  5016.           TOPIC_TOKEN:       print "topic";
  5017.           ENDIT_TOKEN:       print "END";
  5018.       }
  5019.       PREPOSITION_TT:
  5020.           print "'", (address) found_tdata, "'";
  5021.       ROUTINE_FILTER_TT:
  5022.       #ifdef INFIX; print "noun=", (InfixPrintPA) found_tdata;
  5023.       #ifnot; print "noun=Routine(", found_tdata, ")"; #endif;
  5024.       ATTR_FILTER_TT:
  5025.           print (DebugAttribute) found_tdata;
  5026.       SCOPE_TT:
  5027.       #ifdef INFIX; print "scope=", (InfixPrintPA) found_tdata;
  5028.       #ifnot; print "scope=Routine(", found_tdata, ")"; #endif;
  5029.       GPR_TT:
  5030.       #ifdef INFIX; print (InfixPrintPA) found_tdata;
  5031.       #ifnot; print "Routine(", found_tdata, ")"; #endif;
  5032. [ DebugGrammarLine pcount;
  5033.   print " * ";
  5034.   for (:line_token-->pcount ~= ENDIT_TOKEN:pcount++)
  5035.   {   if ((line_token-->pcount)->0 & $10) print "/ ";
  5036.       print (DebugToken) line_token-->pcount, " ";
  5037.   print "-> ", (DebugAction) action_to_be;
  5038.   if (action_reversed) print " reverse";
  5039. [ ShowVerbSub address lines da meta i j;
  5040.     if (((noun->#dict_par1) & 1) == 0)
  5041.       "Try typing ~showverb~ and then the name of a verb.";
  5042.     meta=((noun->#dict_par1) & 2)/2;
  5043.     i = $ff-(noun->#dict_par2);
  5044.     address = (0-->7)-->i;
  5045.     lines = address->0;
  5046.     address++;
  5047.     print "Verb ";
  5048.     if (meta) print "meta ";
  5049.     da = 0-->4;
  5050.     for (j=0:j < (da+5)-->0:j++)
  5051.         if (da->(j*9 + 14) == $ff-i)
  5052.             print "'", (address) (da + 9*j + 7), "' ";
  5053.     new_line;
  5054.     if (lines == 0) "has no grammar lines.";
  5055.     for (:lines > 0:lines--)
  5056.     {   address = UnpackGrammarLine(address);
  5057.         print "    "; DebugGrammarLine(); new_line;
  5058.     }
  5059. [ ShowobjSub c f l a n x;
  5060.    if (noun==0) noun=location;
  5061.    objectloop (c ofclass Class) if (noun ofclass c) { f++; l=c; }
  5062.    if (f == 1) print (name) l, " ~"; else print "Object ~";
  5063.    print (name) noun, "~ (", noun, ")";
  5064.    if (parent(noun)~=0) print " in ~", (name) parent(noun), "~";
  5065.    new_line;
  5066.    if (f > 1)
  5067.    {   print "  class ";
  5068.        objectloop (c ofclass Class) if (noun ofclass c) print (name) c, " ";
  5069.        new_line;
  5070.    for (a=0,f=0:a<48:a++) if (noun has a) f=1;
  5071.    if (f)
  5072.    {   print "  has ";
  5073.        for (a=0:a<48:a++) if (noun has a) print (DebugAttribute) a, " ";
  5074.        new_line;
  5075.    if (noun ofclass Class) return;
  5076.    f=0; l = #identifiers_table-->0;
  5077.    for (a=1:a<=l:a++)
  5078.    {   if ((a~=2 or 3) && noun.&a)
  5079.        {   if (f==0) { print "  with "; f=1; }
  5080.            print (property) a;
  5081.            n = noun.#a;
  5082.            for (c=0:2*c<n:c++)
  5083.            {   print " ";
  5084.                x = (noun.&a)-->c;
  5085.                if (a==name) print "'", (address) x, "'";
  5086.                else
  5087.                {   if (a==number or capacity or time_left)
  5088.                        print x;
  5089.                    else
  5090.                    {   switch(x)
  5091.                        {   NULL: print "NULL";
  5092.                            0: print "0";
  5093.                            1: print "1";
  5094.                            default:
  5095.                            switch(metaclass(x))
  5096.                            {   Class, Object: print (name) x;
  5097.                                String: print "~", (string) x, "~";
  5098.                                Routine: print "[...]";
  5099.                            }
  5100.                            print " (", x, ")";
  5101.                        }
  5102.                    }
  5103.                }
  5104.            }
  5105.            print ",^       ";
  5106.        }
  5107. !   if (f==1) new_line;
  5108. #ENDIF;
  5109. ! ----------------------------------------------------------------------------
  5110. !  Except in Version 3, the DrawStatusLine routine does just that: this is
  5111. !  provided explicitly so that it can be Replace'd to change the style, and
  5112. !  as written it emulates the ordinary Standard game status line, which is
  5113. !  drawn in hardware
  5114. ! ----------------------------------------------------------------------------
  5115. #IFV5;
  5116. [ DrawStatusLine width posa posb;
  5117.    @split_window 1; @set_window 1; @set_cursor 1 1; style reverse;
  5118.    width = 0->33; posa = width-26; posb = width-13;
  5119.    spaces width;
  5120.    @set_cursor 1 2;
  5121.    if (location == thedark) print (name) location;
  5122.    else
  5123.    {   FindVisibilityLevels();
  5124.        if (visibility_ceiling == location)
  5125.            print (name) location;
  5126.        else print (The) visibility_ceiling;
  5127.    if ((0->1)&2 == 0)
  5128.    {   if (width > 76)
  5129.        {   @set_cursor 1 posa; print (string) SCORE__TX, sline1;
  5130.            @set_cursor 1 posb; print (string) MOVES__TX, sline2;
  5131.        }
  5132.        if (width > 63 && width <= 76)
  5133.        {   @set_cursor 1 posb; print sline1, "/", sline2;
  5134.        }
  5135.    else
  5136.    {   @set_cursor 1 posa;
  5137.        print (string) TIME__TX;
  5138.        LanguageTimeOfDay(sline1, sline2);
  5139.    @set_cursor 1 1; style roman; @set_window 0;
  5140. #ENDIF;
  5141. #ifv5;
  5142. Array StorageForShortName --> 161;
  5143. #endif;
  5144. [ PrefaceByArticle o acode pluralise  i artform findout;
  5145.    if (o provides articles)
  5146.    {   print (string) (o.&articles)-->(acode+short_name_case*LanguageCases),
  5147.            " ";
  5148.        if (pluralise) return;
  5149.        print (PSN__) o; return;
  5150.    i = GetGNAOfObject(o);
  5151.    if (pluralise)
  5152.    {   if (i<3 || (i>=6 && i<9)) i = i + 3;
  5153.    i = LanguageGNAsToArticles-->i;
  5154.    artform = LanguageArticles
  5155.              + 6*LanguageContractionForms*(short_name_case + i*LanguageCases);
  5156. #iftrue LanguageContractionForms == 2;
  5157.    if (artform-->acode ~= artform-->(acode+3)) findout = true;
  5158. #endif;
  5159. #iftrue LanguageContractionForms == 3;
  5160.    if (artform-->acode ~= artform-->(acode+3)) findout = true;
  5161.    if (artform-->(acode+3) ~= artform-->(acode+6)) findout = true;
  5162. #endif;
  5163. #iftrue LanguageContractionForms == 4;
  5164.    if (artform-->acode ~= artform-->(acode+3)) findout = true;
  5165.    if (artform-->(acode+3) ~= artform-->(acode+6)) findout = true;
  5166.    if (artform-->(acode+6) ~= artform-->(acode+9)) findout = true;
  5167. #endif;
  5168. #iftrue LanguageContractionForms > 4;
  5169.    findout = true;
  5170. #endif;
  5171.    if (standard_interpreter ~= 0 && findout)
  5172.    {   StorageForShortName-->0 = 160;
  5173.        @output_stream 3 StorageForShortName;
  5174.        if (pluralise) print (number) pluralise; else print (PSN__) o;
  5175.        @output_stream -3;
  5176.        acode = acode + 3*LanguageContraction(StorageForShortName + 2);
  5177.    print (string) artform-->acode;
  5178.    if (pluralise) return;
  5179.    print (PSN__) o;
  5180. [ PSN__ o;
  5181.    if (o==0) { print (string) NOTHING__TX; rtrue; }
  5182.    switch(metaclass(o))
  5183.    {   Routine: print "<routine ", o, ">"; rtrue;
  5184.        String:  print "<string ~", (string) o, "~>"; rtrue;
  5185.        nothing: print "<illegal object number ", o, ">"; rtrue;
  5186.    if (o==player) { print (string) YOURSELF__TX; rtrue; }
  5187.    #ifdef LanguagePrintShortName;
  5188.    if (LanguagePrintShortName(o)) rtrue;
  5189.    #endif;
  5190.    if (indef_mode && o.&short_name_indef~=0
  5191.        && PrintOrRun(o, short_name_indef, 1)~=0) rtrue;
  5192.    if (o.&short_name~=0 && PrintOrRun(o,short_name,1)~=0) rtrue;
  5193.    @print_obj o;
  5194. [ Indefart o i;
  5195.    i = indef_mode; indef_mode = true;
  5196.    if (o has proper) { indef_mode = NULL; print (PSN__) o; return; }
  5197.    if (o provides article)
  5198.    {   PrintOrRun(o,article,1); print " ", (PSN__) o; indef_mode = i; return;
  5199.    PrefaceByArticle(o, 2); indef_mode = i;
  5200. [ Defart o i;
  5201.    i = indef_mode; indef_mode = false;
  5202.    if (o has proper)
  5203.    { indef_mode = NULL; print (PSN__) o; indef_mode = i; return; }
  5204.    PrefaceByArticle(o, 1); indef_mode = i;
  5205. [ CDefart o i;
  5206.    i = indef_mode; indef_mode = false;
  5207.    if (o has proper)
  5208.    { indef_mode = NULL; print (PSN__) o; indef_mode = i; return; }
  5209.    PrefaceByArticle(o, 0); indef_mode = i;
  5210. [ PrintShortName o i;
  5211.    i = indef_mode; indef_mode = NULL;
  5212.    PSN__(o); indef_mode = i;
  5213. [ EnglishNumber n; LanguageNumber(n); ];
  5214. [ NumberWord o i n;
  5215.   n = LanguageNumbers-->0;
  5216.   for (i=1:i<=n:i=i+2)
  5217.       if (o == LanguageNumbers-->i)
  5218.           return LanguageNumbers-->(i+1);
  5219.   return 0;
  5220. [ RandomEntry tab;
  5221.   if (tab-->0==0) return RunTimeError(8);
  5222.   return tab-->(random(tab-->0));
  5223. ! ----------------------------------------------------------------------------
  5224. !  Useful routine: unsigned comparison (for addresses in Z-machine)
  5225. !    Returns 1 if x>y, 0 if x=y, -1 if x<y
  5226. ! ----------------------------------------------------------------------------
  5227. [ UnsignedCompare x y u v;
  5228.   if (x==y) return 0;
  5229.   if (x<0 && y>=0) return 1;
  5230.   if (x>=0 && y<0) return -1;
  5231.   u = x&$7fff; v= y&$7fff;
  5232.   if (u>v) return 1;
  5233.   return -1;
  5234. ! ----------------------------------------------------------------------------
  5235. ! ===========================================================================
  5236. !   Inform Language Definition File: English 981213
  5237. !   (c) Graham Nelson 1997, 1998
  5238. !   Define the constant DIALECT_US before including "Parser" to
  5239. !   obtain American English
  5240. ! ---------------------------------------------------------------------------
  5241. System_file;
  5242. ! ---------------------------------------------------------------------------
  5243. !   Part I.   Preliminaries
  5244. ! ---------------------------------------------------------------------------
  5245. Constant EnglishNaturalLanguage;   ! Needed to keep old pronouns mechanism
  5246. Class  CompassDirection
  5247.   with article "the", number 0
  5248.   has  scenery;
  5249. Object Compass "compass" has concealed;
  5250. IFNDEF WITHOUT_DIRECTIONS;
  5251. CompassDirection -> n_obj "north wall"
  5252.                     with name 'n//' 'north' 'wall',    door_dir n_to;
  5253. CompassDirection -> s_obj "south wall"
  5254.                     with name 's//' 'south' 'wall',    door_dir s_to;
  5255. CompassDirection -> e_obj "east wall"
  5256.                     with name 'e//' 'east' 'wall',     door_dir e_to;
  5257. CompassDirection -> w_obj "west wall"
  5258.                     with name 'w//' 'west' 'wall',     door_dir w_to;
  5259. CompassDirection -> ne_obj "northeast wall"
  5260.                     with name 'ne' 'northeast' 'wall', door_dir ne_to;
  5261. CompassDirection -> nw_obj "northwest wall"
  5262.                     with name 'nw' 'northwest' 'wall', door_dir nw_to;
  5263. CompassDirection -> se_obj "southeast wall"
  5264.                     with name 'se' 'southeast' 'wall', door_dir se_to;
  5265. CompassDirection -> sw_obj "southwest wall"
  5266.                     with name 'sw' 'southwest' 'wall', door_dir sw_to;
  5267. CompassDirection -> u_obj "ceiling"
  5268.                     with name 'u//' 'up' 'ceiling',    door_dir u_to;
  5269. CompassDirection -> d_obj "floor"
  5270.                     with name 'd//' 'down' 'floor',    door_dir d_to;
  5271. ENDIF;
  5272. CompassDirection -> out_obj "outside"
  5273.                     with                               door_dir out_to;
  5274. CompassDirection -> in_obj "inside"
  5275.                     with                               door_dir in_to;
  5276. ! ---------------------------------------------------------------------------
  5277. !   Part II.   Vocabulary
  5278. ! ---------------------------------------------------------------------------
  5279. Constant AGAIN1__WD   = 'again';
  5280. Constant AGAIN2__WD   = 'g//';
  5281. Constant AGAIN3__WD   = 'again';
  5282. Constant OOPS1__WD    = 'oops';
  5283. Constant OOPS2__WD    = 'o//';
  5284. Constant OOPS3__WD    = 'oops';
  5285. Constant UNDO1__WD    = 'undo';
  5286. Constant UNDO2__WD    = 'undo';
  5287. Constant UNDO3__WD    = 'undo';
  5288. Constant ALL1__WD     = 'all';
  5289. Constant ALL2__WD     = 'each';
  5290. Constant ALL3__WD     = 'every';
  5291. Constant ALL4__WD     = 'everything';
  5292. Constant ALL5__WD     = 'both';
  5293. Constant AND1__WD     = 'and';
  5294. Constant AND2__WD     = 'and';
  5295. Constant AND3__WD     = 'and';
  5296. Constant BUT1__WD     = 'but';
  5297. Constant BUT2__WD     = 'except';
  5298. Constant BUT3__WD     = 'but';
  5299. Constant ME1__WD      = 'me';
  5300. Constant ME2__WD      = 'myself';
  5301. Constant ME3__WD      = 'self';
  5302. Constant OF1__WD      = 'of';
  5303. Constant OF2__WD      = 'of';
  5304. Constant OF3__WD      = 'of';
  5305. Constant OF4__WD      = 'of';
  5306. Constant OTHER1__WD   = 'another';
  5307. Constant OTHER2__WD   = 'other';
  5308. Constant OTHER3__WD   = 'other';
  5309. Constant THEN1__WD    = 'then';
  5310. Constant THEN2__WD    = 'then';
  5311. Constant THEN3__WD    = 'then';
  5312. Constant NO1__WD      = 'n//';
  5313. Constant NO2__WD      = 'no';
  5314. Constant NO3__WD      = 'no';
  5315. Constant YES1__WD     = 'y//';
  5316. Constant YES2__WD     = 'yes';
  5317. Constant YES3__WD     = 'yes';
  5318. Constant AMUSING__WD  = 'amusing';
  5319. Constant FULLSCORE1__WD = 'fullscore';
  5320. Constant FULLSCORE2__WD = 'full';
  5321. Constant QUIT1__WD    = 'q//';
  5322. Constant QUIT2__WD    = 'quit';
  5323. Constant RESTART__WD  = 'restart';
  5324. Constant RESTORE__WD  = 'restore';
  5325. Array LanguagePronouns table
  5326.    !  word       possible GNAs                   connected
  5327.    !             to follow:                      to:
  5328.    !             a     i
  5329.    !             s  p  s  p
  5330.    !             mfnmfnmfnmfn                 
  5331.       'it'     $$001000111000                    NULL
  5332.       'him'    $$100000000000                    NULL
  5333.       'her'    $$010000000000                    NULL
  5334.       'them'   $$000111000111                    NULL;
  5335. Array LanguageDescriptors table
  5336.    !  word       possible GNAs   descriptor      connected
  5337.    !             to follow:      type:           to:
  5338.    !             a     i
  5339.    !             s  p  s  p
  5340.    !             mfnmfnmfnmfn                 
  5341.       'my'     $$111111111111    POSSESS_PK      0
  5342.       'this'   $$111111111111    POSSESS_PK      0
  5343.       'these'  $$000111000111    POSSESS_PK      0
  5344.       'that'   $$111111111111    POSSESS_PK      1
  5345.       'those'  $$000111000111    POSSESS_PK      1
  5346.       'his'    $$111111111111    POSSESS_PK      'him'
  5347.       'her'    $$111111111111    POSSESS_PK      'her'
  5348.       'their'  $$111111111111    POSSESS_PK      'them'
  5349.       'its'    $$111111111111    POSSESS_PK      'it'
  5350.       'the'    $$111111111111    DEFART_PK       NULL
  5351.       'a//'    $$111000111000    INDEFART_PK     NULL
  5352.       'an'     $$111000111000    INDEFART_PK     NULL
  5353.       'some'   $$000111000111    INDEFART_PK     NULL
  5354.       'lit'    $$111111111111    light           NULL
  5355.      'lighted' $$111111111111    light           NULL
  5356.       'unlit'  $$111111111111    (-light)        NULL;
  5357. Array LanguageNumbers table
  5358.     'one' 1 'two' 2 'three' 3 'four' 4 'five' 5
  5359.     'six' 6 'seven' 7 'eight' 8 'nine' 9 'ten' 10
  5360.     'eleven' 11 'twelve' 12 'thirteen' 13 'fourteen' 14 'fifteen' 15
  5361.     'sixteen' 16 'seventeen' 17 'eighteen' 18 'nineteen' 19 'twenty' 20;
  5362. ! ---------------------------------------------------------------------------
  5363. !   Part III.   Translation
  5364. ! ---------------------------------------------------------------------------
  5365. [ LanguageToInformese;
  5366. ! ---------------------------------------------------------------------------
  5367. !   Part IV.   Printing
  5368. ! ---------------------------------------------------------------------------
  5369. Constant LanguageAnimateGender   = male;
  5370. Constant LanguageInanimateGender = neuter;
  5371. Constant LanguageContractionForms = 2;     ! English has two:
  5372.                                            ! 0 = starting with a consonant
  5373.                                            ! 1 = starting with a vowel
  5374. [ LanguageContraction text;
  5375.   if (text->0 == 'a' or 'e' or 'i' or 'o' or 'u'
  5376.                  or 'A' or 'E' or 'I' or 'O' or 'U') return 1;
  5377.   return 0;
  5378. Array LanguageArticles -->
  5379.  !   Contraction form 0:     Contraction form 1:
  5380.  !   Cdef   Def    Indef     Cdef   Def    Indef
  5381.      "The " "the " "a "      "The " "the " "an "          ! Articles 0
  5382.      "The " "the " "some "   "The " "the " "some ";       ! Articles 1
  5383.                    !             a           i
  5384.                    !             s     p     s     p
  5385.                    !             m f n m f n m f n m f n                 
  5386. Array LanguageGNAsToArticles --> 0 0 0 1 1 1 0 0 0 1 1 1;
  5387. [ LanguageDirection d;
  5388.    switch(d)
  5389.    {   n_to: print "north";
  5390.        s_to: print "south";
  5391.        e_to: print "east";
  5392.        w_to: print "west";
  5393.        ne_to: print "northeast";
  5394.        nw_to: print "northwest";
  5395.        se_to: print "southeast";
  5396.        sw_to: print "southwest";
  5397.        u_to: print "up";
  5398.        d_to: print "down";
  5399.        in_to: print "in";
  5400.        out_to: print "out";
  5401.        default: return RunTimeError(9,d);
  5402. [ LanguageNumber n f;
  5403.   if (n==0)    { print "zero"; rfalse; }
  5404.   if (n<0)     { print "minus "; n=-n; }
  5405.   if (n>=1000) { print (LanguageNumber) n/1000, " thousand"; n=n%1000; f=1; }
  5406.   if (n>=100)  { if (f==1) print ", ";
  5407.                  print (LanguageNumber) n/100, " hundred"; n=n%100; f=1; }
  5408.   if (n==0) rfalse;
  5409.   #ifndef DIALECT_US;
  5410.   if (f==1) print " and ";
  5411.   #ifnot;
  5412.   if (f==1) print " ";
  5413.   #endif;
  5414.   switch(n)
  5415.   {   1:  print "one";
  5416.       2:  print "two";
  5417.       3:  print "three";
  5418.       4:  print "four";
  5419.       5:  print "five";
  5420.       6:  print "six";
  5421.       7:  print "seven";
  5422.       8:  print "eight";
  5423.       9:  print "nine";
  5424.       10: print "ten";
  5425.       11: print "eleven";
  5426.       12: print "twelve";
  5427.       13: print "thirteen";
  5428.       14: print "fourteen";
  5429.       15: print "fifteen";
  5430.       16: print "sixteen";
  5431.       17: print "seventeen";
  5432.       18: print "eighteen";
  5433.       19: print "nineteen";
  5434.       20 to 99:
  5435.           switch(n/10)
  5436.           {  2: print "twenty";
  5437.              3: print "thirty";
  5438.              4: print "forty";
  5439.              5: print "fifty";
  5440.              6: print "sixty";
  5441.              7: print "seventy";
  5442.              8: print "eighty";
  5443.              9: print "ninety";
  5444.           }
  5445.           if (n%10 ~= 0) print "-", (LanguageNumber) n%10;
  5446. [ LanguageTimeOfDay hours mins i;
  5447.    i=hours%12;
  5448.    if (i==0) i=12;
  5449.    if (i<10) print " ";
  5450.    print i, ":", mins/10, mins%10;
  5451.    if ((hours/12) > 0) print " pm"; else print " am";
  5452. [ LanguageVerb i;
  5453.    if (i==#n$l)        { print "look";              rtrue; }
  5454.    if (i==#n$z)        { print "wait";              rtrue; }
  5455.    if (i==#n$x)        { print "examine";           rtrue; }
  5456.    if (i==#n$i or 'inv' or 'inventory')
  5457.                        { print "inventory";         rtrue; }
  5458.    rfalse;
  5459. Constant NKEY__TX     = "N = next subject";
  5460. Constant PKEY__TX     = "P = previous";
  5461. Constant QKEY1__TX    = "  Q = resume game";
  5462. Constant QKEY2__TX    = "Q = previous menu";
  5463. Constant RKEY__TX     = "RETURN = read subject";
  5464. Constant NKEY1__KY    = 'N';
  5465. Constant NKEY2__KY    = 'n';
  5466. Constant PKEY1__KY    = 'P';
  5467. Constant PKEY2__KY    = 'p';
  5468. Constant QKEY1__KY    = 'Q';
  5469. Constant QKEY2__KY    = 'q';
  5470. Constant SCORE__TX    = "Score: ";
  5471. Constant MOVES__TX    = "Moves: ";
  5472. Constant TIME__TX     = "Time: ";
  5473. Constant CANTGO__TX   = "You can't go that way.";
  5474. Constant FORMER__TX   = "your former self";
  5475. Constant YOURSELF__TX = "yourself";
  5476. Constant DARKNESS__TX = "Darkness";
  5477. Constant THOSET__TX   = "those things";
  5478. Constant THAT__TX     = "that";
  5479. Constant OR__TX       = " or ";
  5480. Constant NOTHING__TX  = "nothing";
  5481. Constant IS__TX       = " is";
  5482. Constant ARE__TX      = " are";
  5483. Constant IS2__TX      = "is ";
  5484. Constant ARE2__TX     = "are ";
  5485. Constant AND__TX      = " and ";
  5486. Constant WHOM__TX     = "whom ";
  5487. Constant WHICH__TX    = "which ";
  5488. [ ThatorThose obj;   ! Used in the accusative
  5489.   if (obj == player) { print "you"; return; }
  5490.   if (obj has pluralname) { print "those"; return; }
  5491.   if (obj has animate)
  5492.   {   if (obj has female) { print "her"; return; }
  5493.       else if (obj hasnt neuter) { print "him"; return; }
  5494.   print "that";
  5495. [ ItorThem obj;
  5496.   if (obj == player) { print "yourself"; return; }
  5497.   if (obj has pluralname) { print "them"; return; }
  5498.   if (obj has animate)
  5499.   {   if (obj has female) { print "her"; return; }
  5500.       else if (obj hasnt neuter) { print "him"; return; }
  5501.   print "it";
  5502. [ IsorAre obj;
  5503.   if (obj has pluralname || obj == player) print "are"; else print "is";
  5504. [ CThatorThose obj;   ! Used in the nominative
  5505.   if (obj == player) { print "You"; return; }
  5506.   if (obj has pluralname) { print "Those"; return; }
  5507.   if (obj has animate)
  5508.   {   if (obj has female) { print "She"; return; }
  5509.       else if (obj hasnt neuter) { print "He"; return; }
  5510.   print "That";
  5511. [ CTheyreorThats obj;
  5512.   if (obj == player) { print "You're"; return; }
  5513.   if (obj has pluralname) { print "They're"; return; }
  5514.   if (obj has animate)
  5515.   {   if (obj has female) { print "She's"; return; }
  5516.       else if (obj hasnt neuter) { print "He's"; return; }
  5517.   print "That's";
  5518. [ LanguageLM n x1;
  5519.   Prompt:  print "^>";
  5520.   Miscellany:
  5521.            switch(n)
  5522.            {   1: "(considering the first sixteen objects only)^";
  5523.                2: "Nothing to do!";
  5524.                3: print " You have died ";
  5525.                4: print " You have won ";
  5526.                5: print "^Would you like to RESTART, RESTORE a saved game";
  5527.                   #IFDEF DEATH_MENTION_UNDO;
  5528.                   print ", UNDO your last move";
  5529.                   #ENDIF;
  5530.                   if (TASKS_PROVIDED==0)
  5531.                       print ", give the FULL score for that game";
  5532.                   if (deadflag==2 && AMUSING_PROVIDED==0)
  5533.                       print ", see some suggestions for AMUSING things to do";
  5534.                   " or QUIT?";
  5535.                6: "[Your interpreter does not provide ~undo~.  Sorry!]";
  5536.                7: "~Undo~ failed.  [Not all interpreters provide it.]";
  5537.                8: "Please give one of the answers above.";
  5538.                9: "^It is now pitch dark in here!";
  5539.               10: "I beg your pardon?";
  5540.               11: "[You can't ~undo~ what hasn't been done!]";
  5541.               12: "[Can't ~undo~ twice in succession. Sorry!]";
  5542.               13: "[Previous turn undone.]";
  5543.               14: "Sorry, that can't be corrected.";
  5544.               15: "Think nothing of it.";
  5545.               16: "~Oops~ can only correct a single word.";
  5546.               17: "It is pitch dark, and you can't see a thing.";
  5547.               18: print "yourself";
  5548.               19: "As good-looking as ever.";           
  5549.               20: "To repeat a command like ~frog, jump~, just say
  5550.                    ~again~, not ~frog, again~.";
  5551.               21: "You can hardly repeat that.";
  5552.               22: "You can't begin with a comma.";
  5553.               23: "You seem to want to talk to someone, but I can't see whom.";
  5554.               24: "You can't talk to ", (the) x1, ".";
  5555.               25: "To talk to someone, try ~someone, hello~ or some such.";
  5556.               26: "(first taking ", (the) not_holding, ")";
  5557.               27: "I didn't understand that sentence.";
  5558.               28: print "I only understood you as far as wanting to ";
  5559.               29: "I didn't understand that number.";
  5560.               30: "You can't see any such thing.";
  5561.               31: "You seem to have said too little!";
  5562.               32: "You aren't holding that!";
  5563.               33: "You can't use multiple objects with that verb.";
  5564.               34: "You can only use multiple objects once on a line.";
  5565.               35: "I'm not sure what ~", (address) pronoun_word,
  5566.                   "~ refers to.";
  5567.               36: "You excepted something not included anyway!";
  5568.               37: "You can only do that to something animate.";
  5569.               38: #ifdef DIALECT_US;
  5570.                   "That's not a verb I recognize.";
  5571.                   #ifnot;
  5572.                   "That's not a verb I recognise.";
  5573.                   #endif;
  5574.               39: "That's not something you need to refer to
  5575.                    in the course of this game.";
  5576.               40: "You can't see ~", (address) pronoun_word,
  5577.                   "~ (", (the) pronoun_obj, ") at the moment.";
  5578.               41: "I didn't understand the way that finished.";
  5579.               42: if (x1==0) print "None";
  5580.                   else print "Only ", (number) x1;
  5581.                   print " of those ";
  5582.                   if (x1==1) print "is"; else print "are";
  5583.                   " available.";
  5584.               43: "Nothing to do!";
  5585.               44: "There are none at all available!";
  5586.               45: print "Who do you mean, ";
  5587.               46: print "Which do you mean, ";
  5588.               47: "Sorry, you can only have one item here. Which exactly?";
  5589.               48: print "Whom do you want";
  5590.                   if (actor~=player) print " ", (the) actor; print " to ";
  5591.                   PrintCommand(); print "?^";
  5592.               49: print "What do you want";
  5593.                   if (actor~=player) print " ", (the) actor; print " to ";
  5594.                   PrintCommand(); print "?^";
  5595.               50: print "Your score has just gone ";
  5596.                   if (x1 > 0) print "up"; else { x1 = -x1; print "down"; }
  5597.                   print " by ", (number) x1, " point";
  5598.                   if (x1 > 1) print "s";
  5599.               51: "(Since something dramatic has happened,
  5600.                    your list of commands has been cut short.)";
  5601.               52: "^Type a number from 1 to ", x1,
  5602.                   ", 0 to redisplay or press ENTER.";
  5603.               53: "^[Please press SPACE.]";
  5604.            }
  5605.   ListMiscellany:
  5606.            switch(n)
  5607.            {   1: print " (providing light)";
  5608.                2: print " (which ", (isorare) x1, " closed)";
  5609.                3: print " (closed and providing light)";
  5610.                4: print " (which ", (isorare) x1, " empty)";
  5611.                5: print " (empty and providing light)";
  5612.                6: print " (which ", (isorare) x1, " closed and empty)";
  5613.                7: print " (closed, empty and providing light)";
  5614.                8: print " (providing light and being worn";
  5615.                9: print " (providing light";
  5616.               10: print " (being worn";
  5617.               11: print " (which ", (isorare) x1, " ";
  5618.               12: print "open";
  5619.               13: print "open but empty";
  5620.               14: print "closed";
  5621.               15: print "closed and locked";
  5622.               16: print " and empty";
  5623.               17: print " (which ", (isorare) x1, " empty)";
  5624.               18: print " containing ";
  5625.               19: print " (on ";
  5626.               20: print ", on top of ";
  5627.               21: print " (in ";
  5628.               22: print ", inside ";
  5629.            }
  5630.   Pronouns: switch(n)
  5631.            {   1: print "At the moment, ";
  5632.                2: print "means ";
  5633.                3: print "is unset";
  5634.                4: "no pronouns are known to the game.";
  5635.            }
  5636.   Order:          print (The) x1;
  5637.                   if (x1 has pluralname) print " have"; else print " has";
  5638.                   " better things to do.";
  5639.   Quit:    switch(n)
  5640.            {   1: print "Please answer yes or no.";
  5641.                2: print "Are you sure you want to quit? ";
  5642.            }
  5643.   Restart: switch(n)
  5644.            {   1: print "Are you sure you want to restart? ";
  5645.                2: "Failed.";
  5646.            }
  5647.   Restore: switch(n)
  5648.            {   1: "Restore failed.";
  5649.                2: "Ok.";
  5650.            }
  5651.   Save:    switch(n)
  5652.            {   1: "Save failed.";
  5653.                2: "Ok.";
  5654.            }
  5655.   Verify:  switch(n)
  5656.            {   1: "The game file has verified as intact.";
  5657.                2: "The game file did not verify as intact,
  5658.                    and may be corrupt.";
  5659.            }
  5660.   ScriptOn: switch(n)
  5661.            {   1: "Transcripting is already on.";
  5662.                2: "Start of a transcript of";
  5663.                3: "Attempt to begin transcript failed.";
  5664.            }
  5665.   ScriptOff: switch(n)
  5666.            {   1: "Transcripting is already off.";
  5667.                2: "^End of transcript.";
  5668.                3: "Attempt to end transcript failed.";
  5669.            }
  5670.   NotifyOn:       "Score notification on.";
  5671.   NotifyOff:      "Score notification off.";
  5672.   Places:         print "You have visited: ";
  5673.   Objects: switch(n)
  5674.            {   1: "Objects you have handled:^";
  5675.                2: "None.";
  5676.                3: print "   (worn)";
  5677.                4: print "   (held)";
  5678.                5: print "   (given away)";
  5679.                6: print "   (in ", (name) x1, ")";
  5680.                7: print "   (in ", (the) x1, ")";
  5681.                8: print "   (inside ", (the) x1, ")";
  5682.                9: print "   (on ", (the) x1, ")";
  5683.               10: print "   (lost)";
  5684.            }
  5685.   Score:          if (deadflag) print "In that game you scored ";
  5686.                   else print "You have so far scored ";
  5687.                   print score, " out of a possible ", MAX_SCORE,
  5688.                   ", in ", turns, " turn";
  5689.                   if (turns~=1) print "s"; return;
  5690.   FullScore: switch(n)
  5691.            {   1: if (deadflag) print "The score was ";
  5692.                   else          print "The score is ";
  5693.                   "made up as follows:^";
  5694.                2: "finding sundry items";
  5695.                3: "visiting various places";
  5696.                4: print "total (out of ", MAX_SCORE; ")";
  5697.            }
  5698.   Inv:     switch(n)
  5699.            {   1: "You are carrying nothing.";
  5700.                2: print "You are carrying";
  5701.            }
  5702.   Take:    switch(n)
  5703.            {   1: "Taken.";
  5704.                2: "You are always self-possessed.";
  5705.                3: "I don't suppose ", (the) x1, " would care for that.";
  5706.                4: print "You'd have to get ";
  5707.                   if (x1 has supporter) print "off "; else print "out of ";
  5708.                   print_ret (the) x1, " first.";
  5709.                5: "You already have ", (thatorthose) x1, ".";
  5710.                6: if (noun has pluralname) print "Those seem ";
  5711.                   else print "That seems ";
  5712.                   "to belong to ", (the) x1, ".";
  5713.                7: if (noun has pluralname) print "Those seem ";
  5714.                   else print "That seems ";
  5715.                   "to be a part of ", (the) x1, ".";
  5716.                8: print_ret (Cthatorthose) x1, " ", (isorare) x1,
  5717.                   "n't available.";
  5718.                9: print_ret (The) x1, " ", (isorare) x1, "n't open.";
  5719.               10: if (x1 has pluralname) print "They're ";
  5720.                   else print "That's ";
  5721.                   "hardly portable.";
  5722.               11: if (x1 has pluralname) print "They're ";
  5723.                   else print "That's ";
  5724.                   "fixed in place.";
  5725.               12: "You're carrying too many things already.";
  5726.               13: "(putting ", (the) x1, " into ", (the) SACK_OBJECT,
  5727.                   " to make room)";
  5728.            }
  5729.   Drop:    switch(n)
  5730.            {   1: if (x1 has pluralname) print (The) x1, " are ";
  5731.                   else print (The) x1, " is ";
  5732.                   "already here.";
  5733.                2: "You haven't got ", (thatorthose) x1, ".";
  5734.                3: "(first taking ", (the) x1, " off)";
  5735.                4: "Dropped.";
  5736.            }
  5737.   Remove:  switch(n)
  5738.            {   1: if (x1 has pluralname) print "They are"; else print "It is";
  5739.                   " unfortunately closed.";
  5740.                2: if (x1 has pluralname)
  5741.                       print "But they aren't";
  5742.                   else print "But it isn't";
  5743.                   " there now.";
  5744.                3: "Removed.";
  5745.            }
  5746.   PutOn:   switch(n)
  5747.            {   1: "You need to be holding ", (the) x1,
  5748.                   " before you can put ", (itorthem) x1,
  5749.                   " on top of something else.";
  5750.                2: "You can't put something on top of itself.";
  5751.                3: "Putting things on ", (the) x1, " would achieve nothing.";
  5752.                4: "You lack the dexterity.";
  5753.                5: "(first taking ", (itorthem) x1, " off)^";
  5754.                6: "There is no more room on ", (the) x1, ".";
  5755.                7: "Done.";
  5756.                8: "You put ", (the) x1, " on ", (the) second, ".";
  5757.            }
  5758.   Insert:  switch(n)
  5759.            {   1: "You need to be holding ", (the) x1,
  5760.                   " before you can put ", (itorthem) x1,
  5761.                   " into something else.";
  5762.                2: print_ret (Cthatorthose) x1, " can't contain things.";
  5763.                3: print_ret (The) x1, " ", (isorare) x1, " closed.";
  5764.                4: "You'll need to take ", (itorthem) x1, " off first.";
  5765.                5: "You can't put something inside itself.";
  5766.                6: "(first taking ", (itorthem) x1, " off)^";
  5767.                7: "There is no more room in ", (the) x1, ".";
  5768.                8: "Done.";
  5769.                9: "You put ", (the) x1, " into ", (the) second, ".";
  5770.            }
  5771.   EmptyT:  switch(n)
  5772.            {   1: print_ret (The) x1, " can't contain things.";
  5773.                2: print_ret (The) x1, " ", (isorare) x1, " closed.";
  5774.                3: print_ret (The) x1, " ", (isorare) x1, " empty already.";
  5775.                4: "That would scarcely empty anything.";
  5776.            }
  5777.   Give:    switch(n)
  5778.            {   1: "You aren't holding ", (the) x1, ".";
  5779.                2: "You juggle ", (the) x1,
  5780.                   " for a while, but don't achieve much.";
  5781.                3: print (The) x1;
  5782.                   if (x1 has pluralname) print " don't";
  5783.                   else print " doesn't";
  5784.                   " seem interested.";
  5785.            }
  5786.   Show:    switch(n)
  5787.            {   1: "You aren't holding ", (the) x1, ".";
  5788.                2: print_ret (The) x1, " ", (isorare) x1, " unimpressed.";
  5789.            }
  5790.   Enter:   switch(n)
  5791.            {   1: print "But you're already ";
  5792.                   if (x1 has supporter) print "on "; else print "in ";
  5793.                   print_ret (the) x1, ".";
  5794.                2: if (x1 has pluralname) print "They're"; else print "That's";
  5795.                   " not something you can enter.";
  5796.                3: "You can't get into the closed ", (name) x1, ".";
  5797.                4: "You can only get into something freestanding.";
  5798.                5: print "You get ";
  5799.                   if (x1 has supporter) print "onto "; else print "into ";
  5800.                   print_ret (the) x1, ".";
  5801.                6: print "(getting ";
  5802.                   if (x1 has supporter) print "off "; else print "out of ";
  5803.                   print (the) x1; ")";
  5804.                7: if (x1 has supporter) "(getting onto ", (the) x1, ")^";
  5805.                   if (x1 has container) "(getting into ", (the) x1, ")^";
  5806.                   "(entering ", (the) x1, ")^";
  5807.            }
  5808.   GetOff:         "But you aren't on ", (the) x1, " at the moment.";
  5809.   Exit:    switch(n)
  5810.            {   1: "But you aren't in anything at the moment.";
  5811.                2: "You can't get out of the closed ", (name) x1, ".";
  5812.                3: print "You get ";
  5813.                   if (x1 has supporter) print "off "; else print "out of ";
  5814.                   print_ret (the) x1, ".";
  5815.            }
  5816.   VagueGo:       "You'll have to say which compass direction to go in.";
  5817.   Go:      switch(n)
  5818.            {   1: print "You'll have to get ";
  5819.                   if (x1 has supporter) print "off "; else print "out of ";
  5820.                   print_ret (the) x1, " first.";
  5821.                2: "You can't go that way.";
  5822.                3: "You are unable to climb ", (the) x1, ".";
  5823.                4: "You are unable to descend by ", (the) x1, ".";
  5824.                5: "You can't, since ", (the) x1, " ", (isorare) x1,
  5825.                   " in the way.";
  5826.                6: print "You can't, since ", (the) x1;
  5827.                   if (x1 has pluralname) " lead nowhere.";
  5828.                   " leads nowhere.";
  5829.            }
  5830.   LMode1:         " is now in its normal ~brief~ printing mode, which gives
  5831.                    long descriptions of places never before visited and short
  5832.                    descriptions otherwise.";
  5833.   LMode2:         " is now in its ~verbose~ mode, which always gives long
  5834.                    descriptions of locations
  5835.                    (even if you've been there before).";
  5836.   LMode3:         " is now in its ~superbrief~ mode, which always gives short
  5837.                    descriptions of locations
  5838.                    (even if you haven't been there before).";
  5839.   Look:    switch(n)
  5840.            {   1: print " (on ", (the) x1, ")";
  5841.                2: print " (in ", (the) x1, ")";
  5842.                3: print " (as "; @print_obj x1; print ")";
  5843.                4: print "^On ", (the) x1;
  5844.                   WriteListFrom(child(x1),
  5845.                       ENGLISH_BIT + RECURSE_BIT + PARTINV_BIT
  5846.                       + TERSE_BIT + ISARE_BIT + CONCEAL_BIT);
  5847.                   ".";
  5848.          default: if (x1~=location)
  5849.                   {   if (x1 has supporter) print "^On "; else print "^In ";
  5850.                       print (the) x1, " you";
  5851.                   }
  5852.                   else print "^You";
  5853.                   print " can ";
  5854.                   if (n==5) print "also "; print "see ";
  5855.                   WriteListFrom(child(x1),
  5856.                       ENGLISH_BIT + WORKFLAG_BIT + RECURSE_BIT
  5857.                       + PARTINV_BIT + TERSE_BIT + CONCEAL_BIT);
  5858.                   if (x1~=location) ".";
  5859.                   " here.";
  5860.            }
  5861.   Examine: switch(n)
  5862.            {   1: "Darkness, noun.  An absence of light to see by.";
  5863.                2: "You see nothing special about ", (the) x1, ".";
  5864.                3: print (The) x1, " ", (isorare) x1, " currently switched ";
  5865.                   if (x1 has on) "on."; else "off.";
  5866.            }
  5867.   LookUnder: switch(n)
  5868.            {   1: "But it's dark.";
  5869.                2: "You find nothing of interest.";
  5870.            }
  5871.   Search:  switch(n)
  5872.            {   1: "But it's dark.";
  5873.                2: "There is nothing on ", (the) x1, ".";
  5874.                3: print "On ", (the) x1;
  5875.                   WriteListFrom(child(x1),
  5876.                       TERSE_BIT + ENGLISH_BIT + ISARE_BIT + CONCEAL_BIT);
  5877.                   ".";
  5878.                4: "You find nothing of interest.";
  5879.                5: "You can't see inside, since ", (the) x1, " ",
  5880.                   (isorare) x1, " closed.";
  5881.                6: print_ret (The) x1, " ", (isorare) x1, " empty.";
  5882.                7: print "In ", (the) x1;
  5883.                   WriteListFrom(child(x1),
  5884.                       TERSE_BIT + ENGLISH_BIT + ISARE_BIT + CONCEAL_BIT);
  5885.                   ".";
  5886.            }
  5887.   Unlock:  switch(n)
  5888.            {   1: if (x1 has pluralname) print "They don't ";
  5889.                   else print "That doesn't ";
  5890.                   "seem to be something you can unlock.";
  5891.                2: print_ret (ctheyreorthats) x1,
  5892.                   " unlocked at the moment.";
  5893.                3: if (x1 has pluralname) print "Those don't ";
  5894.                   else print "That doesn't ";
  5895.                   "seem to fit the lock.";
  5896.                4: "You unlock ", (the) x1, ".";
  5897.            }
  5898.   Lock:    switch(n)
  5899.            {   1: if (x1 has pluralname) print "They don't ";
  5900.                   else print "That doesn't ";
  5901.                   "seem to be something you can lock.";
  5902.                2: print_ret (ctheyreorthats) x1, " locked at the moment.";
  5903.                3: "First you'll have to close ", (the) x1, ".";
  5904.                4: if (x1 has pluralname) print "Those don't ";
  5905.                   else print "That doesn't ";
  5906.                   "seem to fit the lock.";
  5907.                5: "You lock ", (the) x1, ".";
  5908.            }
  5909.   SwitchOn: switch(n)
  5910.            {   1: print_ret (ctheyreorthats) x1,
  5911.                   " not something you can switch.";
  5912.                2: print_ret (ctheyreorthats) x1,
  5913.                   " already on.";
  5914.                3: "You switch ", (the) x1, " on.";
  5915.            }
  5916.   SwitchOff: switch(n)
  5917.            {   1: print_ret (ctheyreorthats) x1,
  5918.                   " not something you can switch.";
  5919.                2: print_ret (ctheyreorthats) x1,
  5920.                   " already off.";
  5921.                3: "You switch ", (the) x1, " off.";
  5922.            }
  5923.   Open:    switch(n)
  5924.            {   1: print_ret (ctheyreorthats) x1,
  5925.                   " not something you can open.";
  5926.                2: if (x1 has pluralname) print "They seem ";
  5927.                   else print "It seems ";
  5928.                   "to be locked.";
  5929.                3: print_ret (ctheyreorthats) x1,
  5930.                   " already open.";
  5931.                4: print "You open ", (the) x1, ", revealing ";
  5932.                   if (WriteListFrom(child(x1),
  5933.                       ENGLISH_BIT + TERSE_BIT + CONCEAL_BIT)==0) "nothing.";
  5934.                   ".";
  5935.                5: "You open ", (the) x1, ".";
  5936.            }
  5937.   Close:   switch(n)
  5938.            {   1: print_ret (ctheyreorthats) x1,
  5939.                   " not something you can close.";
  5940.                2: print_ret (ctheyreorthats) x1,
  5941.                   " already closed.";
  5942.                3: "You close ", (the) x1, ".";
  5943.            }
  5944.   Disrobe: switch(n)
  5945.            {   1: "You're not wearing ", (thatorthose) x1, ".";
  5946.                2: "You take off ", (the) x1, ".";
  5947.            }
  5948.   Wear:    switch(n)
  5949.            {   1: "You can't wear ", (thatorthose) x1, "!";
  5950.                2: "You're not holding ", (thatorthose) x1, "!";
  5951.                3: "You're already wearing ", (thatorthose) x1, "!";
  5952.                4: "You put on ", (the) x1, ".";
  5953.            }
  5954.   Eat:     switch(n)
  5955.            {   1: print_ret (ctheyreorthats) x1,
  5956.                   " plainly inedible.";
  5957.                2: "You eat ", (the) x1, ". Not bad.";
  5958.            }
  5959.   Yes, No:        "That was a rhetorical question.";
  5960.   Burn:           "This dangerous act would achieve little.";
  5961.   Pray:           "Nothing practical results from your prayer.";
  5962.   Wake:           "The dreadful truth is, this is not a dream.";
  5963.   WakeOther:      "That seems unnecessary.";
  5964.   Kiss:           "Keep your mind on the game.";
  5965.   Think:          "What a good idea.";
  5966.   Smell:          "You smell nothing unexpected.";
  5967.   Listen:         "You hear nothing unexpected.";
  5968.   Taste:          "You taste nothing unexpected.";
  5969.   Touch:   switch(n)
  5970.            {   1: "Keep your hands to yourself!";
  5971.                2: "You feel nothing unexpected.";
  5972.                3: "If you think that'll help.";
  5973.            }
  5974.   Dig:            "Digging would achieve nothing here.";
  5975.   Cut:            "Cutting ", (thatorthose) x1, " up would achieve little.";
  5976.   Jump:           "You jump on the spot, fruitlessly.";
  5977.   JumpOver, Tie:  "You would achieve nothing by this.";
  5978.   Drink:          "There's nothing suitable to drink here.";
  5979.   Fill:           "But there's no water here to carry.";
  5980.   Sorry:          #ifdef DIALECT_US;
  5981.                   "Oh, don't apologize.";
  5982.                   #ifnot;
  5983.                   "Oh, don't apologise.";
  5984.                   #endif;
  5985.   Strong:         "Real adventurers do not use such language.";
  5986.   Mild:           "Quite.";
  5987.   Attack:         "Violence isn't the answer to this one.";
  5988.   Swim:           "There's not enough water to swim in.";
  5989.   Swing:          "There's nothing sensible to swing here.";
  5990.   Blow:           "You can't usefully blow ", (thatorthose) x1, ".";
  5991.   Rub:            "You achieve nothing by this.";
  5992.   Set:            "No, you can't set ", (thatorthose) x1, ".";
  5993.   SetTo:          "No, you can't set ", (thatorthose) x1, " to anything.";
  5994.   WaveHands:      "You wave, feeling foolish.";
  5995.   Wave:    switch(n)
  5996.            {   1: "But you aren't holding ", (thatorthose) x1, ".";
  5997.                2: "You look ridiculous waving ", (the) x1, ".";
  5998.            }
  5999.   Pull, Push, Turn:
  6000.            switch(n)
  6001.            {   1: if (x1 has pluralname) print "Those are ";
  6002.                   else print "It is ";
  6003.                   "fixed in place.";
  6004.                2: "You are unable to.";
  6005.                3: "Nothing obvious happens.";
  6006.                4: "That would be less than courteous.";
  6007.            }
  6008.   PushDir: switch(n)
  6009.            {   1: "Is that the best you can think of?";
  6010.                2: "That's not a direction.";
  6011.                3: "Not that way you can't.";
  6012.            }
  6013.   Squeeze: switch(n)
  6014.            {   1: "Keep your hands to yourself.";
  6015.                2: "You achieve nothing by this.";
  6016.            }
  6017.   ThrowAt: switch(n)
  6018.            {   1: "Futile.";
  6019.                2: "You lack the nerve when it comes to the crucial moment.";
  6020.            }
  6021.   Tell:    switch(n)
  6022.            {   1: "You talk to yourself a while.";
  6023.                2: "This provokes no reaction.";
  6024.            }
  6025.   Answer, Ask:    "There is no reply.";
  6026.   Buy:            "Nothing is on sale.";
  6027.   Sing:           "Your singing is abominable.";
  6028.   Climb:          "I don't think much is to be achieved by that.";
  6029.   Wait:           "Time passes.";
  6030.   Sleep:          "You aren't feeling especially drowsy.";
  6031.   Consult:        "You discover nothing of interest in ", (the) x1, ".";
  6032. ! ---------------------------------------------------------------------------
  6033. ! ----------------------------------------------------------------------------
  6034. !  LINKLV:  Link declarations of library variables.
  6035. !  Supplied for use with Inform 6                         Serial number 990428
  6036. !                                                                  Release 6/9
  6037. !  (c) Graham Nelson 1993, 1994, 1995, 1996, 1997, 1998, 1999
  6038. !      but freely usable (see manuals)
  6039. ! ----------------------------------------------------------------------------
  6040. Import global location;
  6041. Import global sline1;
  6042. Import global sline2;
  6043. Import global top_object;
  6044. Import global standard_interpreter;
  6045. Import global undo_flag;
  6046. Import global transcript_mode;
  6047. IFDEF DEBUG;
  6048. Import global xcommsdir;
  6049. ENDIF;
  6050. Import global turns;
  6051. Import global the_time;
  6052. Import global time_rate;
  6053. Import global time_step;
  6054. Import global active_timers;
  6055. Import global score;
  6056. Import global last_score;
  6057. Import global notify_mode;
  6058. Import global places_score;
  6059. Import global things_score;
  6060. Import global player;
  6061. Import global deadflag;
  6062. Import global lightflag;
  6063. Import global real_location;
  6064. Import global visibility_ceiling;
  6065. Import global lookmode;
  6066. Import global print_player_flag;
  6067. Import global lastdesc;
  6068. Import global c_style;
  6069. Import global lt_value;
  6070. Import global listing_together;
  6071. Import global listing_size;
  6072. Import global wlf_indent;
  6073. Import global inventory_stage;
  6074. Import global inventory_style;
  6075. Import global pretty_flag;
  6076. Import global menu_nesting;
  6077. Import global menu_item;
  6078. Import global item_width;
  6079. Import global item_name;
  6080. Import global lm_n;
  6081. Import global lm_o;
  6082. IFDEF DEBUG;
  6083. Import global debug_flag;
  6084. Import global x_scope_count;
  6085. ENDIF;
  6086. Import global action;
  6087. Import global inp1;
  6088. Import global inp2;
  6089. Import global noun;
  6090. Import global second;
  6091. Import global keep_silent;
  6092. Import global reason_code;
  6093. Import global receive_action;
  6094. Import global parser_trace;
  6095. Import global parser_action;
  6096. Import global parser_one;
  6097. Import global parser_two;
  6098. Import global parser_inflection;
  6099. Import global actor;
  6100. Import global actors_location;
  6101. Import global meta;
  6102. Import global multiflag;
  6103. Import global toomany_flag;
  6104. Import global special_word;
  6105. Import global special_number;
  6106. Import global parsed_number;
  6107. Import global consult_from;
  6108. Import global consult_words;
  6109. Import global notheld_mode;
  6110. Import global onotheld_mode;
  6111. Import global not_holding;
  6112. Import global etype;
  6113. Import global best_etype;
  6114. Import global nextbest_etype;
  6115. Import global pcount;
  6116. Import global pcount2;
  6117. Import global parameters;
  6118. Import global nsns;
  6119. Import global special_number1;
  6120. Import global special_number2;
  6121. Import global params_wanted;
  6122. Import global inferfrom;
  6123. Import global inferword;
  6124. Import global dont_infer;
  6125. Import global action_to_be;
  6126. Import global action_reversed;
  6127. Import global advance_warning;
  6128. Import global found_ttype;
  6129. Import global found_tdata;
  6130. Import global token_filter;
  6131. Import global lookahead;
  6132. Import global multi_mode;
  6133. Import global multi_wanted;
  6134. Import global multi_had;
  6135. Import global multi_context;
  6136. Import global indef_mode;
  6137. Import global indef_type;
  6138. Import global indef_wanted;
  6139. Import global indef_guess_p;
  6140. Import global indef_owner;
  6141. Import global indef_cases;
  6142. Import global indef_possambig;
  6143. Import global indef_nspec_at;
  6144. Import global allow_plurals;
  6145. Import global take_all_rule;
  6146. Import global pronoun_word;
  6147. Import global pronoun_obj;
  6148. Import global scope_reason;
  6149. Import global scope_token;
  6150. Import global scope_error;
  6151. Import global scope_stage;
  6152. Import global ats_flag;
  6153. Import global ats_hls;
  6154. Import global placed_in_flag;
  6155. Import global number_matched;
  6156. Import global number_of_classes;
  6157. Import global match_length;
  6158. Import global match_from;
  6159. Import global wn;
  6160. Import global num_words;
  6161. Import global verb_word;
  6162. Import global verb_wordnum;
  6163. Import global usual_grammar_after;
  6164. Import global oops_from;
  6165. Import global saved_oops;
  6166. Import global held_back_mode;
  6167. Import global hb_wn;
  6168. Import global short_name_case;
  6169. IFDEF EnglishNaturalLanguage;
  6170. Import global itobj;
  6171. Import global himobj;
  6172. Import global herobj;
  6173. Import global old_itobj;
  6174. Import global old_himobj;
  6175. Import global old_herobj;
  6176. ENDIF;
  6177. ! ----------------------------------------------------------------------------
  6178. !  LINKLPA:  Link declarations of common properties and attributes.
  6179. !  Supplied for use with Inform 6                         Serial number 990428
  6180. !                                                                  Release 6/9
  6181. !  (c) Graham Nelson 1993, 1994, 1995, 1996, 1997, 1998, 1999
  6182. !      but freely usable (see manuals)
  6183. ! ----------------------------------------------------------------------------
  6184. System_file;
  6185. Attribute animate;
  6186. Ifdef USE_MODULES;
  6187.    Iffalse (animate==0);
  6188.    Message error "Please move your Attribute declarations after the
  6189.                   Include ~Parser~ line: otherwise it will be impossible
  6190.                   to USE_MODULES";
  6191.    Endif;
  6192. Endif;
  6193. Attribute absent;
  6194. Attribute clothing;
  6195. Attribute concealed;
  6196. Attribute container;
  6197. Attribute door;
  6198. Attribute edible;
  6199. Attribute enterable;
  6200. Attribute general;
  6201. Attribute light;
  6202. Attribute lockable;
  6203. Attribute locked;
  6204. Attribute moved;
  6205. Attribute on;
  6206. Attribute open;
  6207. Attribute openable;
  6208. Attribute proper;
  6209. Attribute scenery;
  6210. Attribute scored;
  6211. Attribute static;
  6212. Attribute supporter;
  6213. Attribute switchable;
  6214. Attribute talkable;
  6215. Attribute transparent;
  6216. Attribute visited;
  6217. Attribute workflag;
  6218. Attribute worn;
  6219. Attribute male;
  6220. Attribute female;
  6221. Attribute neuter;
  6222. Attribute pluralname;
  6223. Property additive before $ffff;
  6224. Ifdef USE_MODULES;
  6225.    Iffalse before==4;
  6226.    Message error "Please move your Property declarations after the
  6227.                   Include ~Parser~ line: otherwise it will be impossible
  6228.                   to USE_MODULES";
  6229.    Endif;
  6230. Endif;
  6231. Property additive after  $ffff;
  6232. Property additive life   $ffff;
  6233. Property n_to;  Property s_to;
  6234. Property e_to;  Property w_to;
  6235. Property ne_to; Property se_to;
  6236. Property nw_to; Property sw_to;
  6237. Property u_to;  Property d_to;
  6238. Property in_to; Property out_to;
  6239. Property door_to;
  6240. Property with_key;
  6241. Property door_dir;
  6242. Property invent;
  6243. Property plural;
  6244. Property add_to_scope;
  6245. Property list_together;
  6246. Property react_before;
  6247. Property react_after;
  6248. Property grammar;
  6249. Property additive orders;
  6250. Property initial;
  6251. Property when_open;
  6252. Property when_closed;
  6253. Property when_on;
  6254. Property when_off;
  6255. Property description;
  6256. Property additive describe $ffff;
  6257. Property article "a";
  6258. Property cant_go;
  6259. Property found_in;         !  For fiddly reasons this can't alias
  6260. Property time_left;
  6261. Property number;
  6262. Property additive time_out $ffff;
  6263. Property daemon;
  6264. Property additive each_turn $ffff;
  6265. Property capacity 100;
  6266. Property short_name 0;
  6267. Property short_name_indef 0;
  6268. Property parse_name 0;
  6269. Property articles;
  6270. Property inside_description;
  6271. ! ----------------------------------------------------------------------------
  6272. !  INFIX:  Support for the optional library extension "Infix".
  6273. !  Supplied for use with Inform 6                         Serial number 990428
  6274. !                                                                  Release 6/9
  6275. !  (c) Graham Nelson 1999
  6276. !      but freely usable (see manuals)
  6277. ! ----------------------------------------------------------------------------
  6278. System_file;
  6279. Ifdef DEBUG;
  6280. Constant INFIXTT_NUMBER 0;
  6281. Constant INFIXTT_ARRAY 1;
  6282. Constant INFIXTT_ROUTINE 2;
  6283. Constant INFIXTT_CONSTANT 3;
  6284. Constant INFIXTT_DWORD 4;
  6285. Constant INFIXTT_ACTION 5;
  6286. Constant INFIXTT_ATTRIBUTE 6;
  6287. Constant INFIXTT_PROPERTY 7;
  6288. Constant INFIXTT_GLOBAL 8;
  6289. Constant INFIXTT_NAMEDOBJECT 9;
  6290. Constant INFIXTT_SYSFUN 10;
  6291. Constant INFIXTT_STATICSTRING 11;
  6292. Constant INFIXTT_LOGICAL 12;
  6293. Global infix_term_type;
  6294. Global infix_data1;
  6295. Global infix_data2;
  6296. Global infix_lvalue;
  6297. Global infix_parsed_lvalue;
  6298. Array infix_tolowercase -> 256;
  6299. Array infix_text -> 128;
  6300. [ InfixPrintAttribute x; print (string) #attribute_names_array-->x; ];
  6301. [ InfixPrintProperty x; print (property) x; ];
  6302. [ InfixPrintGlobal x; print (string) #global_names_array-->x; ];
  6303. [ InfixPrintAction x;
  6304.   print (string) #action_names_array-->(x-#lowest_action_number);
  6305. [ InfixPrintRoutine x;
  6306.   print (string) #routine_names_array-->(x-#lowest_routine_number);
  6307. [ InfixPrintConstant x;
  6308.   print (string) #constant_names_array-->(x-#lowest_constant_number);
  6309. [ InfixPrintArray x;
  6310.   print (string) #array_names_array-->(x-#lowest_array_number);
  6311. [ InfixPrintFakeAction x;
  6312.   print (string) #fake_action_names_array-->(x-#lowest_fake_action_number);
  6313. [ InfixPrintPA x n;
  6314.   for (n=#lowest_routine_number:n<=#highest_routine_number:n++)
  6315.   {   if (x == Symb__Tab(INFIXTT_ROUTINE, n))
  6316.       {   print (InfixPrintRoutine) n; return;
  6317.       }
  6318.   print "Routine(", x, ")";
  6319. [ InfixMatchPrule PrintingRule range1 range2 wa wl t i i2 it2 itlc j k plus;
  6320.   itlc = infix_tolowercase;
  6321.   if (itlc->255 == 0)
  6322.   {   for (j=0:j<256:j++) itlc->j = j;
  6323.       itlc->'A' = 'a';      itlc->'B' = 'b';
  6324.       itlc->'C' = 'c';      itlc->'D' = 'd';
  6325.       itlc->'E' = 'e';      itlc->'F' = 'f';
  6326.       itlc->'G' = 'g';      itlc->'H' = 'h';
  6327.       itlc->'I' = 'i';      itlc->'J' = 'j';
  6328.       itlc->'K' = 'k';      itlc->'L' = 'l';
  6329.       itlc->'M' = 'm';      itlc->'N' = 'n';
  6330.       itlc->'O' = 'o';      itlc->'P' = 'p';
  6331.       itlc->'Q' = 'q';      itlc->'R' = 'r';
  6332.       itlc->'S' = 's';      itlc->'T' = 't';
  6333.       itlc->'U' = 'u';      itlc->'V' = 'v';
  6334.       itlc->'W' = 'w';      itlc->'X' = 'x';
  6335.       itlc->'Y' = 'y';      itlc->'Z' = 'z';
  6336.   switch(PrintingRule)
  6337.   {   InfixPrintAttribute:
  6338.           if (wa->0 == '~') { wl--; wa++; plus = 100; } ! A tilde
  6339.           t = #attribute_names_array;
  6340.       InfixPrintProperty: t = #property_names_array;
  6341.       InfixPrintAction: t = #action_names_array;
  6342.       InfixPrintFakeAction: t = #fake_action_names_array;
  6343.       InfixPrintGlobal: t = #global_names_array;
  6344.       InfixPrintRoutine: t = #routine_names_array;
  6345.       InfixPrintAction: t = #constant_names_array;
  6346.       InfixPrintArray: t = #array_names_array;
  6347.   i2 = range2-range1; it2 = infix_text+2;
  6348.   for (i=0: i<=i2: i++)
  6349.   {   infix_text-->0 = 62; @output_stream 3 infix_text;
  6350.       if (t) print (string) t-->i; else PrintingRule(i+range1);
  6351.       @output_stream -3;
  6352.       k = infix_text-->0;
  6353.       if (k ~= wl) jump XL;
  6354.       if (itlc->(it2->0) ~= wa->0) jump XL;
  6355.       for (j=1:j<k:j++)
  6356.           if (itlc->(it2->j) ~= wa->j) jump XL;
  6357.       parsed_number = i + range1 + plus; rtrue;
  6358.      .XL;
  6359.   rfalse;
  6360. [ InfixActionToken;
  6361.   if (InfixMatchPrule(InfixPrintAction,
  6362.       #lowest_action_number, #highest_action_number,
  6363.       WordAddress(wn), WordLength(wn)))
  6364.   {   wn++; infix_lvalue = parsed_number; return 0;
  6365.   if (InfixMatchPrule(InfixPrintFakeAction,
  6366.       #lowest_fake_action_number, #highest_fake_action_number,
  6367.       WordAddress(wn), WordLength(wn)))
  6368.   {   wn++; infix_lvalue = parsed_number; return 0;
  6369.   return -1;
  6370. [ InfixRvalueTerm n w i initial_wn wa wl sign base digit dcount;
  6371.   initial_wn = wn;
  6372.   infix_parsed_lvalue = -1;
  6373.   infix_term_type = INFIXTT_NUMBER;
  6374.   w = NextWordStopped();
  6375.   if (w == -1) return -1;
  6376.   wa = WordAddress(wn-1);
  6377.   wl = WordLength(wn-1);
  6378.   if (wa->0 == '-' or '$' or '0' or '1' or '2' or '3' or '4'
  6379.                or '5' or '6' or '7' or '8' or '9')
  6380.   {   ! Parse decimal, hex or binary number
  6381.       sign = 1; base = 10; dcount = 0;
  6382.       if (wa->0 == '-') { sign = -1; wl--; wa++; }
  6383.       else
  6384.       {   if (wa->0 == '$') { base = 16; wl--; wa++; }
  6385.           if (wa->0 == '$') { base = 2; wl--; wa++; }
  6386.       }
  6387.       if (wl == 0) return -1;
  6388.       n = 0;
  6389.       while (wl > 0)
  6390.       {   if (wa->0 >= 'a') digit = wa->0 - 'a' + 10;
  6391.           else digit = wa->0 - '0';
  6392.           dcount++;
  6393.           switch(base)
  6394.           {   2: if (dcount == 17) return -1;
  6395.              10: if (dcount == 6) return -1;
  6396.                  if (dcount == 5)
  6397.                  {   if (n > 3276) return -1;
  6398.                      if (n == 3276)
  6399.                      {   if (sign == 1 && digit > 7) return -1;
  6400.                          if (sign == -1 && digit > 8) return -1;
  6401.                      }
  6402.                  }
  6403.              16: if (dcount == 5) return -1;
  6404.           }
  6405.           if (digit >= 0 && digit < base) n = base*n + digit;
  6406.           else return -1;
  6407.           wl--; wa++;
  6408.       }
  6409.       parsed_number = n*sign; return 1;
  6410. ! Parse character constant 'a'
  6411.   if (wl == 3 && wa->0==''' && wa->2==''')
  6412.   {   parsed_number = wa->1; return 1;
  6413. ! ##Action, 'dword'
  6414.   switch(w)
  6415.   {   '##': infix_term_type = INFIXTT_ACTION;
  6416.             w = NextWordStopped(); if (w == -1) return -1;
  6417.             wn--;
  6418.             if (InfixActionToken() == 0) return 1;
  6419.             return -1;
  6420.       '^^': infix_term_type = INFIXTT_DWORD;
  6421.             w = NextWordStopped(); if (w == -1) return -1;
  6422.             parsed_number = w; return 1;
  6423. ! Test for attribute, property, class name, variable name, array name, routine
  6424. ! name, constant name
  6425.   wn--;
  6426.   if ((wa->0 >= 'a' && wa->0 <= 'z')
  6427.       || (wa->0 >= 'A' && wa->0 <= 'Z')
  6428.       || wa->0 == '_')
  6429.                
  6430.   infix_term_type = INFIXTT_ATTRIBUTE;
  6431.   if (InfixMatchPrule(InfixPrintAttribute,
  6432.       #lowest_attribute_number, #highest_attribute_number, wa, wl))
  6433.   {   wn++; return 1; }
  6434.   infix_term_type = INFIXTT_PROPERTY;
  6435.   if (InfixMatchPrule(InfixPrintProperty,
  6436.       #lowest_property_number, #highest_property_number, wa, wl))
  6437.   {   wn++; return 1; }
  6438.   infix_term_type = INFIXTT_GLOBAL;
  6439.   if (InfixMatchPrule(InfixPrintGlobal,
  6440.       #lowest_global_number, #highest_global_number, wa, wl))
  6441.   {   infix_parsed_lvalue = parsed_number-16;
  6442.       parsed_number = #globals_array-->infix_parsed_lvalue;
  6443.       wn++; return 1;
  6444.   infix_term_type = INFIXTT_ARRAY;
  6445.   if (InfixMatchPrule(InfixPrintArray,
  6446.       #lowest_array_number, #highest_array_number, wa, wl))
  6447.   {   infix_parsed_lvalue = parsed_number;
  6448.       parsed_number = Symb__Tab(INFIXTT_ARRAY,parsed_number);
  6449.       infix_data1 = temp__global3;
  6450.       infix_data2 = temp__global2;
  6451.       wn++; return 1;
  6452.   infix_term_type = INFIXTT_ROUTINE;
  6453.   if (InfixMatchPrule(InfixPrintRoutine,
  6454.       #lowest_routine_number, #highest_routine_number, wa, wl))
  6455.   {   infix_parsed_lvalue = parsed_number;
  6456.       parsed_number = Symb__Tab(INFIXTT_ROUTINE,parsed_number);
  6457.       infix_data1 = temp__global3;
  6458.       infix_data2 = temp__global2;
  6459.       wn++; return 1;
  6460.   infix_term_type = INFIXTT_CONSTANT;
  6461.   if (InfixMatchPrule(InfixPrintConstant,
  6462.       #lowest_constant_number, #highest_constant_number, wa, wl))
  6463.   {   infix_parsed_lvalue = parsed_number;
  6464.       parsed_number = Symb__Tab(INFIXTT_CONSTANT,parsed_number);
  6465.       infix_data1 = temp__global3;
  6466.       infix_data2 = temp__global2;
  6467.       wn++; return 1;
  6468.   switch(w)
  6469.   {   'parent', 'child', 'children',
  6470.       'random', 'metaclass', 'sibling': parsed_number = w;
  6471.           infix_parsed_lvalue = INFIXTT_SYSFUN;
  6472.           wn++; return 1;
  6473.   infix_term_type = INFIXTT_NAMEDOBJECT;
  6474.   wn = initial_wn; i = ParseToken(SCOPE_TT, InfixBigScope);
  6475.   if (i == GPR_REPARSE) return i;
  6476.   if (i > GPR_MULTIPLE)
  6477.   {   print "(", (name) i, " (", i, "))^";
  6478.       parsed_number = i; return 1;
  6479.   return -1;
  6480. [ InfixBigScope x;
  6481.   if (scope_stage == 1) return false;  ! No multiples here
  6482.   if (scope_stage == 2)
  6483.   {   objectloop (x ofclass Object) PlaceInScope(x);
  6484.       return true; ! That's the whole scope
  6485.   print "; I'm unable to make any sense of that term.^";
  6486. [ InfixCheckLineSpaced wa wl i force altered;
  6487.   for (i = 1 : i <= parse->1 : i++)
  6488.   {   wa = WordAddress(i);
  6489.       wl = WordLength(i);
  6490.       if (wl > 3 && wa->0==''' && wa->(wl-1)==''')
  6491.       {   wa->(wl-1) = ' ';
  6492.           if (wa->(wl-2) == '/' && wa->(wl-3) == '/')
  6493.           {   wa->(wl-2) = ' ';
  6494.               wa->(wl-3) = ' ';
  6495.           }
  6496.           LTI_Insert(wa-buffer, ''');
  6497.           LTI_Insert(wa-buffer + 2, ' ');
  6498.           altered = true; break;
  6499.       }
  6500.   for (i = 2 : i < buffer->1 + 2: i++)
  6501.   {   force = false;
  6502.       if (buffer->i=='-' && buffer->(i+1)=='-' && buffer->(i+2)=='>')
  6503.           force = true;
  6504.       if (force)
  6505.       {   if (i>2 && buffer->(i-1)~=' ')
  6506.           {   LTI_Insert(i++, ' '); altered = true;
  6507.           }
  6508.           if (buffer->(i+3)~=' ')
  6509.           {   LTI_Insert(i+3, ' '); i++; altered = true;
  6510.           }
  6511.           i = i + 2; continue;
  6512.       }
  6513.       if (buffer->i==':' && buffer->(i+1)==':') force = true;
  6514.       if (buffer->i=='-' && buffer->(i+1)=='>') force = true;
  6515.       if (buffer->i=='.' && buffer->(i+1)=='&')
  6516.       {   buffer->i = ']'; force = true;
  6517.       }
  6518.       if (buffer->i=='.' && buffer->(i+1)=='#')
  6519.       {   buffer->i = ']'; force = true;
  6520.       }
  6521.       if (buffer->i==']' && buffer->(i+1)=='&') force = true;
  6522.       if (buffer->i==']' && buffer->(i+1)=='#') force = true;
  6523.       if (buffer->i=='+' && buffer->(i+1)=='+') force = true;
  6524.       if (buffer->i=='-' && buffer->(i+1)=='-') force = true;
  6525.       if (buffer->i=='&' && buffer->(i+1)=='&') force = true;
  6526.       if (buffer->i=='|' && buffer->(i+1)=='|') force = true;
  6527.       if (buffer->i=='~' && buffer->(i+1)=='~') force = true;
  6528.       if (buffer->i=='=' && buffer->(i+1)=='=') force = true;
  6529.       if (buffer->i=='~' && buffer->(i+1)=='=') force = true;
  6530.       if (buffer->i=='>' && buffer->(i+1)=='=') force = true;
  6531.       if (buffer->i=='<' && buffer->(i+1)=='=') force = true;
  6532.       if (buffer->i=='#' && buffer->(i+1)=='#') force = true;
  6533.       if (force)
  6534.       {   if (i>2 && buffer->(i-1)~=' ')
  6535.           {   LTI_Insert(i++, ' '); altered = true;
  6536.           }
  6537.           if (buffer->(i+2)~=' ')
  6538.           {   LTI_Insert(i+2, ' '); i++; altered = true;
  6539.           }
  6540.           i = i + 1; continue;
  6541.       }
  6542.       if (buffer->i=='+') force = true;
  6543.       if (buffer->i=='-') force = true;
  6544.       if (buffer->i=='*') force = true;
  6545.       if (buffer->i=='/') force = true;
  6546.       if (buffer->i=='%') force = true;
  6547.       if (buffer->i=='(') force = true;
  6548.       if (buffer->i==')') force = true;
  6549.       if (buffer->i=='<' && buffer->(i-1)~=';') force = true;
  6550.       if (buffer->i=='>') force = true;
  6551.       if (buffer->i==',') force = true;
  6552.       if (buffer->i=='.') force = true;
  6553.       if (buffer->i=='&') force = true;
  6554.       if (buffer->i=='|') force = true;
  6555.       if (buffer->i=='~') force = true;
  6556.       if (buffer->i=='=') force = true;
  6557.       if (force)
  6558.       {   if (i>2 && buffer->(i-1)~=' ')
  6559.           {   LTI_Insert(i++, ' '); altered = true;
  6560.           }
  6561.           if (buffer->(i+1)~=' ')
  6562.           {   LTI_Insert(i+1, ' '); i++; altered = true;
  6563.           }
  6564.       }
  6565.   for (i = 2 : i < buffer->1 + 2: i++)
  6566.       if (buffer->i == '~') { buffer->i = '['; altered = true; }
  6567.   return altered;
  6568. Array InfixRV_rvals --> 32;
  6569. Array InfixRV_lvals --> 32;
  6570. Array InfixRV_op --> 32;
  6571. Array InfixRV_lop --> 32;
  6572. Array InfixRV_rop --> 32;
  6573. Array InfixRV_types --> 32;
  6574. Array InfixRV_commas --> 32;
  6575. [ InfixRvalue acc w i n flag base expecting_term max maxi lop rop lvalside
  6576.               a b sysfun_f;
  6577.   if (InfixCheckLineSpaced()) return GPR_REPARSE;
  6578. !  w = wn; for (i=0: i<10: i++) { wn = w; InfixRvalueTerm(); print i, "^"; }
  6579. !  wn = w;
  6580.   expecting_term = true; base = 0;
  6581.   {   w = NextWordStopped();
  6582.       if (expecting_term)
  6583.       {   switch(w)
  6584.           {   '-//':
  6585.                   InfixRV_rvals-->n = 'unary-'; InfixRV_types-->n = base + 8;
  6586.               '[//':
  6587.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 6;
  6588.               '[[':
  6589.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 2;
  6590.               '++':
  6591.                   InfixRV_rvals-->n = 'pre++'; InfixRV_types-->n = base + 9;
  6592.               '--':
  6593.                   InfixRV_rvals-->n = 'pre--'; InfixRV_types-->n = base + 9;
  6594.               '(//':
  6595.                   InfixRV_rvals-->n = w; InfixRV_types-->n = -3; base=base+100;
  6596.               ')//':
  6597.                   InfixRV_rvals-->n = w; InfixRV_types-->n = -3; base=base-100;
  6598.                   if (base < 0) { wn--; flag = true; }
  6599.               -1: flag = true;
  6600.               default:
  6601.                   wn--;
  6602.                   if (InfixRValueTerm() == 1)
  6603.                   {   InfixRV_rvals-->n = parsed_number;
  6604.                       InfixRV_lvals-->n = infix_parsed_lvalue;
  6605.                       InfixRV_types-->n = -1;
  6606.                       expecting_term = false;
  6607.                   }
  6608.                   else flag = true;
  6609.           }
  6610.       }
  6611.       else
  6612.       {   expecting_term = true;
  6613.           switch(w)
  6614.           {   ',//':
  6615.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base;
  6616.               '=//':
  6617.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 1;
  6618.               '&&', '||':
  6619.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 2;
  6620.               '==', '[=', '>//', '>=', '<//', '<=', 'has', 'hasnt',
  6621.               'in', 'notin', 'ofclass', 'provides':
  6622.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 3;
  6623.               'or':
  6624.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 4;
  6625.               '+//', '-//':
  6626.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 5;
  6627.               '*//', '@{2f}//', '%//', '&//', '|//':
  6628.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 6;
  6629.               '->', '-->':
  6630.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 7;
  6631.               ']&', ']#':
  6632.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 10;
  6633.               './/':
  6634.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 12;
  6635.               '::':
  6636.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 13;
  6637.               '(//':
  6638.                   InfixRV_rvals-->n = '(rcall';
  6639.                   InfixRV_types-->n = base + 11; base = base + 100;
  6640.               ')//':
  6641.                   InfixRV_rvals-->n = w; InfixRV_types-->n = -3;
  6642.                   base = base - 100;
  6643.                   if (base < 0) { wn--; flag = true; }
  6644.                   expecting_term = false;
  6645.               '++':
  6646.                   InfixRV_rvals-->n = 'post++'; InfixRV_types-->n = base + 9;
  6647.                   expecting_term = false;
  6648.               '--':
  6649.                   InfixRV_rvals-->n = 'post--'; InfixRV_types-->n = base + 9;
  6650.                   expecting_term = false;
  6651.               default:
  6652.                   flag = true;
  6653.           }
  6654.       }
  6655.       n++;
  6656.   } until (flag || n==32);
  6657.   if (base > 0) return -1;
  6658.   n--; if (n == 0) return -1;
  6659.   wn--;
  6660.   for (i=0: i<n: i++)
  6661.   {   acc = 0; if (InfixRV_types-->i ~= -3) acc = InfixRV_rvals-->i;
  6662.       InfixRV_op-->i = acc;
  6663.   for (::)
  6664.   {   
  6665. !      for (i=0: i<n: i++)
  6666. !      {   if (InfixRV_types-->i == -1) print InfixRV_rvals-->i, " ";
  6667. !          else if (InfixRV_types-->i == -3) print " # ";
  6668. !          else if (InfixRV_types-->i == -2) print " ## ";
  6669. !          else print (address) InfixRV_rvals-->i, "_", InfixRV_types-->i, " ";
  6670. !      }
  6671. !      new_line;
  6672.       max = -2;
  6673.       for (i=0:i<n:i++) if (InfixRV_types-->i > max)
  6674.                         { max = InfixRV_types-->i; maxi = i; }
  6675.       if (max == -1) { parsed_number = InfixRV_rvals-->maxi; return 1; }
  6676.       lop = maxi-1; rop = maxi+1;
  6677.       while (lop>=0 && InfixRV_types-->lop < -1) lop--;
  6678.       while (rop<n && InfixRV_types-->rop < -1) rop++;
  6679.       if (lop>=0) InfixRV_lop-->maxi = InfixRV_rvals-->lop;
  6680.       if (rop<n) InfixRV_rop-->maxi = InfixRV_rvals-->rop;
  6681.       flag = false;
  6682.     infix_term_type = INFIXTT_NUMBER;
  6683.     switch(InfixRV_rvals-->maxi)
  6684.     { ',//':     acc = (InfixRV_rvals-->rop);
  6685.       '=//', 'pre++', 'post++', 'pre--', 'post--':
  6686.                  lvalside = lop;
  6687.                  switch(InfixRV_rvals-->maxi)
  6688.                  {   '=//': acc = (InfixRV_rvals-->rop);
  6689.                      'pre++': acc = (InfixRV_rvals-->rop) + 1; lvalside = rop;
  6690.                      'pre--': acc = (InfixRV_rvals-->rop) - 1; lvalside = rop;
  6691.                      'post++': acc = (InfixRV_rvals-->lop) + 1;
  6692.                      'post--': acc = (InfixRV_rvals-->lop) - 1;
  6693.                  }
  6694.                  switch (InfixRV_op-->lvalside)
  6695.                  {   './/':
  6696.                        (InfixRV_lop-->lvalside).(InfixRV_rop-->lvalside) = acc;
  6697.                      '->':
  6698.                        (InfixRV_lop-->lvalside)->(InfixRV_rop-->lvalside) = acc;
  6699.                      '-->':
  6700.                        (InfixRV_lop-->lvalside)-->(InfixRV_rop-->lvalside) = acc;
  6701.                      default:
  6702.                          w = InfixRV_lvals-->lvalside; if (w == -1) return -1;
  6703.                          @storew #globals_array w acc;
  6704.                  }
  6705.                  switch(InfixRV_rvals-->maxi)
  6706.                  {   'post++': acc--;
  6707.                      'post--': acc++;
  6708.                  }
  6709.       '(rcall':  sysfun_f = false;
  6710.                  switch (InfixRV_op-->lop)
  6711.                  {   './/': a = InfixRV_lop-->lop; b = InfixRV_rop-->lop;
  6712.                      default:
  6713.                          a = InfixRV_rvals-->lop; b = call;
  6714.                          if (InfixRV_lvals-->lop == INFIXTT_SYSFUN)
  6715.                              sysfun_f = true;
  6716.                  }
  6717.                  w = 0;
  6718.                  i = maxi + 1; base = 100;
  6719.                  if (InfixRV_types-->i == -1 && InfixRV_rvals-->i == ')//')
  6720.                  {   if (sysfun_f) return -1;
  6721.                      acc = a.b();
  6722.                  }
  6723.                  else
  6724.                  {   while (base > 0)
  6725.                      {   if (InfixRV_types-->i == -3 && InfixRV_rvals-->i == ')//')
  6726.                              base = base - 100;
  6727.                          if (InfixRV_types-->i == -3 && InfixRV_rvals-->i == '(//')
  6728.                              base = base + 100;
  6729.                          if (InfixRV_op-->i=='(rcall') base = base + 100;
  6730.                          if (base == 100 && InfixRV_op-->i == ',//')
  6731.                          {   InfixRV_commas-->(w++) = i;
  6732. !                             print "Comma found at ", i, "^";
  6733.                          }
  6734.                          i++;
  6735.                      }
  6736. !                     print "Num args = ", w + 1, "^";
  6737. !                     for (i = 0 : i < w : i++)
  6738. !                         print "arg: ", InfixRV_lop-->(InfixRV_commas-->i), "^";
  6739. !                     print "arg: ", InfixRV_rvals-->rop, "^";
  6740.                      switch(w+1)
  6741.                      {   1: if (sysfun_f)
  6742.                             {   b = InfixRV_rvals-->rop;
  6743.                                 infix_term_type = INFIXTT_NAMEDOBJECT;
  6744.                                 switch(a)
  6745.                                 {   'metaclass': acc = metaclass(b);
  6746.                                     'parent': acc = parent(b);
  6747.                                     'child': acc = child(b);
  6748.                                     'children': acc = children(b);
  6749.                                          infix_term_type = INFIXTT_NUMBER;
  6750.                                     'random': acc = random(b);
  6751.                                          infix_term_type = INFIXTT_NUMBER;
  6752.                                     'sibling': acc = sibling(b);
  6753.                                 }
  6754.                             }
  6755.                             else
  6756.                                 acc = a.b(InfixRV_rvals-->rop);
  6757.                          2: if (sysfun_f) return -1;
  6758.                             acc = a.b(InfixRV_lop-->(InfixRV_commas-->0),
  6759.                                       InfixRV_rvals-->rop);
  6760.                          3: if (sysfun_f) return -1;
  6761.                             acc = a.b(InfixRV_lop-->(InfixRV_commas-->0),
  6762.                                       InfixRV_lop-->(InfixRV_commas-->1),
  6763.                                       InfixRV_rvals-->rop);
  6764.                          4: if (sysfun_f) return -1;
  6765.                             acc = a.b(InfixRV_lop-->(InfixRV_commas-->0),
  6766.                                       InfixRV_lop-->(InfixRV_commas-->1),
  6767.                                       InfixRV_lop-->(InfixRV_commas-->2),
  6768.                                       InfixRV_rvals-->rop);
  6769.                          5: if (sysfun_f) return -1;
  6770.                             acc = a.b(InfixRV_lop-->(InfixRV_commas-->0),
  6771.                                       InfixRV_lop-->(InfixRV_commas-->1),
  6772.                                       InfixRV_lop-->(InfixRV_commas-->2),
  6773.                                       InfixRV_lop-->(InfixRV_commas-->3),
  6774.                                       InfixRV_rvals-->rop);
  6775.                          default: return -1;
  6776.                      }                     
  6777.                  }
  6778.       '+//':     acc = (InfixRV_rvals-->lop) + (InfixRV_rvals-->rop);
  6779.       '-//':     acc = (InfixRV_rvals-->lop) - (InfixRV_rvals-->rop);
  6780.       '*//':     acc = (InfixRV_rvals-->lop) * (InfixRV_rvals-->rop);
  6781.       '@{2f}//': acc = (InfixRV_rvals-->lop) / (InfixRV_rvals-->rop);
  6782.       '%//':     acc = (InfixRV_rvals-->lop) % (InfixRV_rvals-->rop);
  6783.       './/':     acc = (InfixRV_rvals-->lop) . (InfixRV_rvals-->rop);
  6784.       '->':      acc = (InfixRV_rvals-->lop) -> (InfixRV_rvals-->rop);
  6785.       '-->':     acc = (InfixRV_rvals-->lop) --> (InfixRV_rvals-->rop);
  6786.       ']&':      acc = (InfixRV_rvals-->lop) .& (InfixRV_rvals-->rop);
  6787.       ']#':      acc = (InfixRV_rvals-->lop) .# (InfixRV_rvals-->rop);
  6788.       '::':      acc = (InfixRV_rvals-->lop) :: (InfixRV_rvals-->rop);
  6789.       '&//':     acc = (InfixRV_rvals-->lop) & (InfixRV_rvals-->rop);
  6790.       '|//':     acc = (InfixRV_rvals-->lop) | (InfixRV_rvals-->rop);
  6791.       '&&':      acc = (InfixRV_rvals-->lop) && (InfixRV_rvals-->rop);
  6792.                  infix_term_type = INFIXTT_LOGICAL;
  6793.       '||':      acc = (InfixRV_rvals-->lop) || (InfixRV_rvals-->rop);
  6794.                  infix_term_type = INFIXTT_LOGICAL;
  6795.       '<//':     acc = (InfixRV_rvals-->lop) < (InfixRV_rvals-->rop);
  6796.                  infix_term_type = INFIXTT_LOGICAL;
  6797.       '<=':      acc = (InfixRV_rvals-->lop) <= (InfixRV_rvals-->rop);
  6798.                  infix_term_type = INFIXTT_LOGICAL;
  6799.       '>//':     acc = (InfixRV_rvals-->lop) > (InfixRV_rvals-->rop);
  6800.                  infix_term_type = INFIXTT_LOGICAL;
  6801.       '>=':      acc = (InfixRV_rvals-->lop) >= (InfixRV_rvals-->rop);
  6802.                  infix_term_type = INFIXTT_LOGICAL;
  6803.       '==':      acc = (InfixRV_rvals-->lop) == (InfixRV_rvals-->rop);
  6804.                  infix_term_type = INFIXTT_LOGICAL;
  6805.       '[=':  acc = (InfixRV_rvals-->lop) ~= (InfixRV_rvals-->rop);
  6806.                  infix_term_type = INFIXTT_LOGICAL;
  6807.       'has':     acc = (InfixRV_rvals-->lop) has (InfixRV_rvals-->rop);
  6808.                  infix_term_type = INFIXTT_LOGICAL;
  6809.       'hasnt':   acc = (InfixRV_rvals-->lop) hasnt (InfixRV_rvals-->rop);
  6810.                  infix_term_type = INFIXTT_LOGICAL;
  6811.       'in':      acc = (InfixRV_rvals-->lop) in (InfixRV_rvals-->rop);
  6812.                  infix_term_type = INFIXTT_LOGICAL;
  6813.       'notin':   acc = (InfixRV_rvals-->lop) notin (InfixRV_rvals-->rop);
  6814.                  infix_term_type = INFIXTT_LOGICAL;
  6815.       'provides': acc = (InfixRV_rvals-->lop) provides (InfixRV_rvals-->rop);
  6816.                  infix_term_type = INFIXTT_LOGICAL;
  6817.       'ofclass': acc = (InfixRV_rvals-->lop) ofclass (InfixRV_rvals-->rop);
  6818.                  infix_term_type = INFIXTT_LOGICAL;
  6819.       '[[':      acc = ~~ (InfixRV_rvals-->rop); flag = true;
  6820.       '[//':     acc = ~ (InfixRV_rvals-->rop); flag = true;
  6821.       'unary-':  acc = - (InfixRV_rvals-->rop); flag = true;
  6822.     }
  6823.       InfixRV_rvals-->maxi = acc;
  6824.       InfixRV_types-->maxi = -1;
  6825.       if (rop < n) InfixRV_types-->rop = -2;
  6826.       if (flag==false && lop >= 0) InfixRV_types-->lop = -2;
  6827. ! ------------------------------------------------------------------------
  6828. [ InfixWelcomeSub;
  6829.   print "; Welcome to the ~Infix~ debugger (1/990428), which makes the
  6830.       following verbs available:^^
  6831.       ~; <expression>~: evaluates this Inform expression: e.g.
  6832.       ~; location~ will print the value of the variable ~location~,
  6833.       ~; 3*5+1~ will print 16, ~; children(old cloth bag)~ will tell you
  6834.       how many items are in it. (You can name objects either by their
  6835.       names inside the source code, such as ~n_obj~, or by typing the
  6836.       names by which the game's parser would normally know them, such
  6837.       as ~north wall~: the effect is the same.)^
  6838.       Any expression is allowed except that you can't use double-quoted
  6839.       strings of text: but you can send messages, call routines or
  6840.       assign values to variables, properties and array entries.
  6841.       ^   ~; score++~ is one way to get on in the world.
  6842.       ^   ~; deadflag = true~ is one way to get out of it.
  6843.       ^   ~; StopDaemon(nasty little dwarf)~ will keep you from being pestered.^
  6844.       Conditions like ~; score>20~ are also allowed and print
  6845.       either 1 (if true) or 0 (if false).^^";
  6846.   print "~;examine <something>~ or ~;x <something>~ gives full details
  6847.       of whatever it is. For instance, ~;x ##Take~ describes the Take
  6848.       action; ~;x Class~ the class Class; ~;x 'drop'~ the dictionary
  6849.       word ~drop~ and so on for numbers, routines, arrays and of course
  6850.       objects.  ~;xo~ examines something as an object, so for instance
  6851.       ~;x location~ tells you about the variable ~location~, but ~;xo
  6852.       location~ tells you what object it refers to.^^";
  6853.   print "~;give~, ~;remove~ and ~;move~ work like the corresponding
  6854.       Inform statements.^^";
  6855.   print "~;<~ causes an action: for instance, ~;< Eat cheese~.^^";
  6856.   print "~;watch~ or ~;w~ can set a watch on various activities:
  6857.       type just ~;w~ for details.^^";
  6858.   print "~;inventory~ or ~;i~ describes the contents of this story file.^";
  6859. [ InfixEvalSub;
  6860.   InfixExamineP(true);
  6861. [ InfixActionSub;
  6862.   print "; <", (InfixPrintAction) infix_lvalue;
  6863.   if (noun) print " (", (the) noun, ")";
  6864.   if (second) print " (", (the) second, ")";
  6865.   print ">^";
  6866.   if (second) <<(infix_lvalue) noun second>>;
  6867.   if (noun) <<(infix_lvalue) noun>>;
  6868.   <<(infix_lvalue)>>;
  6869. [ InfixGiveSub f;
  6870.   print "; give (", (the) noun, ") ";
  6871.   if (second<0) { second = ~second; f=true; }
  6872.   if (second < 0 || second>=48) "<No such attribute>";
  6873.   if (f) print "@@126";
  6874.   print (DebugAttribute) second;
  6875.   if (f) @clear_attr noun second;
  6876.   else @set_attr noun second;
  6877. [ InfixMoveSub;
  6878.   print "; move (", (the) noun, ") to (", (the) second, ")";
  6879.   move noun to second;
  6880. [ InfixRemoveSub;
  6881.   print "; remove (", (the) noun, ")";
  6882.   remove noun;
  6883. [ InfixHex x y;
  6884.       y = (x & $7f00) / $100;
  6885.       if (x<0) y=y+$80;
  6886.       x = x & $ff;
  6887.       print (Infixhexdigit) y/$10, (Infixhexdigit) y,
  6888.             (Infixhexdigit) x/$10, (Infixhexdigit) x;
  6889. [ Infixhexdigit x;
  6890.   x = x % $10; if (x<10) print x; else print (char) 'a'+x-10;
  6891. [ InfixExamineOSub;
  6892.   infix_data1 = metaclass(noun);
  6893.   infix_term_type = INFIXTT_CONSTANT;
  6894.   InfixExamineP(false);
  6895. [ InfixExamineSSub;
  6896.   infix_term_type = INFIXTT_STATICSTRING;
  6897.   InfixExamineP(false);
  6898. [ InfixExamineSub;
  6899.   InfixExamineP(false);
  6900. [ InfixExamineP brief x a b w flag lines;
  6901.   switch(infix_term_type)
  6902.   {   INFIXTT_NUMBER:
  6903.           if (brief) "; == ", noun;
  6904.           print "; The number ", noun, " == $", (InfixHex) noun;
  6905.           if (noun >= 32 && noun < 127) print " == '", (char) noun, "'";
  6906.           new_line;
  6907.       INFIXTT_NAMEDOBJECT:
  6908.           print "~", (name) noun, "~ (", noun, ")^"; if (brief) return;
  6909.           <<Showobj noun>>;
  6910.       INFIXTT_CONSTANT:
  6911.           if (brief) "; == ", noun;
  6912.           switch(infix_data1 & 15)
  6913.           {   nothing:
  6914.                   print "; Constant ", (InfixPrintConstant) infix_parsed_lvalue,
  6915.                   " == ", noun, "^";
  6916.               Object: <<Showobj noun>>;
  6917.               Class: print "Class ", (name) noun, "^";
  6918.                   objectloop (a ofclass noun)
  6919.                   {   if (flag) print ", "; else print "Contains: ";
  6920.                       print (name) a, " (", a, ")"; flag=true;
  6921.                   }
  6922.                   if (flag==false) "No object is of this class";
  6923.           }
  6924.           new_line;
  6925.       INFIXTT_ATTRIBUTE:
  6926.           if (brief) "; == ", noun;
  6927.           if (noun>=48 || noun<0) "; No such attribute";
  6928.           print "; Attribute ", (InfixPrintAttribute) noun,
  6929.               " (numbered ", noun, ")^";
  6930.           objectloop (x has noun)
  6931.           {   if (flag) print ", ";
  6932.               else print "Each of these ~has ", (InfixPrintAttribute) noun, "~: ";
  6933.               print (name) x, " (", x, ")"; flag = true;
  6934.           }
  6935.           if (flag == false) "No object ~has ", (InfixPrintAttribute) noun, "~";
  6936.           new_line;
  6937.       INFIXTT_PROPERTY:
  6938.           if (brief) "; == ", noun;
  6939.           print "; Property ", (property) noun, " (numbered ", noun, ")^";
  6940.           objectloop (x provides noun)
  6941.           {   if (flag) print ", "; else print "Provided by: ";
  6942.               print (name) x, " (", x, ")"; flag = true;
  6943.           }
  6944.           if (flag == false) "Which is not provided by any object";
  6945.           new_line;
  6946.       INFIXTT_DWORD:
  6947.           if (brief) "; == ", noun;
  6948.           if (noun == 0) "; This word is not in the dictionary";
  6949.           a = noun->#dict_par1;
  6950.           print "; Dictionary word '", (address) noun;
  6951.           if (a & 4) print "//p";
  6952.           print "' (address ", noun, ")";
  6953.           if (a)
  6954.           {   print ": ";
  6955.               if (a & 2) print "meta ";
  6956.               if (a & 1) print "verb   ";
  6957.               if (a & 8) print "preposition   ";
  6958.               if (a & 4) print "pluralising ";
  6959.               if (a & 128) print "noun ";
  6960.           }
  6961.           new_line;
  6962.           if (a & 1) <<Showverb noun>>;
  6963.       INFIXTT_ROUTINE:
  6964.           if (brief) "; == ", noun;
  6965.           print "; Routine ", (InfixPrintRoutine) infix_parsed_lvalue,
  6966.               " (number ", infix_parsed_lvalue, ",
  6967.               packed address ", noun, ")^";
  6968.       INFIXTT_GLOBAL:
  6969.           if (brief) "; == ", noun;
  6970.           print "; Global ", (InfixPrintGlobal) infix_parsed_lvalue,
  6971.               " == ", noun, "^";
  6972.       INFIXTT_ARRAY:
  6973.           if (brief) "; == ", noun;
  6974.           print "; Array ", (InfixPrintArray) infix_parsed_lvalue, " ";
  6975.           infix_data1 = infix_data1 % 16;
  6976.           switch(infix_data1)
  6977.           {   0: print "->"; a=0;
  6978.               1: print "-->"; a=0;
  6979.               2: print "string"; a=1;
  6980.               3: print "table"; a=1;
  6981.           }
  6982.           print " ", infix_data2, "^; == "; b=infix_data2; if (x) b++;
  6983.           for (w=b-1:w>=a:w--)
  6984.               if (infix_data1 == 0 or 2) { if (noun->w) break; }
  6985.               else { if (noun-->w) break; }
  6986.           if (b-1-w <= 5) w=b-1;
  6987.           for (:x<=w:x++)
  6988.               if (infix_data1 == 0 or 2) print noun->x, " ";
  6989.               else print noun-->x, " ";
  6990.           if (w<a) print "(", b-a, " zero entries)";
  6991.           else if (w<b-1) print "(then ", b-1-w, " zero entries)";
  6992.           new_line;
  6993.       INFIXTT_ACTION:
  6994.           if (brief) "; == ", noun;
  6995.           if (noun >= #lowest_fake_action_number
  6996.               && noun <= #highest_fake_action_number)
  6997.              "; Fake action ", (InfixPrintFakeAction) noun,
  6998.               " (numbered ", noun, ")^Is not generated by any grammar";
  6999.           print "; Action ", (InfixPrintAction) noun,
  7000.               " (numbered ", noun, ")^";
  7001.           w = 0-->4;
  7002.           for (b=0:b<(0-->4 + 5)-->0:b++)
  7003.           {   w = 0-->4 + 7 + b*9;
  7004.               if ((w->#dict_par1) & 1)
  7005.               {   a = (0-->7)-->($ff-(w->#dict_par2));
  7006.                   lines = a->0; a++;
  7007.                   for (:lines > 0:lines--)
  7008.                   {   a = UnpackGrammarLine(a);
  7009.                       if (action_to_be == noun)
  7010.                       {   print "'", (address) w, "' "; DebugGrammarLine();
  7011.                           new_line;
  7012.                           flag = true;
  7013.                       }
  7014.                   }
  7015.               }
  7016.           }
  7017.           if (flag == 0) "Is not generated by any grammar";
  7018.       INFIXTT_SYSFUN:
  7019.           if (brief) "; == ", noun;
  7020.          "; System function ~", (address) infix_parsed_lvalue, "~ has
  7021.           not been overridden by any routine and so has its standard
  7022.           definition.";
  7023.       INFIXTT_STATICSTRING:
  7024.           if (brief) "; == ", noun;
  7025.           if (metaclass(noun) ~= String) "; ", noun, " is not a string.";
  7026.           print "~", (string) noun, "~^";
  7027.       INFIXTT_LOGICAL:
  7028.           if (noun==true) "; true"; if (noun==false) "; false";
  7029.           "; ", noun;
  7030. [ InfixDescribeWatchSub x y z s flag aflag;
  7031.   print "; The Infix ~;watch~ verb allows you to set a watch on any named
  7032.       routine(s) or objects: for instance ~;watch ScoreSub~ or
  7033.       ~;watch silver bars~. You can also:
  7034.       ^    ~;watch objects~: changes to attribute or property settings";
  7035.   if (debug_flag & 8) print " (on)"; else print " (off)";
  7036.       print ";^    ~;watch timers~: the running of timers and daemons each turn";
  7037.   if (debug_flag & 4) print " (on)"; else print " (off)";
  7038.       print ";^    ~;watch messages~: all messages sent";
  7039.   if (debug_flag & 1) print " (on)"; else print " (off)";
  7040.       print ";^    ~;watch actions~: all actions generated";
  7041.   if (debug_flag & 2) print " (on)"; else print " (off)";
  7042.       print ".^~~;watch~ can be abbreviated to ~;w~ and use ~off~ to stop
  7043.       watching: for instance ~;w location off~.^";
  7044.   aflag = debug_flag;
  7045.   objectloop (x has infix__watching) flag = true; aflag = aflag || flag;
  7046.   if (flag) print "The following objects are currently being watched: ";
  7047.   flag = false;
  7048.   objectloop (x has infix__watching)
  7049.   {   if (flag) print ", "; flag = true;
  7050.       print (name) x, " (", x, ")";
  7051.   if (flag) new_line;
  7052.   s = (#highest_routine_number - #lowest_routine_number);
  7053.   if (s%8 == 0) s=s/8; else s=s/8+1;
  7054.   for (flag=false, x=0:x<s:x++) if (#routine_flags_array->x) flag = true;
  7055.   aflag = aflag || flag;
  7056.   if (flag) print "The following routines are currently being watched: ";
  7057.   for (x=0, flag=false:x<s:x++)
  7058.   {   for (y=1,z=0:y<256:z++,y=y*2)
  7059.       {   if ((#routine_flags_array->x) & y)
  7060.           {   if (flag) print ", "; flag = true;
  7061.               print (InfixPrintRoutine)
  7062.                   #lowest_routine_number + x*8 + z;
  7063.           }
  7064.       }
  7065.   if (flag) new_line;
  7066.   if (aflag == false) "At present, nothing is being watched.";
  7067. [ InfixWatchOnSub i j k l;
  7068.   if (noun == 0) return InfixDescribeWatchSub();
  7069.   if (infix_term_type == INFIXTT_ROUTINE)
  7070.   {   i = infix_parsed_lvalue/8;
  7071.       for (j=0,k=1:j<infix_parsed_lvalue%8:j++) k=k*2;
  7072.       l = #routine_flags_array->i;
  7073.       l = l | k;
  7074.       @storeb #routine_flags_array i l;
  7075.      "; Watching routine ", (InfixPrintRoutine) infix_parsed_lvalue, ".";
  7076.   if (metaclass(noun) == Object)
  7077.   {   give noun infix__watching;
  7078.      "; Watching object ~", (name) noun, "~ (", noun, ").";  
  7079.   InfixDescribeWatchSub();
  7080. [ InfixWatchOffSub i j k l;
  7081.   if (noun == 0) return InfixDescribeWatchSub();
  7082.   if (infix_term_type == INFIXTT_ROUTINE)
  7083.   {   i = infix_parsed_lvalue/8;
  7084.       for (j=0,k=1:j<infix_parsed_lvalue%8:j++) k=k*2;
  7085.       l = #routine_flags_array->i;
  7086.       l = l & (~k);
  7087.       @storeb #routine_flags_array i l;
  7088.      "; Not watching ", (InfixPrintRoutine) infix_parsed_lvalue, ".";
  7089.   if (metaclass(noun) == Object)
  7090.   {   @clear_attr noun infix__watching;
  7091.      "; Not watching object ~", (name) noun, "~ (", noun, ").";  
  7092.   InfixDescribeWatchSub();
  7093. [ InfixList from to tab filter i flag;
  7094.   print "^    ";
  7095.   for (i=from:i<=to:i++)
  7096.       if (tab-->(i-from))
  7097.       {   flag = true;
  7098.           if (tab == #array_names_array)
  7099.           {   Symb__Tab(INFIXTT_ARRAY, i);
  7100.               flag = ~~(temp__global3 & 16);
  7101.           }
  7102.           if (tab == #routine_names_array)
  7103.           {   Symb__Tab(INFIXTT_ROUTINE,i);
  7104.               flag = ~~(temp__global3 & 16);
  7105.           }
  7106.           if (tab == #constant_names_array)
  7107.           {   Symb__Tab(INFIXTT_CONSTANT,i);
  7108.               flag = (~~(temp__global3 & 16)) && (temp__global3 % 16 == filter);
  7109.           }
  7110.           if (flag) print (string) tab-->(i-from), " ";
  7111.       }
  7112.   new_line;
  7113. [ InfixInvSub i;
  7114.   print (string) Story, (string) Headline;
  7115.   print "  ", (number) #highest_object_number - #lowest_object_number + 1,
  7116.       " objects;^";
  7117.   print "  non-library object-name constants:";
  7118.   InfixList(#lowest_constant_number, #highest_constant_number,
  7119.       #constant_names_array, 2);
  7120.   print "  ", (number) #highest_class_number - #lowest_class_number + 1,
  7121.       "  classes:^    ";
  7122.   for (i=#lowest_class_number:i<=#highest_class_number:i++)
  7123.       print (name) #class_objects_array-->i, " ";
  7124.   new_line;
  7125.   print "  non-library arrays:";
  7126.   InfixList(#lowest_array_number, #highest_array_number,
  7127.       #array_names_array);
  7128.   print "  non-library routines:";
  7129.   InfixList(#lowest_routine_number, #highest_routine_number,
  7130.       #routine_names_array);
  7131.   print "  non-library constants:";
  7132.   InfixList(#lowest_constant_number, #highest_constant_number,
  7133.       #constant_names_array, 0);
  7134.   print "  (common) properties:";
  7135.   InfixList(#lowest_property_number, 63, #property_names_array);
  7136.   print "  (individual) properties:";
  7137.   InfixList(64, #highest_property_number, #property_names_array + 126);
  7138.   print "  attributes:";
  7139.   InfixList(#lowest_attribute_number, #highest_attribute_number,
  7140.       #attribute_names_array);
  7141.   if (true) return;
  7142.   print "  variables:";
  7143.   InfixList(#lowest_global_number, #highest_global_number,
  7144.       #global_names_array);
  7145.   print "  actions:";
  7146.   InfixList(#lowest_action_number, #highest_action_number,
  7147.       #action_names_array);
  7148.   print "  fake actions:";
  7149.   InfixList(#lowest_fake_action_number, #highest_fake_action_number,
  7150.       #fake_action_names_array);
  7151. Verb ";i" ";inv" ";inventory"
  7152.      * -> InfixInv;
  7153. Verb ";x" ";examine"
  7154.      * InfixRvalue -> InfixExamine;
  7155. Verb ";xo" ";examineo"
  7156.      * InfixRvalue -> InfixExamineO;
  7157. Verb ";xs" ";examines"
  7158.      * InfixRvalue -> InfixExamineS;
  7159. Verb ";<"
  7160.      * InfixActionToken -> InfixAction
  7161.      * InfixActionToken InfixRvalue -> InfixAction
  7162.      * InfixActionToken InfixRvalue InfixRvalue -> InfixAction;
  7163. Verb ";"
  7164.      * -> InfixWelcome
  7165.      * InfixRvalue -> InfixEval;
  7166. Verb ";give"
  7167.      * InfixRvalue InfixRvalue -> InfixGive;
  7168. Verb ";move"
  7169.      * InfixRvalue "to" InfixRvalue -> InfixMove;
  7170. Verb ";remove"
  7171.      * InfixRvalue -> InfixRemove;
  7172. Verb ";watch" ";w"
  7173.      * -> InfixWatchOn
  7174.      * "timers"/"daemons" -> TimersOn
  7175.      * "timers"/"daemons" "off" -> TimersOff
  7176.      * "actions" -> ActionsOn
  7177.      * "actions" "off" -> ActionsOff
  7178.      * "messages" -> RoutinesOn
  7179.      * "messages" "off" -> RoutinesOff
  7180.      * "objects" -> ChangesOn
  7181.      * "objects" "off" -> ChangesOff
  7182.      * InfixRvalueTerm -> InfixWatchOn
  7183.      * InfixRvalueTerm "off" -> InfixWatchOff;
  7184. ! ------------------------------------------------------------------------
  7185. ! ----------------------------------------------------------------------------
  7186. !  GRAMMAR:  Grammar table entries for the standard verbs library.
  7187. !  Supplied for use with Inform 6                         Serial number 990428
  7188. !                                                                  Release 6/9
  7189. !  (c) Graham Nelson 1993, 1994, 1995, 1996, 1997, 1998, 1999
  7190. !      but freely usable (see manuals)
  7191. ! ----------------------------------------------------------------------------
  7192. !  The "meta-verbs", commands to the game rather than in the game, come first:
  7193. ! ----------------------------------------------------------------------------
  7194. System_file;
  7195. Verb meta 'score'
  7196.                 *                                -> Score;
  7197. Verb meta 'fullscore' 'full'
  7198.                 *                                -> FullScore
  7199.                 * 'score'                        -> FullScore;
  7200. Verb meta 'q//' 'quit' 'die'
  7201.                 *                                -> Quit;
  7202. Verb meta 'restore'
  7203.                 *                                -> Restore;
  7204. Verb meta 'restart'
  7205.                 *                                -> Restart;
  7206. Verb meta 'verify'
  7207.                 *                                -> Verify;
  7208. Verb meta 'save'
  7209.                 *                                -> Save;
  7210. Verb meta 'script' 'transcript'
  7211.                 *                                -> ScriptOn
  7212.                 * 'off'                          -> ScriptOff
  7213.                 * 'on'                           -> ScriptOn;
  7214. Verb meta 'noscript' 'unscript'
  7215.                 *                                -> ScriptOff;
  7216. Verb meta 'superbrief' 'short'
  7217.                 *                                -> LMode3;
  7218. Verb meta 'verbose' 'long'
  7219.                 *                                -> LMode2;
  7220. Verb meta 'brief' 'normal'
  7221.                 *                                -> LMode1;
  7222. Verb meta 'pronouns' 'nouns'
  7223.                 *                                -> Pronouns;
  7224. Verb meta 'notify'
  7225.                 * 'on'                           -> NotifyOn
  7226.                 * 'off'                          -> NotifyOff;
  7227. Verb meta 'version'
  7228.                 *                                -> Version;
  7229. #IFNDEF NO_PLACES;
  7230. Verb meta 'places'
  7231.                 *                                -> Places;
  7232. Verb meta 'objects'
  7233.                 *                                -> Objects;
  7234. #ENDIF;
  7235. ! ----------------------------------------------------------------------------
  7236. !  Debugging grammar
  7237. ! ----------------------------------------------------------------------------
  7238. #ifdef DEBUG;
  7239. Verb meta 'trace'
  7240.                 *                                -> TraceOn
  7241.                 * number                         -> TraceLevel
  7242.                 * 'on'                           -> TraceOn
  7243.                 * 'off'                          -> TraceOff;
  7244. Verb meta 'actions'
  7245.                 *                                -> ActionsOn
  7246.                 * 'on'                           -> ActionsOn
  7247.                 * 'off'                          -> ActionsOff;
  7248. Verb meta 'routines' 'messages'
  7249.                 *                                -> RoutinesOn
  7250.                 * 'on'                           -> RoutinesOn
  7251.                 * 'off'                          -> RoutinesOff;
  7252. Verb meta 'timers' 'daemons'
  7253.                 *                                -> TimersOn
  7254.                 * 'on'                           -> TimersOn
  7255.                 * 'off'                          -> TimersOff;
  7256. Verb meta 'changes'
  7257.                 *                                -> ChangesOn
  7258.                 * 'on'                           -> ChangesOn
  7259.                 * 'off'                          -> ChangesOff;
  7260. Verb meta 'recording'
  7261.                 *                                -> CommandsOn
  7262.                 * 'on'                           -> CommandsOn
  7263.                 * 'off'                          -> CommandsOff;
  7264. Verb meta 'replay'
  7265.                 *                                -> CommandsRead;
  7266. Verb meta 'random'
  7267.                 *                                -> Predictable;
  7268. Verb meta 'purloin'
  7269.                 * multi                          -> XPurloin;
  7270. Verb meta 'abstract'
  7271.                 * noun 'to' noun                 -> XAbstract;
  7272. Verb meta 'tree'
  7273.                 *                                -> XTree
  7274.                 * noun                           -> XTree;
  7275. Verb meta 'goto'
  7276.                 * number                         -> Goto;
  7277. Verb meta 'gonear'
  7278.                 * noun                           -> Gonear;
  7279. Verb meta 'scope'
  7280.                 *                                -> Scope
  7281.                 * noun                           -> Scope;
  7282. Verb meta 'showverb'
  7283.                 * special                        -> Showverb;
  7284. Verb meta 'showobj'
  7285.                 *                                -> Showobj
  7286.                 * multi                          -> Showobj;
  7287. #endif;
  7288. ! ----------------------------------------------------------------------------
  7289. !  And now the game verbs.
  7290. ! ----------------------------------------------------------------------------
  7291. Verb 'take' 'carry' 'hold'
  7292.                 * multi                          -> Take
  7293.                 * 'off' worn                     -> Disrobe
  7294.                 * multiinside 'from' noun        -> Remove
  7295.                 * multiinside 'off' noun         -> Remove
  7296.                 * 'inventory'                    -> Inv;
  7297. Verb 'get'      * 'out'/'off'/'up'               -> Exit
  7298.                 * multi                          -> Take
  7299.                 * 'in'/'into'/'on'/'onto' noun   -> Enter
  7300.                 * 'off' noun                     -> GetOff
  7301.                 * multiinside 'from' noun        -> Remove;
  7302. Verb 'pick'
  7303.                 * 'up' multi                     -> Take
  7304.                 * multi 'up'                     -> Take;
  7305. Verb 'stand'
  7306.                 *                                -> Exit
  7307.                 * 'up'                           -> Exit
  7308.                 * 'on' noun                      -> Enter;
  7309. Verb 'remove'
  7310.                 * held                           -> Disrobe
  7311.                 * multi                          -> Take
  7312.                 * multiinside 'from' noun        -> Remove;
  7313. Verb 'shed' 'doff' 'disrobe'
  7314.                 * held                           -> Disrobe; 
  7315. Verb 'wear' 'don'
  7316.                 * held                           -> Wear;
  7317. Verb 'put'
  7318.                 * multiexcept 'in'/'inside'/'into' noun
  7319.                                                  -> Insert
  7320.                 * multiexcept 'on'/'onto' noun   -> PutOn
  7321.                 * 'on' held                      -> Wear
  7322.                 * 'down' multiheld               -> Drop
  7323.                 * multiheld 'down'               -> Drop;
  7324. Verb 'insert'
  7325.                 * multiexcept 'in'/'into' noun   -> Insert;
  7326. Verb 'empty'
  7327.                 * noun                           -> Empty
  7328.                 * 'out' noun                     -> Empty
  7329.                 * noun 'out'                     -> Empty
  7330.                 * noun 'to'/'into'/'on'/'onto' noun
  7331.                                                  -> EmptyT;
  7332. Verb 'transfer'
  7333.                 * noun 'to' noun                 -> Transfer;
  7334. Verb 'drop' 'throw' 'discard'
  7335.                 * multiheld                      -> Drop
  7336.                 * multiexcept 'in'/'into'/'down' noun
  7337.                                                  -> Insert
  7338.                 * multiexcept 'on'/'onto' noun   -> PutOn
  7339.                 * held 'at'/'against'/'on'/'onto' noun
  7340.                                                  -> ThrowAt;
  7341. Verb 'give' 'pay' 'offer' 'feed'
  7342.                 * held 'to' creature             -> Give
  7343.                 * creature held                  -> Give reverse
  7344.                 * 'over' held 'to' creature      -> Give;
  7345. Verb 'show' 'present' 'display'
  7346.                 * creature held                  -> Show reverse
  7347.                 * held 'to' creature             -> Show;
  7348. [ ADirection; if (noun in compass) rtrue; rfalse; ];
  7349. Verb 'go' 'walk' 'run'
  7350.                 *                                -> VagueGo
  7351.                 * noun=ADirection                -> Go
  7352.                 * noun                           -> Enter
  7353.                 * 'into'/'in'/'inside'/'through' noun
  7354.                                                  -> Enter;
  7355. Verb 'leave'
  7356.                 *                                -> VagueGo
  7357.                 * noun=ADirection                -> Go
  7358.                 * noun                           -> Exit
  7359.                 * 'into'/'in'/'inside'/'through' noun
  7360.                                                  -> Enter;
  7361. Verb 'inventory' 'inv' 'i//'
  7362.                 *                                -> Inv
  7363.                 * 'tall'                         -> InvTall
  7364.                 * 'wide'                         -> InvWide;
  7365. Verb 'look' 'l//'
  7366.                 *                                -> Look
  7367.                 * 'at' noun                      -> Examine
  7368.                 * 'inside'/'in'/'into'/'through' noun
  7369.                                                  -> Search
  7370.                 * 'under' noun                   -> LookUnder
  7371.                 * 'up' topic 'in' noun           -> Consult;
  7372. Verb 'consult'  * noun 'about' topic             -> Consult
  7373.                 * noun 'on' topic                -> Consult;
  7374. Verb 'open' 'unwrap' 'uncover' 'undo'
  7375.                 * noun                           -> Open
  7376.                 * noun 'with' held               -> Unlock;
  7377. Verb 'close' 'shut' 'cover'
  7378.                 * noun                           -> Close
  7379.                 * 'up' noun                      -> Close
  7380.                 * 'off' noun                     -> SwitchOff;
  7381. Verb 'enter' 'cross'
  7382.                 *                                -> GoIn
  7383.                 * noun                           -> Enter;
  7384. Verb 'sit' 'lie'
  7385.                 * 'on' 'top' 'of' noun           -> Enter
  7386.                 * 'on'/'in'/'inside' noun        -> Enter;
  7387. Verb 'in' 'inside'
  7388.                 *                                -> GoIn;
  7389. Verb 'exit' 'out' 'outside'
  7390.                 *                                -> Exit;
  7391. Verb 'examine' 'x//' 'watch' 'describe' 'check'
  7392.                 * noun                           -> Examine;
  7393. Verb 'read'
  7394.                 * noun                           -> Examine
  7395.                 * 'about' topic 'in' noun        -> Consult
  7396.                 * topic 'in' noun                -> Consult;
  7397. Verb 'yes' 'y//'
  7398.                 *                                -> Yes;
  7399. Verb 'no'
  7400.                 *                                -> No;
  7401. Verb 'sorry'
  7402.                 *                                -> Sorry;
  7403. Verb 'shit' 'fuck' 'damn' 'sod'
  7404.                 *                                -> Strong
  7405.                 * topic                          -> Strong;
  7406. Verb 'bother' 'curses' 'drat' 'darn'
  7407.                 *                                -> Mild
  7408.                 * topic                          -> Mild;
  7409. Verb 'search'
  7410.                 * noun                           -> Search;
  7411. Verb 'wave'
  7412.                 *                                -> WaveHands
  7413.                 * noun                           -> Wave;
  7414. Verb 'set' 'adjust'
  7415.                 * noun                           -> Set
  7416.                 * noun 'to' special              -> SetTo;
  7417. Verb 'pull' 'drag'
  7418.                 * noun                           -> Pull;
  7419. Verb 'push' 'move' 'shift' 'clear' 'press'
  7420.                 * noun                           -> Push
  7421.                 * noun noun                      -> PushDir
  7422.                 * noun 'to' noun                 -> Transfer;
  7423. Verb 'turn' 'rotate' 'twist' 'unscrew' 'screw'
  7424.                 * noun                           -> Turn
  7425.                 * noun 'on'                      -> Switchon
  7426.                 * noun 'off'                     -> Switchoff
  7427.                 * 'on' noun                      -> Switchon
  7428.                 * 'off' noun                     -> Switchoff;
  7429. Verb 'switch'
  7430.                 * noun                           -> Switchon
  7431.                 * noun 'on'                      -> Switchon
  7432.                 * noun 'off'                     -> Switchoff
  7433.                 * 'on' noun                      -> Switchon
  7434.                 * 'off' noun                     -> Switchoff;
  7435. Verb 'lock'
  7436.                 * noun 'with' held               -> Lock;
  7437. Verb 'unlock'
  7438.                 * noun 'with' held               -> Unlock;
  7439. Verb 'attack' 'break' 'smash' 'hit' 'fight' 'wreck' 'crack'
  7440.      'destroy' 'murder' 'kill' 'torture' 'punch' 'thump'
  7441.                 * noun                           -> Attack;
  7442. Verb 'wait' 'z//'
  7443.                 *                                -> Wait;
  7444. Verb 'answer' 'say' 'shout' 'speak'
  7445.                 * topic 'to' creature            -> Answer;
  7446. Verb 'tell'
  7447.                 * creature 'about' topic         -> Tell;
  7448. Verb 'ask'
  7449.                 * creature 'about' topic         -> Ask
  7450.                 * creature 'for' noun            -> AskFor;
  7451. Verb 'eat'
  7452.                 * held                           -> Eat;
  7453. Verb 'sleep' 'nap'
  7454.                 *                                -> Sleep;
  7455. Verb 'peel'
  7456.                 * noun                           -> Take
  7457.                 * 'off' noun                     -> Take;
  7458. Verb 'sing'
  7459.                 *                                -> Sing;
  7460. Verb 'climb' 'scale'
  7461.                 * noun                           -> Climb
  7462.                 * 'up'/'over' noun               -> Climb;
  7463. Verb 'buy' 'purchase'
  7464.                 * noun                           -> Buy;
  7465. Verb 'squeeze' 'squash'
  7466.                 * noun                           -> Squeeze;
  7467. Verb 'swim' 'dive'
  7468.                 *                                -> Swim;
  7469. Verb 'swing'
  7470.                 * noun                           -> Swing
  7471.                 * 'on' noun                      -> Swing;
  7472. Verb 'blow'
  7473.                 * held                           -> Blow;
  7474. Verb 'pray'
  7475.                 *                                -> Pray;
  7476. Verb 'wake' 'awake' 'awaken'
  7477.                 *                                -> Wake
  7478.                 * 'up'                           -> Wake
  7479.                 * creature                       -> WakeOther
  7480.                 * creature 'up'                  -> WakeOther
  7481.                 * 'up' creature                  -> WakeOther;
  7482. Verb 'kiss' 'embrace' 'hug'
  7483.                 * creature                       -> Kiss;
  7484. Verb 'think'
  7485.                 *                                -> Think;
  7486. Verb 'smell' 'sniff'
  7487.                 *                                -> Smell
  7488.                 * noun                           -> Smell;
  7489. Verb 'hear' 'listen'
  7490.                 *                                -> Listen
  7491.                 * noun                           -> Listen
  7492.                 * 'to' noun                      -> Listen;
  7493. Verb 'taste'
  7494.                 * noun                           -> Taste;
  7495. Verb 'touch' 'fondle' 'feel' 'grope'
  7496.                 * noun                           -> Touch;
  7497. Verb 'rub' 'shine' 'polish' 'sweep' 'clean' 'dust' 'wipe' 'scrub'
  7498.                 * noun                           -> Rub;
  7499. Verb 'tie' 'attach' 'fasten' 'fix'
  7500.                 * noun                           -> Tie
  7501.                 * noun 'to' noun                 -> Tie;
  7502. Verb 'burn' 'light'
  7503.                 * noun                           -> Burn
  7504.                 * noun 'with' held               -> Burn;
  7505. Verb 'drink' 'swallow' 'sip'
  7506.                 * noun                           -> Drink;
  7507. Verb 'fill'
  7508.                 * noun                           -> Fill;
  7509. Verb 'cut' 'slice' 'prune' 'chop'
  7510.                 * noun                           -> Cut;
  7511. Verb 'jump' 'skip' 'hop'
  7512.                 *                                -> Jump
  7513.                 * 'over' noun                    -> JumpOver;
  7514. Verb 'dig'      * noun                           -> Dig
  7515.                 * noun 'with' held               -> Dig;
  7516. ! ----------------------------------------------------------------------------
  7517. !  This routine is no longer used here, but provided to help existing games
  7518. !  which use it as a general parsing routine:
  7519. [ ConTopic w; consult_from = wn;
  7520.   do w=NextWordStopped();
  7521.   until (w==-1 || (w=='to' && action_to_be==##Answer));
  7522.   wn--;
  7523.   consult_words = wn-consult_from;
  7524.   if (consult_words==0) return -1;
  7525.   if (action_to_be==##Ask or ##Answer or ##Tell)
  7526.   {   w=wn; wn=consult_from; parsed_number=NextWord();
  7527.       if (parsed_number=='the' && consult_words>1) parsed_number=NextWord();
  7528.       wn=w; return 1;
  7529.   return 0;
  7530. ! ----------------------------------------------------------------------------
  7531. !  Final task: provide trivial routines if the user hasn't already:
  7532. ! ----------------------------------------------------------------------------
  7533. #Stub TimePasses      0;
  7534. #Stub Amusing         0;
  7535. #Stub DeathMessage    0;
  7536. #Stub DarkToDark      0;
  7537. #Stub NewRoom         0;
  7538. #Stub LookRoutine     0;
  7539. #Stub AfterLife       0;
  7540. #Stub GamePreRoutine  0;
  7541. #Stub GamePostRoutine 0;
  7542. #Stub AfterPrompt     0;
  7543. #Stub BeforeParsing   0;
  7544. #Stub PrintTaskName   1;
  7545. #Stub InScope         1;
  7546. #Stub UnknownVerb     1;
  7547. #Stub PrintVerb       1;
  7548. #Stub ParserError     1;
  7549. #Stub ParseNumber     2;
  7550. #Stub ChooseObjects   2;
  7551. #IFNDEF PrintRank;
  7552. Constant Make__PR;
  7553. #ENDIF;
  7554. #IFDEF Make__PR;
  7555. [ PrintRank; "."; ];
  7556. #ENDIF;
  7557. #IFNDEF ParseNoun;
  7558. Constant Make__PN;
  7559. #ENDIF;
  7560. #IFDEF Make__PN;
  7561. [ ParseNoun obj; obj=obj; return -1; ];
  7562. #ENDIF;
  7563. #Default Story 0;
  7564. #Default Headline 0;
  7565. #IFDEF INFIX;
  7566. #Include "infix";
  7567. #ENDIF;
  7568. ! ----------------------------------------------------------------------------
  7569. ! ----------------------------------------------------------------------------
  7570. !  PARSER:  Front end to parser.
  7571. !  Supplied for use with Inform 6
  7572. !  (c) Graham Nelson 1993, 1994, 1995, 1996, 1997, 1998, 1999
  7573. !      but freely usable (see manuals)
  7574. ! ----------------------------------------------------------------------------
  7575. System_file;
  7576. IFDEF INFIX; IFNDEF DEBUG; Constant DEBUG; ENDIF; ENDIF;
  7577. IFDEF STRICT_MODE; IFNDEF DEBUG; Constant DEBUG; ENDIF; ENDIF;
  7578. Constant LibSerial  = "990428";
  7579. Constant LibRelease = "6/9";
  7580. Constant Grammar__Version = 2;
  7581. IFNDEF VN_1610;
  7582. Message fatalerror "*** Library 6/9 needs Inform v6.10 or later to work ***";
  7583. ENDIF;
  7584. Include "linklpa";
  7585. Fake_Action LetGo;
  7586. Fake_Action Receive;
  7587. Fake_Action ThrownAt;
  7588. Fake_Action Order;
  7589. Fake_Action TheSame;
  7590. Fake_Action PluralFound;
  7591. Fake_Action ListMiscellany;
  7592. Fake_Action Miscellany;
  7593. Fake_Action Prompt;
  7594. Fake_Action NotUnderstood;
  7595. IFDEF NO_PLACES;
  7596. Fake_Action Places;
  7597. Fake_Action Objects;
  7598. ENDIF;
  7599. [ Main; InformLibrary.play(); ];
  7600. IFDEF USE_MODULES;
  7601. Link "parserm";
  7602. IFNOT;
  7603. Include "parserm";
  7604. ENDIF;
  7605. Times New Roman
  7606. &Heading 1L
  7607. Times New Roman
  7608. &Heading 2L
  7609. Times New Roman
  7610. &Heading 3L
  7611. OutputO
  7612. Courier New
  7613. SBecause of the way the Epoc console is implemented, and the way output is currently handled by this port,  it is tricky to read the help text produced by inform. Here it is:
  7614. Epoc Inform 6.21 (30th April 1999)
  7615. his program is a compiler of Infocom format (also called "Z-machine")
  7616. story files: copyright (c) Graham Nelson 1993, 1994, 1995, 1996, 1997, 1998.
  7617. Usage: "inform [commands...] <file1> [<file2>]"
  7618. <file1> is the Inform source file of the game to be compiled. <file2>,
  7619. if given, overrides the filename Inform would normally use for the
  7620. compiled output.  Try "inform -h1" for file-naming conventions.
  7621. One or more words can be supplied as "commands". These may be:
  7622.   -switches     a list of compiler switches, 1 or 2 letter
  7623.                 (see "inform -h2" for the full range)
  7624.   +dir          set Include_Path to this directory
  7625.   +PATH=dir     change the PATH to this directory
  7626.   $...          one of the following memory commands:
  7627.      $list            list current memory allocation settings
  7628.      $huge            make standard "huge game" settings (default)
  7629.      $large           make standard "large game" settings
  7630.      $small           make standard "small game" settings
  7631.      $?SETTING        explain briefly what SETTING is for
  7632.      $SETTING=number  change SETTING to given number
  7633.   (filename)    read in a list of commands (in the format above)
  7634.                 from this "setup file"
  7635. For example: "inform -dexs $huge curses".
  7636. For fuller information, see the Inform Designer's Manual.
  7637. [No compilation requested]
  7638. Here is the output of running "inform -h2":
  7639. Epoc Inform 6.21 (30th April 1999)
  7640. This program is a compiler of Infocom format (also called "Z-machine")
  7641. story files: copyright (c) Graham Nelson 1993, 1994, 1995, 1996, 1997, 1998.
  7642. Help on the full list of legal switch commands:
  7643.   a   trace assembly-language (without hex dumps; see -t)
  7644.   c   more concise error messages
  7645.   d   contract double spaces after full stops in text
  7646.   d2  contract double spaces after exclamation and question marks, too
  7647.   e   economy mode (slower): make use of declared abbreviations
  7648.   f   frequencies mode: show how useful abbreviations are
  7649.   g   traces calls to functions (except in the library)
  7650.   g2  traces calls to all functions
  7651.   h   print this information
  7652.   i   ignore default switches set within the file
  7653.   j   list objects as constructed
  7654.   k   output Infix debugging information to "gameinfo.dbg" (and switch -D on)
  7655.   l   list every statement run through Inform
  7656.   m   say how much memory has been allocated
  7657.   n   print numbers of properties, attributes and actions
  7658.   o   print offset addresses
  7659.   p   give percentage breakdown of story file
  7660.   q   keep quiet about obsolete usages
  7661.   r   record all the text to "gametext.txt"
  7662.   s   give statistics
  7663.   t   trace assembly-language (with full hex dumps; see -a)
  7664.   u   work out most useful abbreviations (very very slowly)
  7665.   v3  compile to version-3 ("Standard") story file
  7666.   v4  compile to version-4 ("Plus") story file
  7667.   v5  compile to version-5 ("Advanced") story file: the default
  7668.   v6  compile to version-6 (graphical) story file
  7669.   v8  compile to version-8 (expanded "Advanced") story file
  7670.   w   disable warning messages
  7671.   x   print # for every 100 lines compiled
  7672.   y   trace linking system
  7673.   z   print memory map of the Z-machine
  7674.   C0  text character set is plain ASCII only
  7675.   Cn  text character set is ISO 8859-n (n = 1 to 9)
  7676.       (1 to 4, Latin1 to Latin4; 5, Cyrillic; 6, Arabic;
  7677.        7, Greek; 8, Hebrew; 9, Latin5.  Default is -C1.)
  7678.   D   insert "Constant DEBUG;" automatically
  7679.   E0  Archimedes-style error messages
  7680.   E1  Microsoft-style error messages (current setting)
  7681.   E2  Macintosh MPW-style error messages
  7682.   F1  use temporary files to reduce memory consumption
  7683.   L   log all console messages to message log file messages.txt
  7684.   M   compile as a Module for future linking
  7685.   S   compile strict error-checking at run-time (on by default)
  7686.   U   insert "Constant USE_MODULES;" automatically
  7687.   X   compile with INFIX debugging facilities present
  7688. [No compilation requested]
  7689. And finally, for the completists in the audience, here is the result of running "inform $list"
  7690. Epoc Inform 6.21 (30th April 1999)
  7691. +--------------------------------------+
  7692. |             Memory setting = Value   |
  7693. +--------------------------------------+
  7694. |                MAX_ABBREVS = 64      |
  7695. |                MAX_ACTIONS = 200     |
  7696. |             MAX_ADJECTIVES = 50      |
  7697. |                MAX_CLASSES = 64      |
  7698. |       MAX_CLASS_TABLE_SIZE = 1000    |
  7699. |           MAX_DICT_ENTRIES = 2000    |
  7700. |       MAX_EXPRESSION_NODES = 100     |
  7701. |              HASH_TAB_SIZE = 512     |
  7702. |  MAX_INDIV_PROP_TABLE_SIZE = 15000   |
  7703. |                 MAX_LABELS = 1000    |
  7704. |              MAX_LINESPACE = 16000   |
  7705. |         MAX_LINK_DATA_SIZE = 2000    |
  7706. |            MAX_LOW_STRINGS = 2048    |
  7707. |                MAX_OBJECTS = 640     |
  7708. |        MAX_PROP_TABLE_SIZE = 30000   |
  7709. |             MAX_QTEXT_SIZE = 4000    |
  7710. |                MAX_SYMBOLS = 10000   |
  7711. |            MAX_STATIC_DATA = 10000   |
  7712. |         MAX_STATIC_STRINGS = 8000    |
  7713. |         SYMBOLS_CHUNK_SIZE = 5000    |
  7714. |        MAX_TRANSCRIPT_SIZE = 200000  |
  7715. |                  MAX_VERBS = 200     |
  7716. |              MAX_VERBSPACE = 4096    |
  7717. |             MAX_ZCODE_SIZE = 20000   |
  7718. +--------------------------------------+
  7719. [No compilation requested]
  7720. "Word.app
  7721. Times New Roman
  7722. &Heading 1L
  7723. Times New Roman
  7724. &Heading 2L
  7725. Times New Roman
  7726. &Heading 3L
  7727. CodeO
  7728. Courier New
  7729. BNotes on this port of Inform
  7730. Storage Requirements:
  7731. The inform library and compiler will require just under 700K. In addition, the compiler itself will require about 1M of storage on drive C while it is running. You will also need storage for your inform source files and the Z-code output, of course.
  7732. The command line
  7733. The only way to pass command line arguments to an EXE under Epoc is to use the command line shell "eshell". Unfortunately the Epoc shell appears to map the entire command line up uppercase. This makes it difficult to pass some parameters to inform (such as -x). While you could put the switches in your inform source a better solution is to place create an icl commands file and run inform with the name of this file:
  7734. inform (c:\inf\cmds.icl)
  7735. You will have to provide the full path to the icl file. You must also provide full paths for any other filenames you use. If inform fails to locate any files, or if any of your output files appear to be missing check that you have used fully qualified path names. Missing output files might be lurking in \System\Programs on the drive you installed inform to. This is caused by the command line shell not setting the working directory for inform.
  7736. New options to Inform
  7737. This port adds one new switch and one new path to Inform. The console used in this port does not provide any mechanism for capturing what is printed. This means that if there is more than a single screenful of messages printed during a run of inform there is no way to examine the old text. In an attempt to fix this two new elements have been added to ICL which allow everything printed to the console to be logged:
  7738. The switch -L causes all text written to the console to be logged in a text file. The default name for this file is "messages.txt"
  7739. The path "Messages_Name" can be set to a filename to be used as the log.
  7740. So, to place the inform help messages in the file "C:\Documents\Inform.txt" use the command line
  7741. inform +messages_name=c:\documents\inform.txt -L -h
  7742. Installation locations
  7743. Most of the package is installed to the \Inform directory on the chosen drive. The main inform binary, however, is installed to \System\Programs on the same drive. Installing to \System\Programs allows eshell to locate the inform executable without having to provide a complete path. Your own sources can go anywhere, of course.
  7744. Invoking Eshell
  7745. Eshell is Symbians command line environment for Epoc. It is not a standard feature of Epoc, but it is useful for running ports which have not been given a native GUI (like Inform). You will have to obtain a copy (for instance, from the symbian website at http://www.symbian.com). You can start it from system once you have installed it. If you would rather have an icon on the extras bar for it, then you could make a small OPL program to start it up - this minimal OPL program will do it:
  7746. INCLUDE "System.oxh"
  7747. APP EShell, &20000000
  7748. PROC Main:
  7749.   RunExe:("c:\inform\eshell.exe")
  7750. Enter this into program and compile it and an icon for eshell will be added to the extras bar. A couple of points to note about this program:
  7751. It uses a development UID (&20000000). UIDs in the range 0x01000000 to 0x0fffffff are reserved for development work and should not be used for software being distributed - Symbian allocate UIDs for all applications.
  7752. The path to eshell depends on where you installed it, obviously.
  7753. This application uses the default "question mark" icon. Consult the OPL programming manual if you want to add a fancy icon.
  7754. Known issues
  7755. The user interface could be a more Eikon-ish (it could hardly be less eikon-ish).
  7756. Release History
  7757. 1999/07/08: Version 1.00: Initial release (labelled Alpha)
  7758. 1999/08/10: Version 1.01:
  7759. Reapplied the veneer.c patch properly (d'oh) and rewrote the readme in line with comments received.
  7760. 1999/09/14:
  7761. Version 1.02: Added a new switch and a new path to inform to enable logging of everything output to the console.
  7762. End notes and copyrights
  7763. Inform and the Inform Library was written by, and is the copyright of, Graham Nelson. 
  7764.  1994-1999.
  7765. The original is available from http://www.gnelson.demon.co.uk/.
  7766. This version of Inform 6.21 was compiled by Glenn Strong <Glenn.Strong@cs.tcd.ie> and is available from http://www.cs.tcd.ie/Glenn.Strong/epoc/
  7767. Courier New
  7768. Swiss
  7769. "Word.app
  7770. A 'string' array can have at most 256 entries
  7771. MAX_STATIC_DATA
  7772. Entries in byte arrays and strings must be known constants
  7773. Entry in '->' or 'string' array not in range 0 to 255
  7774. new array name
  7775. new global variable name
  7776. Variable must be defined before use:
  7777. MAX_ARRAYS
  7778. All 233 global variables already declared
  7779. array definition
  7780. more modern to use 'Array', not 'Global'
  7781. '->', '-->', 'string' or 'table'
  7782. '=', '->', '-->', 'string' or 'table'
  7783. No array size or initial values given
  7784. use '->' instead of 'data'
  7785. use '->' instead of 'initial'
  7786. use '->' instead of 'initstr'
  7787. Array sizes must be known now, not externally defined
  7788. An array must have between 1 and 32767 entries
  7789. Missing ';' to end the initial array values before "[" or "]"
  7790. literal text in double-quotes
  7791. error
  7792. static data
  7793. array sizes
  7794. array types
  7795. array symbols
  7796. global values
  7797. MAX_LABELS
  7798. TEMP1
  7799. TEMP2
  7800. TEMP3
  7801. TEMP4
  7802. sender
  7803. sw__var
  7804. expr_
  7805. long_
  7806. short_
  7807. <no value>
  7808. MAX_ZCODE_SIZE
  7809. picture_table
  7810. make_menu
  7811. print_form
  7812. put_wind_prop
  7813. push_stack
  7814. mouse_window
  7815. read_mouse
  7816. pop_stack
  7817. scroll_window
  7818. get_wind_prop
  7819. window_style
  7820. window_size
  7821. move_window
  7822. set_margins
  7823. erase_picture
  7824. picture_data
  7825. draw_picture
  7826. restore_undo
  7827. save_undo
  7828. set_font
  7829. art_shift
  7830. log_shift
  7831. piracy
  7832. catch
  7833. call_1n
  7834. check_arg_count
  7835. print_table
  7836. copy_table
  7837. encode_text
  7838. tokenise
  7839. call_vn2
  7840. call_vn
  7841. throw
  7842. set_colour
  7843. call_2n
  7844. call_1s
  7845. scan_table
  7846. read_char
  7847. buffer_mode
  7848. set_text_style
  7849. get_cursor
  7850. set_cursor
  7851. erase_line
  7852. erase_window
  7853. call_vs2
  7854. call_vs
  7855. call_2s
  7856. verify
  7857. show_status
  7858. new_line
  7859. ret_popped
  7860. restart
  7861. restore
  7862. print_ret
  7863. print
  7864. rfalse
  7865. rtrue
  7866. print_paddr
  7867. print_obj
  7868. remove_obj
  7869. print_addr
  7870. get_prop_len
  7871. get_parent
  7872. get_child
  7873. get_sibling
  7874. sound_effect
  7875. input_stream
  7876. output_stream
  7877. set_window
  7878. split_window
  7879. random
  7880. print_num
  7881. print_char
  7882. put_prop
  7883. storeb
  7884. storew
  7885. get_next_prop
  7886. get_prop_addr
  7887. get_prop
  7888. loadb
  7889. loadw
  7890. insert_obj
  7891. store
  7892. clear_attr
  7893. set_attr
  7894. test_attr
  7895. inc_chk
  7896. dec_chk
  7897. invalid
  7898.  <operand>
  7899.  <operand1> <operand2>
  7900.  <0 to 4 operands>
  7901.  <0 to 8 operands>
  7902.  <text>
  7903.  <label>
  7904.  <variable>
  7905.  <routine>
  7906.  <1 to 4 operands>
  7907.  <1 to 8 operands>
  7908.  -> <result-variable>
  7909.  ?[~]<label>
  7910. Opcode unavailable in this Z-machine version
  7911. This statement can never be reached
  7912. %5d  +%05lx %3s %-12s 
  7913. FALSE
  7914. rtrue if %s
  7915. rfalse if %s
  7916. (no branch)
  7917. to L%d if %s
  7918.                                
  7919. %02x 
  7920. Assembly mistake: syntax is
  7921. %5d  +%05lx    .L%d
  7922. %5d  +%05lx  [ %s 
  7923. [ %s(
  7924. %s%s = 
  7925. Local variable
  7926. Routine contains no such label as
  7927. Label
  7928. Backpatching routine at %05lx: initial size %d, %d labels
  7929. Branch detected at offset %04x
  7930. To label %d, which is %d from here
  7931. Short form
  7932. Opening label: %d
  7933. Label %d offset %04x next -> %d previous -> %d
  7934. Position of L%d corrected from %04x to %04x
  7935. Label out of range for branch
  7936. Addr is %04x
  7937. Illegal code backpatch value
  7938. Illegal value of %02x at PC = %04x
  7939. After branch optimisation, routine length is %d bytes
  7940. expression
  7941. variable or constant
  7942. Opcode specification should have form "VAR:102"
  7943. VAR_LONG
  7944. EXT_LONG
  7945. Expected 0OP, 1OP, 2OP, VAR, EXT, VAR_LONG or EXT_LONG
  7946. %d to %d
  7947. For this operand type, opcode number must be in range
  7948. Unknown flag: options are B (branch), S (store), T (text), I (indirect addressing), F** (set this Flags 2 bit)
  7949. an opcode name
  7950. literal text in double-quotes
  7951. semicolon ';' after print string
  7952. Only one '->' store destination can be given
  7953. variable name or 'sp'
  7954. Store '->' destination not 'sp' or a variable:
  7955. Only one '?' branch destination can be given
  7956. label name after '?' or '?~'
  7957. No assembly instruction may have more than 8 operands
  7958. This opcode does not use indirect addressing
  7959. Indirect addressing can only be used on the first operand
  7960. Opcode unavailable in this Z-machine version:
  7961. Store destination (the last operand) is not a variable
  7962. label offsets
  7963. label symbols
  7964. label dll 1
  7965. sequence point labels
  7966. sequence point refs
  7967. compiled routine code area
  7968. named routine symbols
  7969. label dll 2
  7970. compiled routine code markers
  7971. BP %s applied to %04x giving 
  7972. Backpatch veneer routine number out of range
  7973. Illegal BP veneer routine number: %d
  7974. Backpatch system constant number out of range
  7975. Illegal BP system constant number: %d
  7976. No 'Main' routine has been defined
  7977. Backpatch symbol number out of range
  7978. Illegal BP symbol number: %d
  7979. No such constant as
  7980. Illegal backpatch marker attached to symbol
  7981. Illegal backpatch marker
  7982. Illegal backpatch marker %d value %04x
  7983.  %04x
  7984. Illegal area to backpatch
  7985. *** MV %d ZA %d Off %04x ***
  7986. :a:o:u:A:O:Uss>><<:e:i:y:E:I'a'e'i'o'u'y'A'E'I'O'U'Y`a`e`i`o`u`A`E`I`O`U^a^e^i^o^u^A^E^I^O^UoaoA/o/O~a~n~o~A~N~OaeAEcccCthetThEtLLoeOE!!??
  7987. Character must first be entered into Zcharacter table:
  7988. Character can't be used in alphabets unless entered into Zcharacter table
  7989. Alphabet string must give exactly 23 characters
  7990. Alphabet string must give exactly 26 characters
  7991. Character duplicated in alphabet:
  7992. Attempted to map a Unicode character into the ZSCII set at an illegal position
  7993. No more room in the Zcharacter table
  7994. '@' plus an accent code or '@{...}'
  7995. No such accented character as
  7996. '@{' without matching '}'
  7997. At most four hexadecimal digits allowed in '@{...}'
  7998. '@{...}' may only contain hexadecimal digits
  7999. @{%x}
  8000. Latin1
  8001. Latin2
  8002. Latin3
  8003. Latin4
  8004. Cyrillic
  8005. Arabic
  8006. Greek
  8007. Hebrew
  8008. Latin5
  8009. Plain ASCII
  8010. abcdefghijklmnopqrstuvwxyz
  8011. ABCDEFGHIJKLMNOPQRSTUVWXYZ
  8012.  ^0123456789.,!?_#'~/\-:()
  8013. All 64 abbreviations already declared
  8014. MAX_ABBREVS
  8015. All abbreviations must be declared together
  8016. abbreviation string
  8017. It's not worth abbreviating
  8018. new constant name
  8019. Grammar__Version must be given an explicit constant value
  8020. Once a fake action has been defined it is too late to change the grammar version. (If you are using the library, move any Fake_Action directives to a point after the inclusion of "Parser".)
  8021. 'Default' cannot be used in -M (Module) mode
  8022. use 'word' as a constant dictionary address
  8023. 'Endif' without matching 'If...'
  8024. symbol name
  8025. 'Ifnot' without matching 'If...'
  8026. Second 'Ifnot' for the same 'If...' condition
  8027. End of file reached in code 'If...'d out
  8028. This condition can't be determined
  8029. semicolon after 'If...' condition
  8030. 'Import' can only be used in -M (Module) mode
  8031. 'Import' cannot import things of this type:
  8032. filename in double-quotes
  8033. semicolon ';' after Include filename
  8034. language__
  8035. 'LowString' cannot be used in -M (Module) mode
  8036. new low string name
  8037. literal string in double-quotes
  8038. error message in double-quotes
  8039. fatal error message in double-quotes
  8040. warning message in double-quotes
  8041. a message in double-quotes, 'error', 'fatalerror' or 'warning'
  8042. A definite value must be given as release number
  8043. You can't 'Replace' a system function already used
  8044. name of routine to replace
  8045. name of routine not yet defined
  8046. The serial number must be a 6-digit date in double-quotes
  8047. This does not set the final game's statusline
  8048. 'score' or 'time' after 'statusline'
  8049. routine name to stub
  8050. number of local variables
  8051. Must specify 0 to 3 local variables for 'Stub' routine
  8052. dummy1
  8053. dummy2
  8054. dummy3
  8055. string of switches
  8056. A 'Switches' directive must must come before the first constant definition
  8057. debugging keyword
  8058. A definite value must be given as version number
  8059. The version number must be in the range 3 to 8
  8060. double-quoted alphabet string
  8061. single character value
  8062. character or Unicode number
  8063. ZSCII number
  8064. 'table', 'terminating', a string or a constant
  8065. three alphabet strings, a 'table' or 'terminating' command or a single character
  8066. "%s", 
  8067. line %d: 
  8068. (%d): 
  8069. File "%s"; Line %d    # 
  8070. Fatal error: %s
  8071. %s "%s"
  8072. Run out of memory allocating %d bytes for %s
  8073. Run out of memory allocating array of %dx%d bytes for %s
  8074. The memory setting %s (which is %ld at present) has been exceeded.  Try running Inform again with $%s=<some-larger-number> on the command line.
  8075. Error: 
  8076. Warning: 
  8077. Error:  [linking '%s']  
  8078. *** Compiler error: 
  8079.   ...etc
  8080. Too many errors: giving up
  8081. No such label as
  8082. Expected %s but found %s
  8083. %s (unicode) $%04x = (ISO %s) $%02x
  8084. %s (ISO Latin1) $%02x
  8085. , i.e., '%c'
  8086. %s (unicode) $%04x
  8087. %s "%s" declared but not used
  8088. Obsolete usage: %s
  8089. 30th April 1999
  8090. ***********************************************************************
  8091. * 'Compiler errors' should never occur if Inform is working properly. *
  8092. * This is version %d.%02d of Inform, dated %20s: so      *
  8093. * if that was more than six months ago, there may be a more recent    *
  8094. * version available, from which the problem may have been removed.    *
  8095. * If not, please report this fault to:   graham@gnelson.demon.co.uk   *
  8096. * and if at all possible, please include your source code, as faults  *
  8097. * such as these are rare and often difficult to reproduce.  Sorry.    *
  8098. ***********************************************************************
  8099. Too many compiler errors: giving up
  8100. <no text read yet>
  8101. errors buffer
  8102. call to individual property
  8103. call to common property
  8104. common property postdecrement
  8105. individual property postdecrement
  8106. word array entry postdecrement
  8107. byte array entry postdecrement
  8108. common property postincrement
  8109. individual property postincrement
  8110. word array entry postincrement
  8111. byte array entry postincrement
  8112. common property predecrement
  8113. individual property predecrement
  8114. word array entry predecrement
  8115. byte array entry predecrement
  8116. common property preincrement
  8117. individual property preincrement
  8118. word array entry preincrement
  8119. byte array entry preincrement
  8120. common property assignment
  8121. individual property assignment
  8122. word array entry assignment
  8123. byte array entry assignment
  8124. superclass operator '::'
  8125. property selector '.'
  8126. individual property selector '..'
  8127. function call
  8128. individual property length operator '..#'
  8129. individual property address operator '..&'
  8130. property length operator '.#'
  8131. property address operator '.&'
  8132. post-decrement operator '--'
  8133. pre-decrement operator '--'
  8134. post-increment operator '++'
  8135. pre-increment operator '++'
  8136. unary minus
  8137. word array operator '-->'
  8138. byte array operator '->'
  8139. bitwise NOT '~'
  8140. bitwise OR '|'
  8141. bitwise AND '&'
  8142. remainder after division '%'
  8143. negated 'provides' condition
  8144. negated 'ofclass' condition
  8145. 'provides' condition
  8146. 'ofclass' condition
  8147. 'notin' condition
  8148. 'in' condition
  8149. 'hasnt' condition
  8150. 'has' condition
  8151. '<' condition
  8152. '<=' condition
  8153. '>' condition
  8154. '>=' condition
  8155. '~=' condition
  8156. '==' condition
  8157. expression used as condition
  8158. expression used as condition then negated
  8159. logical negation '~~'
  8160. logical disjunction '||'
  8161. logical conjunction '&&'
  8162. assignment operator '='
  8163. comma
  8164. <constant>
  8165. print_paddr
  8166. ignoring 'print_paddr': use 'print (string)' instead
  8167. print_addr
  8168. ignoring 'print_addr': use 'print (address)' instead
  8169. print_char
  8170. ignoring 'print_char': use 'print (char)' instead
  8171. assignment or statement
  8172. Array size can't be found
  8173. 'has'/'hasnt' applied to illegal attribute number
  8174. Evaluating this has no effect:
  8175. Argument to system function missing
  8176. System function given with too many arguments
  8177. Only constants can be used as possible 'random' results
  8178. A function may be called with at most 3 arguments
  8179. A function may be called with at most 7 arguments
  8180. ** Trouble op = %d i.e. '%s' **
  8181. Expr code gen: Can't generate yet
  8182. Raw parse tree:
  8183. Code generation for expression in 
  8184. condition
  8185. quantity
  8186. assembly
  8187. array initialisation
  8188. * ILLEGAL *
  8189.  context with annotated tree:
  8190. Character can be printed but not used as a value:
  8191. Label name used as value:
  8192. Previous token type = %d
  8193. Previous token val  = %d
  8194. <call>
  8195. '#a$Act' is now superceded by '##Act'
  8196. '#n$word' is now superceded by ''word''
  8197. '#r$Routine' can now be written just 'Routine'
  8198. The obsolete '#w$word' construct has been removed
  8199. 'r$', 'n$' or internal Inform constant name after '#'
  8200. Without bracketing, the minus sign '-' is ambiguous
  8201. Discarding as not allowable: '%s' 
  8202. Discarding as no longer part: '%s' 
  8203. Expr token = '%s' 
  8204. Function call triggered
  8205. Output: %-19s%21s 
  8206.  FVALUE:
  8207.  ORVALUE:
  8208. No expression between brackets '(' and ')'
  8209. System function name used as a value:
  8210. MAX_EXPRESSION_NODES1
  8211. Emit token error:
  8212. FCALL_OP finds marker stack: 
  8213. Missing operand for
  8214. MAX_EXPRESSION_NODES2
  8215. Division of constant by zero
  8216. MAX_EXPRESSION_NODES3
  8217. i=%d, emitter_sp=%d, arity=%d, ETU=%d
  8218. MAX_EXPRESSION_NODES4
  8219. %d + %d = %d
  8220. %d - %d = %d
  8221. %d * %d = %d
  8222. Signed arithmetic on compile-time constants overflowed the range -32768 to +32767:
  8223. Folding constant to: 
  8224.  [%s]
  8225.  %d|%d 
  8226.  def %d after 
  8227.  con to expr 
  8228. Constant: 
  8229. '=' applied to undeclared variable
  8230. '=' applied to
  8231. MAX_EXPRESSION_NODES5
  8232. '=' used as condition: '==' intended?
  8233. MAX_EXPRESSION_NODES6
  8234. MAX_EXPRESSION_NODES7
  8235. expression
  8236. Input: %-20s
  8237. ET_used = %d
  8238. SR error: stack empty
  8239. SR error: emitter stack empty
  8240. SR error: emitter stack overfull
  8241. Tree before lvalue checking:
  8242. <expression>
  8243. constant
  8244. Brackets mandatory to clarify order of:
  8245. MAX_EXPRESSION_NODES8
  8246. 'or' not between values to the right of a condition
  8247. Missing operand after
  8248. Found '(' without matching ')'
  8249. Missing operator: inserting '+'
  8250. expression parse trees
  8251. emitter markers
  8252. emitter stack
  8253. shift-reduce parser stack
  8254. Program contains too many source files: increase #define MAX_SOURCE_FILES
  8255. Source files have unduly long file names: increase #define MAX_SOURCE_FILES
  8256. Couldn't open source file
  8257. Opening file "%s"
  8258. I/O failure: couldn't read from source file
  8259. Closing file
  8260. Couldn't open output file
  8261. I/O failure: couldn't reopen temporary file 2
  8262. short
  8263. *** %s  zcode offset=%08lx  backpatch offset=%08lx ***
  8264. I/O failure: couldn't read from temporary file 2
  8265. I/O failure: couldn't reopen temporary file 1
  8266. I/O failure: couldn't read from temporary file 1
  8267. I/O failure: couldn't reopen temporary file 3
  8268. I/O failure: couldn't read from temporary file 3
  8269. I/O failure: couldn't write to story file
  8270. I/O failure: couldn't backtrack on story file for checksum
  8271. Couldn't open message log file
  8272. Couldn't open transcript file
  8273. Transcript of the text of "%s"
  8274. [From %s]
  8275. [End of transcript: release %d.%s]
  8276. I/O failure: couldn't write to transcript file
  8277. Couldn't open debugging information file
  8278. I/O failure: can't write to debugging info file
  8279. Couldn't open temporary file 1
  8280. Couldn't open temporary file 2
  8281. Couldn't open temporary file 3
  8282. I/O failure: couldn't write to temporary file 1
  8283. I/O failure: couldn't write to temporary file 2
  8284. I/O failure: couldn't write to temporary file 3
  8285. filename storage
  8286. Class
  8287. Object
  8288. Routine
  8289. String
  8290. The character '%c' is used to divide entries in a list of possible locations, and can only be used in the Include_Path, Source_Path, Module_Path or ICL_Path variables. Other paths are for output only.
  8291. \system\temp
  8292. gameinfo.dbg
  8293. gametext.txt
  8294. English
  8295. messages.txt
  8296. source_path
  8297. include_path
  8298. code_path
  8299. module_path
  8300. icl_path
  8301. temporary_path
  8302. debugging_name
  8303. transcript_name
  8304. language_name
  8305. message_name
  8306. No such path setting as "%s"
  8307. (unset)
  8308. Help information on filenames:
  8309. The command line can take one of two forms:
  8310.   inform [commands...] <file1>
  8311.   inform [commands...] <file1> <file2>
  8312. Inform translates <file1> into a source file name (see below) for its input.
  8313. <file2> is usually omitted: if so, the output filename is made from <file1>
  8314. by cutting out the name part and translating that (see below).
  8315. If <file2> is given, however, the output filename is set to just <file2>
  8316. (not altered in any way).
  8317. Filenames given in the game source (with commands like Include "name" and
  8318. Link "name") are also translated by the rules below.
  8319. Rules of translation:
  8320. Inform translates plain filenames (such as "xyzzy") into full pathnames
  8321. (such as "adventure%cgames%cxyzzy") according to the following rules.
  8322. 1. If the name contains a '%c' character (so it's already a pathname), it
  8323.    isn't changed.
  8324.    [Exception: when the name is given in an Include command using the >
  8325.    form (such as Include ">prologue"), the ">" is replaced by the path
  8326.    of the file doing the inclusion
  8327.  and a suitable file extension is added
  8328.    Filenames must never contain double-quotation marks ".  To use filenames
  8329.    which contain spaces, write them in double-quotes: for instance,
  8330.    "inform +code_path="Jigsaw Final Version" jigsaw".
  8331. 2. The file is looked for at a particular "path" (the filename of a
  8332.    directory), depending on what kind of file it is.
  8333.        File type              Name                Current setting
  8334.        Source code (in)       source_path         %s
  8335.        Include file (in)      include_path        %s
  8336.        Story file (out)       code_path           %s
  8337.        Temporary file (out)   temporary_path      %s
  8338.        ICL command file (in)  icl_path            %s
  8339.        Module (in & out)      module_path         %s
  8340.    If the path is unset, then the current working directory is used (so
  8341.    the filename doesn't change): if, for instance, include_path is set to
  8342.    "backup%coldlib" then when "parser" is included it is looked for at
  8343.    "backup%coldlib%cparser".
  8344.    The paths can be set or unset on the Inform command line by, eg,
  8345.    "inform +code_path=finished jigsaw" or
  8346.    "inform +include_path= balances" (which unsets include_path).
  8347.    The four input path variables can be set to lists of alternative paths
  8348.    separated by '%c' characters: these alternatives are always tried in
  8349.    the order they are specified in, that is, left to right through the text
  8350.    in the path variable.
  8351.    (Modules are written to the first alternative in the module_path list;
  8352.    it is an error to give alternatives at all for purely output paths.)
  8353. 3. The following file extensions are added:
  8354.       Source code:     %s
  8355.       Include files:   %s
  8356.       Story files:     %s (Version 3), %s (v4), %s (v5, the default),
  8357.                        %s (v6), %s (v7), %s (v8)
  8358.       Temporary files: .tmp
  8359.       Modules:         %s
  8360.    except that any extension you give (on the command line or in a filename
  8361.    used in a program) will override these.  If you give the null extension
  8362.    "." then Inform uses no file extension at all (removing the ".").
  8363. Names of three individual files can also be set using the same
  8364.   + command notation (though they aren't really pathnames).  These are:
  8365.       transcript_name  (text written by -r switch): now "%s"
  8366.       debugging_name   (data written by -k switch): now "%s"
  8367.       language_name    (library file defining natural language of game):
  8368.                        now "%s"
  8369.       message_name     (text written by -M switch): now "%s"
  8370. rezrov
  8371. Examples: 1. "inform rezrov"
  8372.   the source code is read from "%s"
  8373.   and a story file is compiled to "%s".
  8374. frotz
  8375. 2. "inform -M frotz"
  8376.   the source code is read from "%s"
  8377.   and a module is compiled to "%s".
  8378. demos%cplugh
  8379. 3. "inform %s"
  8380.   the source code is read from "%s"
  8381. 4. "inform plover my_demo"
  8382. plover
  8383. my_demo
  8384. %cnew%cold%crecent%cold%cancient
  8385. 5. "inform +source_path=%s zooge"
  8386.    Note that four alternative paths are given, the first being the empty
  8387.    path-name (meaning: where you are now).  Inform looks for the source code
  8388.    by trying these four places in turn, stopping when it finds anything:
  8389. zooge
  8390.      "%s"
  8391. Inftemp
  8392. %s%s%d
  8393. Compiled with 
  8394. %d error%s
  8395.  and 
  8396. %d warning%s
  8397.  (%d suppressed)
  8398. %d suppressed warning%s
  8399.  (no output)
  8400. Completed in %ld seconds
  8401. Infix (-X) facilities are not available when compiling modules: disabling -X switch
  8402. Strict checking (-S) facilities are not available when compiling modules: disabling -S switch
  8403. transcription text
  8404. This program is a compiler of Infocom format (also called "Z-machine")
  8405. story files: copyright (c) Graham Nelson 1993, 1994, 1995, 1996, 1997, 1998.
  8406. Usage: "inform [commands...] <file1> [<file2>]"
  8407. <file1> is the Inform source file of the game to be compiled. <file2>,
  8408. if given, overrides the filename Inform would normally use for the
  8409. compiled output.  Try "inform -h1" for file-naming conventions.
  8410. One or more words can be supplied as "commands". These may be:
  8411.   -switches     a list of compiler switches, 1 or 2 letter
  8412.                 (see "inform -h2" for the full range)
  8413.   +dir          set Include_Path to this directory
  8414.   +PATH=dir     change the PATH to this directory
  8415.   $...          one of the following memory commands:
  8416. (default)
  8417.      $list            list current memory allocation settings
  8418.      $huge            make standard "huge game" settings %s
  8419.      $large           make standard "large game" settings %s
  8420.      $small           make standard "small game" settings %s
  8421.      $?SETTING        explain briefly what SETTING is for
  8422.      $SETTING=number  change SETTING to given number
  8423.   (filename)    read in a list of commands (in the format above)
  8424.                 from this "setup file"
  8425. For example: "inform -dexs $huge curses".
  8426. For fuller information, see the Inform Designer's Manual.
  8427. Help on the full list of legal switch commands:
  8428.   a   trace assembly-language (without hex dumps; see -t)
  8429.   c   more concise error messages
  8430.   d   contract double spaces after full stops in text
  8431.   d2  contract double spaces after exclamation and question marks, too
  8432.   e   economy mode (slower): make use of declared abbreviations
  8433.   f   frequencies mode: show how useful abbreviations are
  8434.   g   traces calls to functions (except in the library)
  8435.   g2  traces calls to all functions
  8436.   h   print this information
  8437.   i   ignore default switches set within the file
  8438.   j   list objects as constructed
  8439.   k   output Infix debugging information to "%s" (and switch -D on)
  8440.   l   list every statement run through Inform
  8441.   m   say how much memory has been allocated
  8442.   n   print numbers of properties, attributes and actions
  8443.   o   print offset addresses
  8444.   p   give percentage breakdown of story file
  8445.   q   keep quiet about obsolete usages
  8446.   r   record all the text to "%s"
  8447.   s   give statistics
  8448.   t   trace assembly-language (with full hex dumps; see -a)
  8449.   u   work out most useful abbreviations (very very slowly)
  8450.   v3  compile to version-3 ("Standard") story file
  8451.   v4  compile to version-4 ("Plus") story file
  8452.   v5  compile to version-5 ("Advanced") story file: the default
  8453.   v6  compile to version-6 (graphical) story file
  8454.   v8  compile to version-8 (expanded "Advanced") story file
  8455.   w   disable warning messages
  8456.   x   print # for every 100 lines compiled
  8457.   y   trace linking system
  8458.   z   print memory map of the Z-machine
  8459.   C0  text character set is plain ASCII only
  8460.   Cn  text character set is ISO 8859-n (n = 1 to 9)
  8461.       (1 to 4, Latin1 to Latin4; 5, Cyrillic; 6, Arabic;
  8462.        7, Greek; 8, Hebrew; 9, Latin5.  Default is -C1.)
  8463.   D   insert "Constant DEBUG;" automatically
  8464.  (current setting)
  8465.   E0  Archimedes-style error messages%s
  8466.   E1  Microsoft-style error messages%s
  8467.   E2  Macintosh MPW-style error messages%s
  8468.   F1  use temporary files to reduce memory consumption
  8469.   L   log all console messages to message log file %s
  8470.   M   compile as a Module for future linking
  8471.   S   compile strict error-checking at run-time (on by default)
  8472.   U   insert "Constant USE_MODULES;" automatically
  8473.   X   compile with INFIX debugging facilities present
  8474. Ignoring second word which should be a -list of switches.
  8475. The switch ~-k~ can't be set with ~Switches~
  8476. The switch ~-r~ can't be set with ~Switches~
  8477. -v must be followed by 3 to 8
  8478. -C must be followed by 0 to 9
  8479. Switch "-%c" unknown (try "inform -h2" for the list)
  8480. Error in ICL file '%s', line %d:
  8481. [Running ICL file '%s']
  8482. expected comment or nothing but found '%s'
  8483. compile
  8484. No filename given to 'compile'
  8485. [Compiling <%s>]
  8486. [Compiling <%s> to <%s>]
  8487. Expected comment or nothing but found '%s'
  8488. Expected command or comment but found '%s'
  8489. Error in ICL: Couldn't open command file '%s'
  8490.  Inform %d.%d%d (%s)
  8491. 30th April 1999
  8492. Command line error: unknown parameter '%s'
  8493. source
  8494. output
  8495. [No compilation requested]
  8496. [%d compilations completed]
  8497. symbol 
  8498. literal number %d
  8499. string "%s"
  8500. string '%s'
  8501. separator '%s'
  8502. end of file
  8503. statement name '%s'
  8504. object segment marker '%s'
  8505. directive name '%s'
  8506. textual conditional '%s'
  8507. opcode name '%s'
  8508. built-in function name '%s'
  8509. local variable name '%s'
  8510. statement keyword '%s'
  8511. directive keyword '%s'
  8512. 'trace' keyword '%s'
  8513. system constant name '%s'
  8514. operator '%s'
  8515. end of expression
  8516. open bracket
  8517. close bracket
  8518. large number: '%s'=%d
  8519. small number: '%s'=%d
  8520. variable '%s'=%d
  8521. dictionary word '%s'
  8522. action name '%s'
  8523. ** unknown token type %d, text='%s', value=%d **
  8524. picture_table
  8525. make_menu
  8526. print_form
  8527. put_wind_prop
  8528. push_stack
  8529. mouse_window
  8530. read_mouse
  8531. pop_stack
  8532. scroll_window
  8533. get_wind_prop
  8534. window_style
  8535. window_size
  8536. move_window
  8537. set_margins
  8538. erase_picture
  8539. picture_data
  8540. draw_picture
  8541. restore_undo
  8542. save_undo
  8543. set_font
  8544. art_shift
  8545. log_shift
  8546. piracy
  8547. catch
  8548. call_1n
  8549. check_arg_count
  8550. print_table
  8551. copy_table
  8552. encode_text
  8553. tokenise
  8554. call_vn2
  8555. call_vn
  8556. throw
  8557. set_colour
  8558. call_2n
  8559. call_1s
  8560. scan_table
  8561. read_char
  8562. buffer_mode
  8563. set_text_style
  8564. get_cursor
  8565. set_cursor
  8566. erase_line
  8567. erase_window
  8568. call_vs2
  8569. aread
  8570. call_vs
  8571. call_2s
  8572. verify
  8573. show_status
  8574. new_line
  8575. ret_popped
  8576. restart
  8577. restore
  8578. print_ret
  8579. print
  8580. rfalse
  8581. rtrue
  8582. print_paddr
  8583. print_obj
  8584. remove_obj
  8585. print_addr
  8586. get_prop_len
  8587. get_parent
  8588. get_child
  8589. get_sibling
  8590. sound_effect
  8591. input_stream
  8592. output_stream
  8593. set_window
  8594. split_window
  8595. random
  8596. print_num
  8597. print_char
  8598. sread
  8599. put_prop
  8600. storeb
  8601. storew
  8602. get_next_prop
  8603. get_prop_addr
  8604. get_prop
  8605. loadb
  8606. loadw
  8607. insert_obj
  8608. store
  8609. clear_attr
  8610. set_attr
  8611. test_attr
  8612. inc_chk
  8613. dec_chk
  8614. zcharacter
  8615. version
  8616. trace
  8617. system_file
  8618. statusline
  8619. switches
  8620. serial
  8621. replace
  8622. release
  8623. property
  8624. object
  8625. nearby
  8626. message
  8627. lowstring
  8628. include
  8629. import
  8630. iffalse
  8631. iftrue
  8632. ifnot
  8633. ifndef
  8634. ifdef
  8635. global
  8636. fake_action
  8637. extend
  8638. endif
  8639. dictionary
  8640. default
  8641. constant
  8642. class
  8643. attribute
  8644. array
  8645. abbreviate
  8646. linker
  8647. tokens
  8648. lines
  8649. expressions
  8650. assembly
  8651. verbs
  8652. objects
  8653. symbols
  8654. private
  8655. terminating
  8656. warning
  8657. fatalerror
  8658. error
  8659. initstr
  8660. initial
  8661. table
  8662. string
  8663. first
  8664. reverse
  8665. topic
  8666. scope
  8667. number
  8668. special
  8669. creature
  8670. multiinside
  8671. multiexcept
  8672. multiheld
  8673. multi
  8674. score
  8675. additive
  8676. alias
  8677. address
  8678. fixed
  8679. underline
  8680. roman
  8681. while
  8682. until
  8683. switch
  8684. style
  8685. spaces
  8686. return
  8687. remove
  8688. objectloop
  8689. inversion
  8690. continue
  8691. break
  8692. provides
  8693. ofclass
  8694. notin
  8695. hasnt
  8696. metaclass
  8697. youngest
  8698. younger
  8699. sibling
  8700. parent
  8701. indirect
  8702. eldest
  8703. elder
  8704. children
  8705. child
  8706. highest_object_number
  8707. lowest_object_number
  8708. class_objects_array
  8709. highest_class_number
  8710. lowest_class_number
  8711. constant_names_array
  8712. constants_array
  8713. highest_constant_number
  8714. lowest_constant_number
  8715. array_flags_array
  8716. array_names_array
  8717. arrays_array
  8718. highest_array_number
  8719. lowest_array_number
  8720. global_flags_array
  8721. global_names_array
  8722. globals_array
  8723. highest_global_number
  8724. lowest_global_number
  8725. routine_flags_array
  8726. routine_names_array
  8727. routines_array
  8728. highest_routine_number
  8729. lowest_routine_number
  8730. fake_action_names_array
  8731. highest_fake_action_number
  8732. lowest_fake_action_number
  8733. action_names_array
  8734. highest_action_number
  8735. lowest_action_number
  8736. property_names_array
  8737. highest_property_number
  8738. lowest_property_number
  8739. attribute_names_array
  8740. highest_attribute_number
  8741. lowest_attribute_number
  8742. array__end
  8743. array__start
  8744. ipv__end
  8745. ipv__start
  8746. cpv__end
  8747. cpv__start
  8748. readable_memory_offset
  8749. array_names_offset
  8750. static_memory_offset
  8751. actual_largest_object
  8752. dict_par3
  8753. dict_par2
  8754. dict_par1
  8755. code_offset
  8756. strings_offset
  8757. largest_object
  8758. version_number
  8759. preactions_table
  8760. identifiers_table
  8761. classes_table
  8762. actions_table
  8763. adjectives_table
  8764. SFUN 
  8765. SCON 
  8766. <no such local variable>
  8767. <before compilation>
  8768. <constructing output>
  8769. <veneer routine>
  8770. The lexical analyser has collapsed because of a wrong assumption inside Inform
  8771. Illegal character found in source:
  8772. <end of file>
  8773. Binary number expected after '$$'
  8774. Hexadecimal number expected after '$'
  8775. Too much text for one pair of quotations '...' to hold
  8776. No text between quotation marks ''
  8777. Too much text for one pair of quotations "..." to hold
  8778. empty rest of line after '\' in string
  8779. Name exceeds the maximum length of %d characters:
  8780. Unrecognised combination in source:
  8781. Character expected after
  8782. Alphabetic character expected after
  8783. '%s' 
  8784. (if this is ever visible, there is a bug)
  8785. <veneer routine '%s'>
  8786. source file buffer
  8787. lexeme memory
  8788. keyword hash table
  8789. keyword hash end table
  8790. keyword hashing linked list
  8791. local variable hash table
  8792. text of local variable names
  8793. dictionary word
  8794. string literal
  8795. system constant
  8796. routine
  8797. veneer routine
  8798. internal array
  8799. the number of objects
  8800. inherited common p value
  8801. indiv prop table address
  8802. inherited indiv p value
  8803. ref to Main
  8804. ref to symbol value
  8805. global variable
  8806. prop identifier number
  8807. action
  8808. internal object
  8809. Export   
  8810. Export sf
  8811. Export ##
  8812. Import   
  8813. ** No such MV **
  8814. %8s %20s %04d %04x %s
  8815. Marker value of %d
  8816. Link: illegal import/export marker value
  8817. action name clash with
  8818. program and module give differing values of
  8819. %s '%s' in both program and module
  8820. '%s' has type %s in program but type %s in module
  8821. Creating action ##%s
  8822. failed because too many extra global variables needed
  8823. Map %d '%s' to %d
  8824. module (wrongly) declared this a variable:
  8825. this attribute is undeclared within module:
  8826. this property is undeclared within module:
  8827. this was referred to as a constant, but isn't:
  8828. Module tried to import a Global variable not defined here:
  8829. unmapped action number
  8830. *** Link: unmapped action number %d ***
  8831. ** Unmapped variable %d! **
  8832. unmapped variable error
  8833. ** Symbol number %d cannot be crossreferenced **
  8834. symbol crossreference error
  8835. Backpatch %s area %d offset %04x size %d: 
  8836. %04x 
  8837. Couldn't open module file
  8838. File isn't a module:
  8839. module compiled as Version %d (so it can't link into this V%d game):
  8840. link module storage
  8841. module and game both define non-standard character sets, but they disagree
  8842. module and game use different character sets
  8843. module has a more advanced format than this release of the Inform 6 compiler knows about: it may not link in correctly
  8844. [Reading module map:
  8845. linker cross-references table
  8846. property identifier map
  8847. [Linking release %d.%c%c%c%c%c%c of module '%s' (size %dK)]
  8848. Merging module's dictionary at %04x
  8849. dictionary accession numbers map
  8850. %03d %04x  '%s' %02x %02x %02x
  8851. Import/export table is at byte offset %04x
  8852. Replaced routine addresses:
  8853. Replace code offset %04x with %04x
  8854. Symbol cross-references table:
  8855. module %4d -> story file '%s'
  8856. Action numbers map:
  8857. %3d -> %3d
  8858. Property identifier number map:
  8859. module %04x -> program %04x
  8860. Final variables map, Module -> Main:
  8861. %d->%d  
  8862. (set var %d to %d) 
  8863. MAX_STATIC_DATA
  8864. Inserting dynamic array area, %04x to %04x, at %04x
  8865. Inserting code area, %04x to %04x, at code offset %04x (+%04x)
  8866. Inserting strings area, %04x to %04x, at strings offset %04x (+%04x)
  8867. Joining on object tree of size %d
  8868. Module objects[%d] has %d,%d,%d
  8869. Objects[%d] has %d,%d,%d
  8870. Inserting object properties area, %04x to %04x, at +%04x
  8871. MAX_INDIV_PROP_TABLE_SIZE
  8872. Inserting individual prop tables area, %04x to %04x, at +%04x
  8873. Link complete
  8874. accession numbers map
  8875. MAX_LINK_DATA_SIZE
  8876. link data holding area
  8877. Allocating %ld bytes for %s at (%08lx)
  8878. Allocating %ld bytes: array (%ld entries size %ld) for %s at (%08lx)
  8879. Freeing memory for %s at (%08lx)
  8880. (unknown)
  8881. static strings area
  8882. Z-code area
  8883. link data area
  8884. Z-code backpatch table
  8885. Z-machine backpatch table
  8886. %s chunk %d
  8887. memory: read from unwritten byte in
  8888. memory: negative index to
  8889. One of the memory blocks has exceeded 640K
  8890. +--------------------------------------+
  8891. Value
  8892. Memory setting
  8893. |  %25s = %-7s |
  8894. MAX_ABBREVS
  8895. |  %25s = %-7d |
  8896. MAX_ACTIONS
  8897. MAX_ADJECTIVES
  8898. MAX_CLASSES
  8899. MAX_CLASS_TABLE_SIZE
  8900. MAX_DICT_ENTRIES
  8901. MAX_EXPRESSION_NODES
  8902. HASH_TAB_SIZE
  8903. MAX_INDIV_PROP_TABLE_SIZE
  8904. MAX_LABELS
  8905. MAX_LINESPACE
  8906. MAX_LINK_DATA_SIZE
  8907. MAX_LOW_STRINGS
  8908. MAX_OBJECTS
  8909. MAX_PROP_TABLE_SIZE
  8910. MAX_QTEXT_SIZE
  8911. MAX_SYMBOLS
  8912. MAX_STATIC_DATA
  8913. MAX_STATIC_STRINGS
  8914. |  %25s = %-7ld |
  8915. SYMBOLS_CHUNK_SIZE
  8916. MAX_TRANSCRIPT_SIZE
  8917. MAX_VERBS
  8918. MAX_VERBSPACE
  8919. MAX_ZCODE_SIZE
  8920.   MAX_QTEXT_SIZE is the maximum length of a quoted string.  Increasing
  8921.    by 1 costs 5 bytes (for lexical analysis memory).  Inform automatically
  8922.    ensures that MAX_STATIC_STRINGS is at least twice the size of this.
  8923.   MAX_SYMBOLS is the maximum number of symbols - names of variables, 
  8924.   objects, routines, the many internal Inform-generated names and so on.
  8925.   The symbols names are stored in memory which is allocated in chunks 
  8926.   of size SYMBOLS_CHUNK_SIZE.
  8927.   HASH_TAB_SIZE is the size of the hash tables used for the heaviest 
  8928.   symbols banks.
  8929.   MAX_OBJECTS is the maximum number of objects.  (If compiling a version-3 
  8930.   game, 255 is an absolute maximum in any event.)
  8931.   MAX_ACTIONS is the maximum number of actions - that is, routines such as 
  8932.   TakeSub which are referenced in the grammar table.
  8933.   MAX_ADJECTIVES is the maximum number of different "adjectives" in the 
  8934.   grammar table.  Adjectives are misleadingly named: they are words such as 
  8935.   "in", "under" and the like.
  8936.   MAX_DICT_ENTRIES is the maximum number of words which can be entered 
  8937.   into the game's dictionary.  It costs 29 bytes to increase this by one.
  8938.   MAX_STATIC_DATA is the size of an array of integers holding initial 
  8939.   values for arrays and strings stored as ASCII inside the Z-machine.  It 
  8940.   should be at least 1024 but seldom needs much more.
  8941.   MAX_PROP_TABLE_SIZE is the number of bytes allocated to hold the 
  8942.   properties table.
  8943.   MAX_ABBREVS is the maximum number of declared abbreviations.  It is not 
  8944.   allowed to exceed 64.
  8945. MAX_ARRAYS
  8946.   MAX_ARRAYS is the maximum number of declared arrays.
  8947.   MAX_EXPRESSION_NODES is the maximum number of nodes in the expression 
  8948.   evaluator's storage for parse trees.  In effect, it measures how 
  8949.   complicated algebraic expressions are allowed to be.  Increasing it by 
  8950.   one costs about 80 bytes.
  8951.   MAX_VERBS is the maximum number of verbs (such as "take") which can be 
  8952.   defined, each with its own grammar.  To increase it by one costs about
  8953.   128 bytes.  A full game will contain at least 100.
  8954.   MAX_VERBSPACE is the size of workspace used to store verb words, so may
  8955.   need increasing in games with many synonyms: unlikely to exceed 4K.
  8956.   MAX_LABELS is the maximum number of label points in any one routine.
  8957.   (If the -k debugging information switch is set, MAX_LABELS is raised to
  8958.   a minimum level of 2000, as about twice the normal number of label points
  8959.   are needed to generate tables of how source code corresponds to positions
  8960.   in compiled code.)
  8961.   MAX_LINESPACE is the size of workspace used to store grammar lines, so 
  8962.   may need increasing in games with complex or extensive grammars.
  8963.   MAX_STATIC_STRINGS is the size in bytes of a buffer to hold compiled
  8964.   strings before they're written into longer-term storage.  2000 bytes is 
  8965.   plenty, allowing string constants of up to about 3000 characters long.
  8966.   Inform automatically ensures that this is at least twice the size of
  8967.   MAX_QTEXT_SIZE, to be on the safe side.
  8968.   MAX_ZCODE_SIZE is the size in bytes of a buffer to hold compiled 
  8969.   Z-machine code for a single routine.  As a guide, the longest library 
  8970.   routine is about 6500 bytes long.
  8971.   MAX_LINK_DATA_SIZE is the size in bytes of a buffer to hold module 
  8972.   link data before it's written into longer-term storage.  2000 bytes 
  8973.   is plenty.
  8974.   MAX_LOW_STRINGS is the size in bytes of a buffer to hold all the 
  8975.   compiled "low strings" which are to be written above the synonyms table 
  8976.   in the Z-machine.  1024 is plenty.
  8977.   MAX_TRANSCRIPT_SIZE is only allocated for the abbreviations optimisation 
  8978.   switch, and has the size in bytes of a buffer to hold the entire text of
  8979.   the game being compiled: it has to be enormous, say 100000 to 200000.
  8980.   MAX_CLASSES maximum number of object classes which can be defined.  This
  8981.   is cheap to increase.
  8982.   MAX_CLASS_TABLE_SIZE is the number of bytes allocated to hold the table 
  8983.   of properties to inherit from each class.
  8984.   MAX_INDIV_PROP_TABLE_SIZE is the number of bytes allocated to hold the 
  8985.   table of ..variable values.
  8986. No such memory setting as "%s"
  8987. LARGE
  8988. SMALL
  8989. Bad numerical setting in $ command "%s=%s"
  8990. BUFFER_LENGTH
  8991. MAX_BANK_SIZE
  8992. BANK_CHUNK_SIZE
  8993. MAX_OLDEPTH
  8994. MAX_ROUTINES
  8995. MAX_GCONSTANTS
  8996. MAX_FORWARD_REFS
  8997. STACK_SIZE
  8998. STACK_LONG_SLOTS
  8999. STACK_SHORT_LENGTH
  9000. The Inform 5 memory setting "%s" has been withdrawn.
  9001. It should be safe to omit it (putting nothing in its place).
  9002. No such memory $ command as "%s"
  9003. Properties table used %d
  9004. Allocated a total of %ld bytes of memory
  9005. %s  %02ld  
  9006. All 32 attributes already declared (compile as Advanced game to get an extra 16)
  9007. All 48 attributes already declared
  9008. new attribute name
  9009. an existing attribute name after 'alias'
  9010. All 30 properties already declared (compile as Advanced game to get an extra 62)
  9011. All 62 properties already declared
  9012. all properties are now automatically 'long'
  9013. new property name
  9014. 'alias' incompatible with 'additive'
  9015. an existing property name after 'alias'
  9016. obj   par nxt chl   Object tree:
  9017. %3d   %3d %3d %3d
  9018. An additive property has inherited so many values that the list has overflowed the maximum 32 entries
  9019. MAX_INDIV_PROP_TABLE_SIZE
  9020. MAX_PROP_TABLE_SIZE
  9021. property name
  9022. "%s" is a name already in use (with type %s) and may not be used as a property name too
  9023. No such property name as
  9024. Property should be declared in 'with', not 'private':
  9025. Property given twice in the same declaration:
  9026. Property given twice in the same declaration, because the names '%s' and '%s' actually refer to the same property
  9027. %s::%s
  9028. %s.%s
  9029. Missing ','? Property data seems to contain the property name
  9030. Limit (of 32 values) exceeded for property
  9031. Version 3 limit of 4 values per property exceeded (use -v5 to get 32), so truncating property
  9032. attribute name after '~'
  9033. name of an already-declared attribute
  9034. name of an already-declared class
  9035. Two commas ',' in a row in object/class definition
  9036. Object/class definition finishes with ','
  9037. Expected 'with', 'has' or 'class' in object/class definition but found
  9038. MAX_CLASSES
  9039. Inform's maximum possible number of classes (whatever amount of memory is allocated) has been reached. If this causes serious inconvenience, please contact the author.
  9040. new class name
  9041. Duplicate-number not known at compile time
  9042. The number of duplicates must be 0 to 10000
  9043. This class is too complex: it now carries too many properties. You may be able to get round this by declaring some of its property names as "common properties" using the 'Property' directive.
  9044. MAX_OBJECTS
  9045. nameless_obj__%d
  9046. The syntax '->' is only used as an alternative to 'Nearby'
  9047. name for new object or its textual short name
  9048. Two textual short names given for only one object
  9049. parent object or the object's textual short name
  9050. parent object
  9051. body of object definition
  9052. name of (the parent) object
  9053. (with no short name)
  9054. %3d "%s"
  9055. Use of '->' (or 'Nearby') clashes with giving a parent
  9056. '->' (or 'Nearby') fails because there is no previous object
  9057. '-> -> ...' fails because no previous object is deep enough
  9058. objects
  9059. inherited classes list
  9060. pointers to classes
  9061. class object numbers
  9062. properties table
  9063. individual properties table
  9064. property 3 lists
  9065. Unlike C, Inform uses ':' to divide parts of a 'for' loop specification: replacing ';' with ':'
  9066. label name
  9067. A reserved word was used as a print specification:
  9068. printing routine name
  9069. print specification
  9070. comma
  9071. something to print
  9072. Duplicate definition of label:
  9073. statement
  9074. The 'box' statement has no effect in a version 3 game
  9075. text of box line in double-quotes
  9076. No lines of text given for 'box' display
  9077. 'break' can only be used in a loop or 'switch' block
  9078. 'continue' can only be used in a loop block
  9079. 'do' without matching 'until'
  9080. 'on' or 'off'
  9081. This is not a declared Attribute:
  9082. 'objectloop' variable
  9083. In Version 3 no status-line drawing routine can be given
  9084. The 'style' statement cannot be used for Version 3 games
  9085. 'roman', 'bold', 'underline', 'reverse' or 'fixed'
  9086. 'default' without matching 'switch'
  9087. 'else' without matching 'if'
  9088. 'until' without matching 'do'
  9089. MAX_SYMBOLS
  9090. symbol names chunk
  9091. Routine
  9092. Label
  9093. Global variable
  9094. Array
  9095. Defined constant
  9096. Attribute
  9097. Property
  9098. Individual property
  9099. Object
  9100. Class
  9101. Fake action
  9102. (Unknown type)
  9103. (used) 
  9104. (Replaced) 
  9105. (Defaulted) 
  9106. (Stubbed) 
  9107. (value will change) 
  9108. (Imported) 
  9109. (Exported) 
  9110. (System) 
  9111. (created in sys file) 
  9112. ('Unknown' error issued) 
  9113. (aliased) 
  9114. (Action name) 
  9115. (Redefinable) 
  9116. %4d  %-16s  %2d:%04d  %04x  %s  
  9117. <unknown attribute>
  9118. nothing
  9119. false
  9120. Grammar__Version
  9121. MODULE_MODE
  9122. STRICT_MODE
  9123. DEBUG
  9124. USE_MODULES
  9125. INFIX
  9126. infix__watching
  9127. temp_global
  9128. temp__global2
  9129. temp__global3
  9130. temp__global4
  9131. sender
  9132. sw__var
  9133. sys__glob0
  9134. sys__glob1
  9135. sys__glob2
  9136. create
  9137. recreate
  9138. destroy
  9139. remaining
  9140. print
  9141. print_to_array
  9142. symbols
  9143. symbol values
  9144. symbol lines
  9145. symbol types
  9146. symbol flags
  9147. symbol linked-list forward links
  9148. hash code list beginnings
  9149. symbol names chunk addresses
  9150. property name strings
  9151. action name strings
  9152. attribute name strings
  9153. array name strings
  9154. It is illegal to nest routines using '#['
  9155. routine name
  9156. ';' after ']'
  9157. directive, '[' or class name
  9158. At most 32 values can be given in a single 'switch' case
  9159. action (or fake action) name
  9160. ',' or ':'
  9161. ',', ':' or 'to'
  9162. local variable name or ';'
  9163. A routine can have at most 15 local variables
  9164. Local variable defined twice:
  9165. Multiple 'default' clauses defined in same 'switch'
  9166. ':' after 'default'
  9167. 'default' must be the last 'switch' case
  9168. switch value
  9169. braced code block after 'switch'
  9170. %y%m%d
  9171.    %-20s %2d.%d%%
  9172. Standard
  9173. Advanced
  9174. Graphical
  9175. Extended
  9176. experimental format
  9177. module
  9178. story file
  9179. identifier name strings
  9180. action name strings
  9181. attribute name strings
  9182. array name strings
  9183. output buffer
  9184. This version of Inform is unable to produce the grammar table format requested (producing number 2 format instead)
  9185. This program has overflowed the maximum readable-memory size of the Z-machine format. See the memory map below: the start of the area marked "above readable memory" must be brought down to $10000 or less.
  9186. The %s exceeds version-%d limit (%dK) by %d bytes
  9187. In:%3d source code files            %6d syntactic lines
  9188. %6d textual lines                %6ld characters 
  9189. (plain ASCII)
  9190. (ISO 8859-%d %s)
  9191. Allocated:
  9192. %6d symbols (maximum %4d)       %6ld bytes of memory
  9193. Out:   Version %d "%s" %s %d.%c%c%c%c%c%c (%ld%sK long):
  9194. %6d classes (maximum %2d)         %6d objects (maximum %3d)
  9195. %6d global vars (maximum 233)    %6d variable/array space (maximum %d)
  9196. %6d verbs (maximum %3d)          %6d dictionary entries (maximum %d)
  9197. %6d grammar lines (version %d)    %6d grammar tokens (unlimited)
  9198. %6d actions (maximum %3d)        %6d attributes (maximum %2d)
  9199. %6d common props (maximum %2d)    %6d individual props (unlimited)
  9200. %6ld characters used in text      %6ld bytes compressed (rate %d.%3ld)
  9201. %6d abbreviations (maximum %d)   %6d routines (unlimited)
  9202. %6ld instructions of Z-code       %6d sequence points
  9203. %6ld bytes readable memory used (maximum 65536)
  9204. %6ld bytes used in Z-machine      %6ld bytes free in Z-machine
  9205. Offsets in %s:
  9206. %05lx Synonyms     %05lx Defaults     %05lx Objects    %05lx Properties
  9207. %05lx Variables    %05lx Parse table  %05lx Actions    %05lx Preactions
  9208. %05lx Adjectives   %05lx Dictionary   %05lx Code       %05lx Strings
  9209. %05lx Linking data
  9210. abbreviations table
  9211. header extension
  9212. alphabets table
  9213. Unicode table
  9214. property defaults
  9215. object tree
  9216. common properties
  9217. class numbers
  9218. individual properties
  9219. global variables
  9220. array space
  9221. grammar table
  9222. actions table
  9223. parsing routines
  9224. adjectives table
  9225. dictionary
  9226. code area
  9227. strings area
  9228. Dynamic +---------------------+   00000
  9229. memory  |       header        |
  9230.         +---------------------+   00040
  9231.         |    abbreviations    |
  9232.         + - - - - - - - - - - +   %05lx
  9233.         | abbreviations table |
  9234.         +---------------------+   %05lx
  9235.         |  header extension   |
  9236.         |   alphabets table   |
  9237.         |    Unicode table    |
  9238.         |  property defaults  |
  9239.         |       objects       |
  9240.         | object short names, |
  9241.         | common prop values  |
  9242.         | class numbers table |
  9243.         | symbol names table  |
  9244.         | indiv prop values   |
  9245.         |  global variables   |
  9246.         |       arrays        |
  9247.         +=====================+   %05lx
  9248. Readable|    grammar table    |
  9249. memory  + - - - - - - - - - - +   %05lx
  9250.         |       actions       |
  9251.         |   parsing routines  |
  9252.         |     adjectives      |
  9253.         |     dictionary      |
  9254.         | map of module addrs |
  9255. Above   |       Z-code        |
  9256. readable+---------------------+   %05lx
  9257. memory  |       strings       |
  9258.         | module linking data |
  9259. Approximate percentage breakdown of %s:
  9260. Z-code
  9261. Linking data
  9262. Static strings
  9263. Dictionary
  9264. Objects
  9265. Globals
  9266. Parsing tables
  9267. Header and synonyms
  9268. Total of save area
  9269. Total of text
  9270. How frequently abbreviations were used, and roughly
  9271. how many bytes they saved:  ('_' denotes spaces)
  9272. %10s %5d/%5d   
  9273. None were declared.
  9274. MAX_LOW_STRINGS
  9275. MAX_STATIC_STRINGS
  9276. MAX_TRANSCRIPT_SIZE
  9277. '@..' must have two decimal digits
  9278. Character can only be used if declared in advance as part of 'Zcharacter table':
  9279. Pass %d, %4ld/%ld '%s' (%ld occurrences) 
  9280.  (%d seconds)
  9281. Beginning calculation of optimal abbreviations...
  9282. tlb table
  9283. sub_buffer
  9284. bestyet
  9285. bestyet2
  9286. grandtable
  9287. All %ld cross-references used
  9288. All %d three-letter-blocks used
  9289. grandflags
  9290. Cross-reference table (%ld entries) built...
  9291. Pass %d
  9292. Selection %2ld: '%s' (repeated %ld times, scoring %ld)
  9293. Chosen abbreviations (in Inform syntax):
  9294. Abbreviate "%s";
  9295. Expected 'p' after '//' to give number of dictionary word
  9296. Obsolete usage: use the ^ character for the apostrophe in
  9297. Character can be printed but not input:
  9298. MAX_DICT_ENTRIES
  9299. %02x 
  9300. noun 
  9301.        
  9302. preposition:%d  
  9303. preposition    
  9304. metaverb:%d  
  9305. verb:%d  
  9306. Dictionary contains %d entries:
  9307. Z-machine alphabet entries:
  9308. [Dictionary contains %d entries:]
  9309. abbreviations
  9310. abbrev values
  9311. abbrev quality
  9312. abbrev freqs
  9313. red-black tree for dictionary
  9314. final dictionary ordering table
  9315. dictionary sort codes
  9316. dictionary
  9317. static strings holding area
  9318. low (abbreviation) strings
  9319. Main__
  9320. @print_obj a; ]
  9321. a;         if (Z__Region(a)~=1) return RT__Err(36);
  9322. RT__ChPrintO
  9323. @print_paddr a; ]
  9324. a;         if (Z__Region(a)~=3) return RT__Err(35);
  9325. RT__ChPrintS
  9326. @print_addr a; ]
  9327. a;         if (Unsigned__Compare(a, #readable_memory_offset)>=0)         return RT__Err(34);
  9328. RT__ChPrintA
  9329. @print_char c; ]
  9330. c fl;         if (c==0 or 9 or 11 or 13) fl=1;         if (c>=32 && c<=126) fl=1; if (c>=155 && c<=251) fl=1;         if (fl==0) return RT__Err(33,c);
  9331. RT__ChPrintC
  9332. @storew base offset val; ]
  9333. base offset val a f;         a=base+2*offset;         if (Unsigned__Compare(a,#array__start)>=0             && Unsigned__Compare(a,#array__end)<0) f=1; else         if (Unsigned__Compare(a,#cpv__start)>=0             && Unsigned__Compare(a,#cpv__end)<0) f=1; else         if (Unsigned__Compare(a,#ipv__start)>=0             && Unsigned__Compare(a,#ipv__end)<0) f=1; else         if (a==$0010) f=1;         if (f==0) return RT__Err(27);
  9334. RT__ChSTW
  9335. @storeb base offset val; ]
  9336. base offset val a f;         a=base+offset;         if (Unsigned__Compare(a,#array__start)>=0             && Unsigned__Compare(a,#array__end)<0) f=1; else         if (Unsigned__Compare(a,#cpv__start)>=0             && Unsigned__Compare(a,#cpv__end)<0) f=1; else         if (Unsigned__Compare(a,#ipv__start)>=0             && Unsigned__Compare(a,#ipv__end)<0) f=1; else         if (a==$0011) f=1;         if (f==0) return RT__Err(26);
  9337. RT__ChSTB
  9338. @loadw base offset -> val;return val; ]
  9339. base offset a val;         a=base+2*offset;if (Unsigned__Compare(a,#readable_memory_offset)>=0)         return RT__Err(25);
  9340. RT__ChLDW
  9341. @loadb base offset -> val;return val; ]
  9342. base offset a val;         a=base+offset;if (Unsigned__Compare(a,#readable_memory_offset)>=0)         return RT__Err(24);
  9343. RT__ChLDB
  9344. obj prop val;         print "[Setting ",(name) obj,".",(property) prop,         " to ",val,"]^"; ]
  9345. RT__TrPS
  9346. #ifdef INFIX;         if (obj has infix__watching || (debug_flag & 15)) RT__TrPS(obj,prop,val);         #ifnot; #ifdef DEBUG;         if (debug_flag & 15) RT__TrPS(obj,prop,val);         #endif; #endif;         return val; ]
  9347. obj prop val;         if (obj<5 || obj>(#largest_object-255) || obj in 1 || obj.&prop==0)         return RT__Err("set", obj, prop);         @put_prop obj prop val;
  9348. RT__ChPS
  9349. #ifdef INFIX;         if (a ~= workflag && (obj1 has infix__watching || (debug_flag & 15)))         print "[Giving ",(name) obj1," @@126", (DebugAttribute) a, "]^";         #ifnot; #ifdef DEBUG;         if (a ~= workflag && debug_flag & 15)         print "[Giving ",(name) obj1," @@126", (DebugAttribute) a, "]^";         #endif; #endif;         @clear_attr obj1 a; ]
  9350. obj1 a;         if (obj1<5 || obj1>(#largest_object-255) || obj1 in 1)         return RT__Err(14,obj1); if (a<0 || a>=48) return RT__Err(19,obj1);         if (obj1 hasnt a) return;
  9351. RT__ChGt
  9352. #ifdef INFIX;         if (a ~= workflag && (obj1 has infix__watching || (debug_flag & 15)))         print "[Giving ", (name) obj1, " ", (DebugAttribute) a, "]^";         #ifnot; #ifdef DEBUG;         if (a ~= workflag && debug_flag & 15)         print "[Giving ", (name) obj1, " ", (DebugAttribute) a, "]^";         #endif; #endif;         @set_attr obj1 a; ]
  9353. obj1 a;         if (obj1<5 || obj1>(#largest_object-255) || obj1 in 1)         return RT__Err(14,obj1); if (a<0 || a>=48) return RT__Err(19,obj1);         if (obj1 has a) return;
  9354. RT__ChG
  9355. #ifdef INFIX;         if (obj1 has infix__watching || (debug_flag & 15))         print "[Removing ", (name) obj1, "]^";         #ifnot; #ifdef DEBUG;         if (debug_flag & 15)         print "[Removing ", (name) obj1, "]^";         #endif; #endif;         @remove_obj obj1; ]
  9356. obj1;         if (obj1<5 || obj1>(#largest_object-255) || obj1 in 1)             return RT__Err(15,obj1);
  9357. RT__ChR
  9358. x=obj2; while (x~=0) { if (x==obj1) return RT__Err(18,obj1,obj2);          x=parent(x); }         #ifdef INFIX;         if (obj1 has infix__watching             || obj2 has infix__watching || (debug_flag & 15))         print "[Moving ", (name) obj1, " to ", (name) obj2, "]^";         #ifnot; #ifdef DEBUG;         if (debug_flag & 15)         print "[Moving ", (name) obj1, " to ", (name) obj2, "]^";         #endif; #endif;         @insert_obj obj1 obj2; ]
  9359. obj1 obj2 x;         if (obj1<5 || obj1>(#largest_object-255) || obj1 in 1)             return RT__Err(16,obj1,obj2);         if (obj2<5 || obj2>(#largest_object-255) || obj2 in 1)             return RT__Err(17,obj1,obj2);
  9360. RT__ChT
  9361. copy:                 if (~~(a ofclass obj))                 { RT__Err("copy", a, -obj); rfalse; }                 if (~~(b ofclass obj))                 { RT__Err("copy", b, -obj); rfalse; }                 Copy__Primitive(a, b); rfalse;         }         ]
  9362. destroy:                 if (~~(a ofclass obj))                 { RT__Err("destroy", a, -obj); rfalse; }                 if (a provides destroy) a..destroy();                 Copy__Primitive(a, child(obj));                 move a to obj; rfalse;             remaining:                 return children(obj)-1;
  9363. obj id y a b c d x;         switch(id)         {   create:                 if (children(obj)<=1) rfalse; x=child(obj);                 remove x; if (x provides create) { if (y==0) x..create();                 if (y==1) x..create(a); if (y==2) x..create(a,b);                 if (y>3) RT__Err(1,obj); if (y>=3) x..create(a,b,c);}                 return x;             recreate:                 if (~~(a ofclass obj))                 { RT__Err("recreate", a, -obj); rfalse; }                 Copy__Primitive(a, child(obj));                 if (a provides create) { if (y==1) a..create();                 if (y==2) a..create(b); if (y==3) a..create(b,c);                 if (y>4) RT__Err(1,obj); if (y>=4) a..create(b,c,d);                 } rfalse;
  9364. Cl__Ms
  9365. x id n l;         while ((n=0->x) ~= 0)         {   if (n & $80) { x++; l = (0->x) & $3f; }             else { if (n & $40) l=2; else l=1; }             x++;             if ((n & $3f) == id) return x;             x = x + l;         }         if (id<0) return x+1; rfalse; ]
  9366. CP__Tab
  9367. obj;         switch(Z__Region(obj))         {   2: return Routine;             3: return String;             1: if (obj in 1 || obj <= 4) return Class;                return Object;         }         rfalse;         ]
  9368. Meta__class
  9369. x y u v;         if (x==y) return 0;         if (x<0 && y>=0) return 1;         if (x>=0 && y<0) return -1;         u = x&$7fff; v= y&$7fff;         if (u>v) return 1;         return -1;         ]
  9370. Unsigned__Compare
  9371. addr;         if (addr==0) rfalse;         if (addr>=1 && addr<=(#largest_object-255)) rtrue;         if (Unsigned__Compare(addr, #strings_offset)>=0) return 3;         if (Unsigned__Compare(addr, #code_offset)>=0) return 2;         rfalse;         ]
  9372. Z__Region
  9373. else         {   print " has no property ", (property) id;             p = #identifiers_table;             size = p-->0;             if (id<0 || id>=size)                 print " (and nor has any other object)";         }         print " to ", (string) crime, " **]^";         ]
  9374. .RErr; if (obj>=0 && obj<=(#largest_object-255)) {         if (obj && obj in Class) print "class ";         if (obj) @print_obj obj;else print "nothing";print" ";}         print "(object number ", obj, ") ";         if (id<0) print "is not of class ", (name) -id;
  9375. 16,17,18: print "move~ ", (name) obj, " to ", (name) id;         if (crime==18) { print ", which would make a loop: ",(name) obj;         p=id; do { print " in ", (name) p; p=parent(p);} until (p==obj);         " in ", (name) p, " **]"; }         " **]"; 19: "give~ or test ~has~ or ~hasnt~ with a non-attribute         on the object ",(name) obj," **]";         21: print ".&"; 22: print ".#"; 23: print "."; }         "~ of ", (name) obj, " **]"; }
  9376. if (crime < 32) { print "tried to ";         if (crime >= 28) { if (crime==28 or 29) print "read from ";         else print "write to ";         if (crime==29 or 31) print "-"; print "->", obj,         " in the"; if(size>=8) { print" (->)"; size=size-8; }         if(size>=4) { print" (-->)"; size=size-4; }         switch(size){0,1:q=0; 2:print " string";         q=1; 3:print " table";q=1;} " array ~",         (string) #array_names_offset-->p, "~, which has entries ", q,         " up to ",id," **]"; }         if (crime >= 24 && crime <=27) { if (crime<=25) print "read";         else print "write"; print " outside memory using ";         switch(crime) { 24,26:"-> **]"; 25,27:"--> **]"; } }         if (crime < 4) print "test "; else         if (crime < 12 || crime > 20) print "find the "; else         if (crime < 14) print "use ";         if (crime==20) "divide by zero **]"; print "~";         switch(crime) {         2: print "in~ or ~notin"; 3: print "has~ or ~hasnt";         4: print "parent"; 5: print "eldest"; 6: print "child";         7: print "younger"; 8: print "sibling"; 9: print "children";         10: print "youngest"; 11: print "elder";         12: print "objectloop"; 13: print "}~ at end of ~objectloop";         14: "give~ an attribute to ", (name) obj, " **]";         15: "remove~ ", (name) obj, " **]";
  9377. crime obj id size p q;         print "^[** Programming error: ";         if (crime<0) jump RErr;         if (crime==1) { print "class "; @print_obj obj;         ": 'create' can have 0 to 3 parameters only **]";}         if (crime == 32) "objectloop broken because the object ",         (name) obj, " was moved while the loop passed through it **]";         if (crime == 33) "tried to print (char) ", obj,         ", which is not a valid ZSCII character code for output **]";         if (crime == 34) "tried to print (address) on something not the ",         "byte address of a string **]";         if (crime == 35) "tried to print (string) on something not a ",         "string **]";         if (crime == 36) "tried to print (object) on something not an ",         "object or class **]";
  9378. RT__Err
  9379. if (o1.&3 == 0 || o2.&3 == 0) return;         for (n=o2.3: n-->0 ~= 0: n = n + size + 3)         {   identifier = n-->0;             size = n->2;             for (m=o1.3: m-->0 ~= 0: m = m + m->2 + 3)                 if ((identifier & $7fff == (m-->0) & $7fff) && size==m->2)                     for (l=3: l<size+3: l++) m->l = n->l;         }         ]
  9380. o1 o2 a1 a2 n m l size identifier;         for (n=0:n<48:n++)         {   if (o2 has n) give o1 n;             else give o1 ~n;         }         for (n=1:n<64:n++) if (n~=2 or 3)         {   a1 = o1.&n; a2 = o2.&n; size = o1.#n;             if (a1~=0 && a2~=0 && size==o2.#n)             {   for (m=0:m<size:m++) a1->m=a2->m;             }         }
  9381. Copy__Primitive
  9382. if (cla notin 1) { RT__Err("apply 'ofclass' for", cla, -1);rfalse;}         a = obj.&2;         if (a==0) rfalse;         n = obj.#2;         for (j=0: j<n/2: j++)         {   if (a-->j == cla) rtrue;         }         rfalse;         ]
  9383. obj cla j a n;         if (obj<1 || obj > (#largest_object-255))         {   if (cla ~= 3 or 4) rfalse;             if (Z__Region(obj) == cla-1) rtrue;             rfalse;         }         switch(cla)         {   1: if (obj<=4) rtrue;                if (obj in 1) rtrue;                rfalse;             2: if (obj<=4) rfalse;                if (obj in 1) rfalse;                rtrue;             3, 4: rfalse;         }
  9384. OC__Cl
  9385. if (identifier<64)         {   if (obj.&identifier ~= 0) rtrue;             rfalse;         }         if (obj..&identifier ~= 0) rtrue;         if (identifier<72 && obj in 1) rtrue;         rfalse;         ]
  9386. obj identifier;         if (obj<1 || obj > (#largest_object-255))         {   if (identifier ~= print or print_to_array or call) rfalse;             switch(Z__Region(obj))             {   2: if (identifier == call) rtrue;                 3: if (identifier == print or print_to_array) rtrue;             }             rfalse;         }
  9387. OP__Pr
  9388. while (i-->0 ~= 0)                 {   if (i-->0 == identifier or otherid)                         return $8000 + k*$100 + j;                     i = i + i->2 + 3;                     k++;                 }                 break;             }         }         RT__Err("make use of", cla, identifier);         rfalse;         ]
  9389. cla identifier otherid i j k;         if (cla notin 1 && cla > 4)         {   RT__Err("be a '::' superclass", cla, -1); rfalse; }         if (self ofclass cla) otherid = identifier | $8000;         for (j=0: #classes_table-->j ~= 0: j++)         {   if (cla==#classes_table-->j)             {   if (identifier < 64) return $4000 + identifier*$100 + j;                 if (cla.&3 == 0) break;                 i = cla.3;
  9390. RA__Sc
  9391. obj identifier x;         if (identifier<64 && identifier>0) return obj.#identifier;         x = obj..&identifier;         if (x==0) rfalse;         if (identifier&$C000==$4000)             switch (((x-1)->0)&$C0)             {  0: return 1;  $40: return 2;  $80: return ((x-1)->0)&$3F; }         return (x-1)->0;         ]
  9392. RL__Pr
  9393. if (self == obj)             otherid = identifier | $8000;         i = obj.3;         while (i-->0 ~= 0)         {   if (i-->0 == identifier or otherid)                 return i+3;             i = i + i->2 + 3;         }         rfalse;         ]
  9394. if (identifier & $4000 ~= 0)         {   cla = #classes_table-->(identifier & $ff);             identifier = (identifier & $3f00) / $100;             if (~~(obj ofclass cla)) rfalse; i=0-->5;             if (cla == 2) return i+2*identifier-2;             i = 0-->((i+124+cla*14)/2);             i = CP__Tab(i + 2*(0->i) + 1, -1)+6;             return CP__Tab(i, identifier);         }         if (obj.&3 == 0) rfalse;         if (obj in 1)         {   if (identifier<64 || identifier>=72) rfalse;         }
  9395. obj identifier i otherid cla;         if (obj==0) rfalse;         if (identifier<64 && identifier>0) return obj.&identifier;         if (identifier & $8000 ~= 0)         {   cla = #classes_table-->(identifier & $ff);             if (cla.&3 == 0) rfalse;             if (~~(obj ofclass cla)) rfalse;             identifier = (identifier & $7f00) / $100;             i = cla.3;             while (identifier>0)             {   identifier--;                 i = i + i->2 + 3;             }             return i+3;         }
  9396. RA__Pr
  9397. obj identifier x;         x = obj..&identifier;         if (x==0) { RT__Err("decrement", obj, identifier); return; }         #ifdef INFIX;         if (obj has infix__watching || (debug_flag & 15)) RT__TrPS(obj,identifier,(x-->0)-1);         #ifnot; #ifdef DEBUG;         if (debug_flag & 15) RT__TrPS(obj,identifier,(x-->0)-1);         #endif; #endif;         return (x-->0)--;         ]
  9398. DA__Pr
  9399. obj identifier x;         x = obj..&identifier;         if (x==0) { RT__Err("decrement", obj, identifier); return; }         #ifdef INFIX;         if (obj has infix__watching || (debug_flag & 15)) RT__TrPS(obj,identifier,(x-->0)-1);         #ifnot; #ifdef DEBUG;         if (debug_flag & 15) RT__TrPS(obj,identifier,(x-->0)-1);         #endif; #endif;         return --(x-->0);         ]
  9400. DB__Pr
  9401. obj identifier x;         x = obj..&identifier;         if (x==0) { RT__Err("increment", obj, identifier); return; }         #ifdef INFIX;         if (obj has infix__watching || (debug_flag & 15))         RT__TrPS(obj,identifier,(x-->0)+1);         #ifnot; #ifdef DEBUG;         if (debug_flag & 15) RT__TrPS(obj,identifier,(x-->0)+1);         #endif; #endif;         return (x-->0)++;         ]
  9402. IA__Pr
  9403. obj identifier x;         x = obj..&identifier;         if (x==0) { RT__Err("increment", obj, identifier); return; }         #ifdef INFIX;         if (obj has infix__watching || (debug_flag & 15)) RT__TrPS(obj,identifier,(x-->0)+1);         #ifnot; #ifdef DEBUG;         if (debug_flag & 15) RT__TrPS(obj,identifier,(x-->0)+1);         #endif; #endif;         return ++(x-->0);         ]
  9404. IB__Pr
  9405. 4: z = indirect(x-->m, a, b, c, d); 5:z = indirect(x-->m, a, b, c, d, e);     6: z = indirect(x-->m, a, b, c, d, e, f); }                 self = sender; sender = s; sw__var = s2;                 if (z ~= 0) return z;              3: print_ret (string) x-->m;        default: return x-->m;            }         }         rfalse;         ]
  9406. for (:2*m<n:m++)         {  if (x-->m==$ffff) rfalse;            switch(Z__Region(x-->m))            { 2: s = sender; sender = self; self = obj; s2 = sw__var;               #ifdef LibSerial;               if (id==life) sw__var=reason_code; else sw__var=action;               #endif;     switch(y) { 0: z = indirect(x-->m); 1: z = indirect(x-->m, a);     2: z = indirect(x-->m, a, b); 3: z = indirect(x-->m, a, b, c);
  9407. if (id > 0 && id < 64)         { x = obj.&id; if (x==0) { x=$000a-->0 + 2*(id-1); n=2; }         else n = obj.#id; }         else         { if (id>=64 && id<69 && obj in Class)             return Cl__Ms(obj,id,y,a,b,c,d);           x = obj..&id;           if (x == 0) { .Call__Error;             RT__Err("send message", obj, id); return; }           n = 0->(x-1);           if (id&$C000==$4000)             switch (n&$C0) { 0: n=1; $40: n=2; $80: n=n&$3F; }         }
  9408. #ifdef INFIX;if (obj has infix__watching) n=1;#endif;         #ifdef DEBUG;if (debug_flag & 1 ~= 0) n=1;#endif;         if (n==1) {           #ifdef DEBUG;n=debug_flag & 1; debug_flag=debug_flag-n;#endif;           print "[ ~", (name) obj, "~.", (property) id, "(";     switch(y) { 1: print a; 2: print a,",",b; 3: print a,",",b,",",c;     4: print a,",",b,",",c,",",d;     5: print a,",",b,",",c,",",d,",",e;     6: print a,",",b,",",c,",",d,",",e,",",f; }           print ") ]^";           #ifdef DEBUG;debug_flag = debug_flag + n;#endif;           }
  9409. 3: if (id == print) { @print_paddr obj; rtrue; }                   if (id == print_to_array)                   { @output_stream 3 a; @print_paddr obj; @output_stream -3;                     return a-->0; }                   jump Call__Error;             }             jump Call__Error;         }         @check_arg_count 3 ?~A__x;y++;@check_arg_count 4 ?~A__x;y++;         @check_arg_count 5 ?~A__x;y++;@check_arg_count 6 ?~A__x;y++;         @check_arg_count 7 ?~A__x;y++;@check_arg_count 8 ?~A__x;y++;.A__x;
  9410. obj id a b c d e f x y z s s2 n m;         if (obj < 1 || obj > #largest_object-255)         {   switch(Z__Region(obj))             { 2: if (id == call)                   { s = sender; sender = self; self = obj;                     #ifdef action;sw__var=action;#endif;                     x = indirect(obj, a, b, c, d, e, f);                     self = sender; sender = s; return x; }                   jump Call__Error;
  9411. CA__Pr
  9412. obj identifier x;         x = obj..&identifier;         if (x==0)         {   if (identifier >= 1 && identifier < 64)                 return obj.identifier;             RT__Err("read", obj, identifier); return; }         return x-->0;         ]
  9413. RV__Pr
  9414. obj identifier value x;         x = obj..&identifier;         if (x==0) { RT__Err("write to", obj, identifier); return; }         #ifdef INFIX;         if (obj has infix__watching || (debug_flag & 15)) RT__TrPS(obj,identifier,value);         #ifnot; #ifdef DEBUG;         if (debug_flag & 15) RT__TrPS(obj,identifier,value);         #endif; #endif;         x-->0 = value;         ]
  9415. WV__Pr
  9416. p = #identifiers_table;         size = p-->0;         if (prop<=0 || prop>=size || p-->prop==0)             print "<number ", prop, ">";         else print (string) p-->prop;         ]
  9417. prop p size cla i;         if (prop & $c000)         {   cla = #classes_table-->(prop & $ff);             print (name) cla, "::";             if ((prop & $8000) == 0) prop = (prop & $3f00)/$100;             else             {   prop = (prop & $7f00)/$100;                 i = cla.3;                 while ((i-->0 ~= 0) && (prop>0))                 {   i = i + i->2 + 3;                     prop--;                 }                 prop = (i-->0) & $7fff;             }         }
  9418. Print__PName
  9419. obj; print obj; ]
  9420. EnglishNumber
  9421. obj; switch(metaclass(obj))         {   0: print "nothing";             Object: @print_obj obj;             Class: print "class "; @print_obj obj;             Routine: print "(routine at ", obj, ")";             String: print "(string at ", obj, ")";         } ]
  9422. PrintShortName
  9423. obj; print "The ", obj; ]
  9424. CDefArt
  9425. obj; print "a ", obj; ]
  9426. InDefArt
  9427. obj; print "the ", obj; ]
  9428. DefArt
  9429. a b c; print "Action <", a, " ", b, " ", c, ">^";         ]
  9430. R_Process
  9431. do         {   w = table --> lc;             if (w ~= 0) print (string) w;             lc++;             if (lc > n)             {   print "]^^";                 break;             }             print "^  ";         } until (false);         @output_stream 1;         ]
  9432. do         {   @set_cursor line w;             spaces maxw + 4;             @set_cursor line w2;             t = table --> lc;             if (t~=0) print (string) t;             line++; lc++;         } until (lc > n);         @set_cursor line w;         spaces maxw + 4;         @buffer_mode 1;         style roman;         @set_window 0;         @split_window 1;         @output_stream $ffff;         print "[ ";         lc = 1;
  9433. maxw table n w w2 line lc t;         n = table --> 0;         @add n 6 -> sp;         @split_window sp;         @set_window 1;         w = 0 -> 33;         if (w == 0) w=80;         w2 = (w - maxw)/2;         style reverse;         @sub w2 2 -> w;         line = 5;         lc = 1;         @set_cursor 4 w;         spaces maxw + 4;
  9434. Box__Routine
  9435. Symb__Tab
  9436. The following name is reserved by Inform for its own use as a routine name; you can use it as a routine name yourself (to override the standard definition) but cannot use it for anything else:
  9437. veneer source code area
  9438. Verb %2d has %d lines
  9439. Action '%s' is numbered %d
  9440. new fake action name
  9441. %s__A
  9442. MAX_ACTIONS
  9443. There is no action routine called
  9444. Not an action routine:
  9445. MAX_ADJECTIVES
  9446. Two different verb definitions refer to
  9447. MAX_VERBSPACE
  9448. There is no previous grammar for the verb
  9449. an English verb in quotes
  9450. '*' divider
  9451. Too many lines of grammar for verb. This maximum is built into Inform, so suggest rewriting grammar using general parsing routines
  9452. MAX_LINESPACE
  9453. '->' clause
  9454. grammar token
  9455. '/' can only be used with Library 6/3 or later
  9456. grammar token or '->'
  9457. '/' can only be applied to prepositions
  9458. routine name after 'noun='
  9459. The 'topic' token is only available if you are using Library 6/3 or later
  9460. '=' after 'scope'
  9461. routine name after 'scope='
  9462. '=' is only legal here as 'noun=Routine'
  9463. No such grammar token as
  9464. Grammar line cut short: you can only have up to 6 tokens in any line (unless you're compiling with library 6/3 or later)
  9465. name of new or existing action
  9466. This is a fake action, not a real one:
  9467. 'reverse' actions can only be used with Library 6/3 or later
  9468. English verb in quotes
  9469. ';' after English verb
  9470. MAX_VERBS
  9471. Verb disagrees with previous verbs:
  9472. 'replace', 'last', 'first' or '*'
  9473. verbs
  9474. grammar lines
  9475. actions
  9476. action symbols
  9477. grammar token routines
  9478. adjectives
  9479. adjective sort codes
  9480. register of verbs
  9481. ESTLIB[100002c3].DLL
  9482. EUSER[100000c1].DLL
  9483. 0014181<1@1
  9484. 2t2x2
  9485. 2`6d6h6l6p6t6x6|6
  9486. 7d8h8l8p8X:\:`:d:h:l:p:t:x:|:
  9487. :0;4;h;l;
  9488. <@<D<H<
  9489. =H=L=P=T=X=\=`=d=
  9490. > >$>
  9491. ?p?t?x?|?
  9492. 0 0$04181<1@1D1|1
  9493. 2D3H3L3P3$4
  9494. 8 8$8(8,8084888<8@8D8H8L8P8T8X8\8`8d8
  9495. >X>\>
  9496. 2 2$2H4L4P4T4X4\4`4d4h44787<7@7D7H7L7P7T7X7\7`7d7h7l7p7t7x7|7
  9497. ;T<X<\<`<d<h<l<p<t<x<|<
  9498. = >$>(>X>
  9499. < <$<(<,<0<4<8<<<
  9500. l1p1t1x1|1
  9501. 14282<2@2D2H2
  9502. 24383<3@3P4T4\4`4d4h4l4p4t4x4|4
  9503. 4 5$5(5,5054585<5@5D5H5L5P5T5X5\5`5d5h5
  9504. 5@9D9H9L9P9T9X9\9`9d9h9l9p9t9x9|9
  9505. 94:8:<:@:D:H:L:P:
  9506. =0=4=0>4>8><>@>
  9507. 0l1p1t1x1|1
  9508. 2 2$2(2,2024282<2@2D2H2
  9509. 3 3$3(3,3034383<3@3D3X3\3`3d3h3l3p3t3x3|3
  9510. 4 4$4(4,4044484<4@4D4H4L4P4T4X4\4`4d4h4l4p4t4x4|4
  9511. 6\7`7d7h7l7p7t7x7|7
  9512. 8 8$8(8,8084888<8@8D8H8L8P8T8X8\8`8d8h8l8p8t8x8|8
  9513. : :$:(:,:0:4:8:<:@:D:H:L:P:T:X:\:`:d:h:l:p:t:x:|:
  9514. = =$=(=,=0=4=8=<=@=D=H=L=P=T=X=\=`=d=h=l=p=t=x=|=
  9515. > >$>(>,>0>4>8><>@>D>H>L>P>T>X>\>`>d>h>l>p>t>
  9516. 3 3$3(3,3034383<3@3D3H3L3P3T3X3\3`3d3h3l3p3t3x3|3
  9517. 6 6$6(6,6064686<6@6D6H6L6P6T6X6\6`6d6h6l6p6t6x6|6
  9518. 6`:d:h:l:p:t:x:|:
  9519. ; ;$;(;,;0;4;8;<;@;D;H;L;P;T;X;\;`;d;h;l;p;t;x;|;
  9520. > >$>(>,>0>4>8><>@>D>H>L>P>T>X>\>
  9521. 0l2p2t2x2|2
  9522. 2X3\3`3d3x3|3
  9523. 5 6$6(6,6064686<6@6D6H6L6P6T6X6\6`6d6h6l6p6t6x6|6
  9524. 2 2$2(2,20242
  9525. 6 6$6(6,6064686<6@6D6H6L6P6T6X6\6`6d6h6l6
  9526. 94:8:<:@:D:H:L:P:T:X:\:`:d:h:l:p:t:x:|:
  9527. :T=X=\=`=d=h=l=p=t=x=|=
  9528. =8><>@>D>H>L>T?X?\?`?d?h?l?p?t?
  9529. 0 0X0\0`0
  9530. 04181<1@1
  9531. 2 2$2(2,2024282<2@2D2H2L2P2
  9532. 4@5D5H5L5P5
  9533. 5@6D6H6
  9534. 6P7T7X7\7`7
  9535. 8p8t8x8|8
  9536. 8$9(9,90949\9`9
  9537. 9,:0:4:8:<:@:D:
  9538. 9L;P;
  9539. ; ;$;(;,;0;4;8;<;@;D;H;L;P;T;X;\;`;d;h;l;p;t;x;|;
  9540. ;d?h?l?p?t?x?
  9541. 3d6h6l6p6
  9542. 9 9$9(9,90949
  9543. = =$=(=,=`=d=h=l=p=t=x=|=
  9544. 4T8X8\8`8
  9545. ;<?@?D?H?L?P?
  9546. 5 5$5(5,5054585<5@5D5
  9547. 8p:t:x:|:
  9548. < <$<(<,<0<4<8<<<@<D<H<L<P<h<l<p<t<x<|<
  9549. = =$=
  9550. (0,0004080<0@0D0H0L0P0T0X0\0`0d0h0l0p0t0x0L3P3T3X3\3`3d3h3l3p3t3x3|3
  9551. 5 5$5(5,5054585<5@5D5H5L5P5T5X5\5`5d5h5l5p5t5x5|5
  9552. 8 8$8(8,8084888<8@8D8H8L8P8T8X8\8`8d8h8
  9553. : :$:(:,:0:4:8:<:@:D:H:L:P:T:X:\:`:d:h:l:p:t:x:|:
  9554. 0 0$0(0,000h2l2p2t2x2|2
  9555. 4(7,7074787<7@7D7H7L7T7X7\7`7
  9556. 9h:l:p:
  9557. = =$=(=,=0=4=H=L=P=T=X=\=`=d=h=l=p=t=x=|=
  9558. > >$>(>,>0>4>8><>@>D>H>L>
  9559. ?`?d?h?l?
  9560. ; ;$;(;,;0;4;8;
  9561. ;4<t<
  9562. =D=H=L=P=T=X=\=`=
  9563. 5 5$5(5,5054585<5@5D5H5L5P5T5X5\5`5d5
  9564. 9 9$9(9,9094989<9@9D9H9L9P9T9X9\9`9d9h9l9p9t9x9|9
  9565. :X:\:
  9566. ; ;$;(;,;0;4;
  9567. <H<L<P<T<
  9568. <`>d>h>l>p>t>x>|>
  9569. 0@0D0H0L0\0`0
  9570. 1L2P2T2X2\2`2d2h2l2p2t2x2|2
  9571. 2 4$4(4,4044484<4@4D4H4L4P4T4
  9572. 90:D;H;L;P;T;X;
  9573. ;$<(<
  9574. = =$=
  9575. 81<1@1D1H1L1P1T1X1\1`1d1h1l1p1t1x1|1
  9576. 2L3P3T3X3\3`3
  9577. 7 7$7(7,7074787<7@7x8|8
  9578. 8\9`9d9h9l9p9t9x9|9
  9579. : :$:(:,:0:4:8:h<l<p<t<x<|<
  9580. = =$=(=,=0=4=8=<=@=D=<?@?D?H?L?P?T?X?\?`?d?h?l?p?t?x?|?
  9581. 3$4(4,40444
  9582. 6 6$6(6,6064686<6@6D6H6L6P6T6X6\6`6d6h6l6p6t6x6|6
  9583. 7 7$7(7,7074787<7@7D7H7L7P7T7X7\7`7d7h7l7p7t7x7|7
  9584. 8 8$8(8,8084888<8@8D8H8L8P8T8X8\8`8d8h8l8p8t8x8|8
  9585. 9 9$9(9,9094989<9@9D9H9L9P9T9X9\9
  9586. :(;,;0;4;8;<;@;D;H;L;P;T;X;\;`;d;h;l;p;
  9587. (0,0004080<0@0D0H0P2T2X2\2`2d2h2l2p2t2x2|2
  9588. 2p4t4
  9589. 5$6(6,606
  9590. 8X8\8`8d8x:|:
  9591. ;L<P<T<X<\<
  9592. 0 0$0(0,0004080<0X0\0`0d0h0l0p0
  9593. 4 4,404
  9594. 8$8(8,8084888<8@8
  9595. : :$:(:,:0:4:8:<:@:D:H:L:P:T:x:|:
  9596. ;h<l<p<t<x<|<
  9597. = =$=(=,=0=4=8=<=@=
  9598. > >$>(>,>0>4>8><>@>D>H>
  9599. >@?D?H?L?P?T?X?|?
  9600. 4080<0@0D0H0L0P1T1X1\1`1
  9601. 5 5$5(5,5054585<5@5D5H5L5\6`6d6h6l6p6t6x6|6L7P7T7X7\7`7d7h7l7p7t7
  9602. 8 8$8(8,8084888<8@8h8l8p8t8x8|8
  9603. <8><>@>D>H>L>P>T>X>\>`>d>
  9604. L2P2T2X2\2`2d2h2l2p2t2x2|2
  9605. 8 8$8(8,808l8p8t8x8|8
  9606. < <$<(<,<0<4<8<<<@<D<H<L<P<T<X<\<
  9607. 3 3$3(3,3034383<3@3D3H3L3P3T3X3
  9608. 3t4x4|4
  9609. 8 8|8
  9610. 8$9(9,9
  9611. :x:|:
  9612. ;h<l<
  9613. ? ?$?(?,?0?4?8?<?@?D?H?L?P?T?X?
  9614. 3 3$3(3034383@3
  9615. 7 7$7(7,7074787<7@7D7H7L7P7T7X7\7`7T8X8\8`8d8D<H<L<P<T<X<\<`<d<h<l<p<t<x<|<
  9616. = =$=
  9617. t0x0|0
  9618. 3 4$4(4,4
  9619. ;D<H<L<P<T<
  9620. ? ?$?(?
  9621. 5 5$5(5
  9622. ;p<t<x<|<
  9623. <D=H=L=P=T=X=\=
  9624. >H>L>P>T>X>\>`>
  9625. 1 1$1(1,1014181<1@1D1H1L1P1T1X1\1`1d1h1p1t1x1
  9626. 7 7$7(7,7074787<7@7D788<8@8D8H8L8
  9627. :P;T;X;\;`;d;h;l;p;t;x;|;
  9628. <D<H<L<P<
  9629. 3 3$3(3,303
  9630. 5 5$5
  9631. 7 7$7(7,7$:(:,:0:4:8:<:@:D:H:L:P:
  9632. > >$>(>,>0>4>8>
  9633. 5P9T9X9\9`9d9h9l9p9t9x9
  9634. 3<8@8D8H8L8P8T8p;t;x;|;
  9635. >t?x?|?
  9636. P0T0X0\0`0
  9637. 1D1H1
  9638. 4 4$4(4,4044484<4@4D4H4L4P4T4X4l4p4t4x4|4
  9639. 5 5$5
  9640. 6 6$6(6,6064686<6@6D6H6
  9641. 7T8X8\8`8d8h8l8
  9642. < <$<(<,<0<4<8<<<@<D<H<
  9643. 3d3h3l3p3
  9644. 6 6$6(6,6064686<6
  9645. 8 8(9,9094989<9@9D9H9L9P9T9X9\9`9d9h9l9p9t9x9|9
  9646. >t?x?
  9647. 3 3$3(3,3034383<3
  9648. <D<H<l<
  9649. <0=4=8=<=@=D=
  9650. ? ?$?(?,?0?4?8?<?@?
  9651. 3 3$3(3,3034383<3@3D3H3L3P3
  9652. 58:<:@:D:H:L:P:T:X:\:`:d:h:l:p:t:x:|:
  9653. 2@5D5H5L5P5T5X5\5`5d5h5l5p5t5x5|5
  9654. 1 1$1(1,1014181<1@1D1H1L1P1T1X1\1`1d5h5l5p5t5x5|5
  9655. 6 6$6(6,6064686<6@6D6H6L6P6T6X6\6`6L:P:T:X:\:`:d:h:l:p:t:x:|:
  9656. ; ;$;(;,;L;P;
  9657. <,<0<`=d=h=l=p=t=x=X>\>`>
  9658. 0\1`1d1h1l1
  9659. 24686<6@6D6H6L6P6T6X6\6`6d6h6l6p6t6x6|6
  9660. 6h7l7p7t7 ;$;(;,;0;4;8;<;@;
  9661. 1 1$1(1,1014181
  9662. 4(6,6064686<6@6
  9663. ;l;p;t;x;|;|<
  9664. 82<2@2|3
  9665. 4T4X4
  9666. 7H8L8P8T8X8
  9667. : :$:(:
  9668. :h;l;p;t;x;|;
  9669. = >$>(>,>0>4>8><>@>D>H>L><?@?D?H?L?
  9670. 0 0$0(0,0004080<0@0D0
  9671. 4p6t6x6|6
  9672. 7P9T9X9\9`9d9h9l9p9t9x9
  9673. 9(:,:0:P:T:d:h:
  9674. ;$<(<,<
  9675. >8?<?@?D?
  9676. L0P0T0X0
  9677. 0@1D1
  9678. 1<2@2D2H2L2
  9679. ;4<8<\=`=d=h=l=p=D>H>L>P>T>
  9680. 014181<1@1D1H1L1P1T1X1
  9681. 1024282<2@2D2$3(3,3034383<3@3D3H3L3P3T3X3\3`3d3h3l3p3t3x3
  9682. 4 4|4
  9683. 5$505<5H5T5`5l5x5
  9684. 6 6,686D6P6\6
  9685. 0$0H0l0
  9686. 0 1D1h1
  9687. 2@2d2
  9688. 3<3`3
  9689. 484\4
  9690. 545X5|5
  9691. 606T6x6
  9692. 7,7P7t7
  9693. 8(8L8p8
  9694. 9$9H9l9
  9695. 9 :D:h:
  9696. ;@;d;
  9697. <<<`<
  9698. =8=\=
  9699. >4>X>|>
  9700. ?0?T?x?
  9701. 0,0P0t0
  9702. 1(1L1p1,;T;|;
  9703. <D<l<
  9704. =4=\=
  9705. =$>L>t>
  9706. ?<?d?
  9707. 0,0T0|0
  9708. 1D1l1
  9709. 242\2
  9710. 2$3L3t3
  9711. 4<4d4
  9712. 5,5T5|5
  9713. P9T9X9\9`9d9h9l9p9t9x9|9
  9714. : :$:(:,:0:4:8:<:@:D:H:L:P:T:X:\:`:d:h:l:p:t:x:|:
  9715. ; ;<;@;D;H;L;P;T;X;\;`;d;h;l;p;t;x;|;
  9716. ;(=,=0=4=8=<=@=D=H=L=P=T=
  9717. ? ?$?
  9718. 1 1$1(1,1014181<1@1D1H1L1P1T1X1\1`1d1h1l1p1t1x1|1
  9719. 3 3$3(3,3034383<3@3
  9720. 5 5$5(5,5054585<5@5D5H5L5P5T5
  9721. ; ;$;(;,;0;4;8;<;@;D;H;L;P;T;X;\;`;d;h;l;p;t;x;|;
  9722. ? ?$?(?,?0?4?8?<?@?D?H?L?P?T?X?\?`?d?h?l?p?t?x?|?
  9723. 0 0$0(0,0004080<0@0D0H0L0P0T0X0\0`0d0h0l0p0t0x0|0
  9724. 1 1$1(1,1014181<1@1D1H1L1P1T1X1\1`1d1h1l1p1t1x1|1
  9725. 2 2$2(2,2024282<2@2D2H2L2P2T2X2\2`2d2h2l2p2t2x2|2
  9726. 3 3$3(3,3034383<3@3D3H3L3P3T3X3\3`3d3h3l3p3t3
  9727.