1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-08 18:14:21 +03:00
inform7/docs/CommandParserKit/S-prs.html

4451 lines
686 KiB
HTML
Raw Normal View History

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
2020-04-14 19:56:54 +03:00
<title>Parser Template</title>
2020-03-19 02:11:25 +02:00
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
2020-03-19 02:11:25 +02:00
<link href="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
2020-04-14 19:56:54 +03:00
</head>
<body>
2020-03-19 02:11:25 +02:00
<nav role="navigation">
2020-04-14 19:56:54 +03:00
<h1><a href="../index.html">
<img src="../docs-src/Figures/Inform.png" height=72">
</a></h1>
<ul><li><a href="../compiler.html">compiler tools</a></li>
2020-03-19 02:11:25 +02:00
<li><a href="../other.html">other tools</a></li>
2020-04-14 19:56:54 +03:00
<li><a href="../extensions.html">extensions and kits</a></li>
2020-03-19 02:11:25 +02:00
<li><a href="../units.html">unit test tools</a></li>
2020-04-14 19:56:54 +03:00
</ul><h2>Extensions</h2><ul>
<li><a href="../basic_inform/index.html">basic_inform</a></li>
<li><a href="../standard_rules/index.html">standard_rules</a></li>
</ul><h2>Kits</h2><ul>
2020-03-19 02:11:25 +02:00
<li><a href="../BasicInformKit/index.html">BasicInformKit</a></li>
<li><a href="../BasicInformExtrasKit/index.html">BasicInformExtrasKit</a></li>
2020-04-14 19:56:54 +03:00
<li><a href="index.html"><span class="selectedlink">CommandParserKit</span></a></li>
2020-03-19 02:11:25 +02:00
<li><a href="../EnglishLanguageKit/index.html">EnglishLanguageKit</a></li>
<li><a href="../WorldModelKit/index.html">WorldModelKit</a></li>
2020-04-14 19:56:54 +03:00
</ul>
2020-03-19 02:11:25 +02:00
</nav>
<main role="main">
2020-04-14 19:56:54 +03:00
<!--Weave of 'Parser Template' generated by 7-->
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../extensions.html">Kits</a></li><li><a href="index.html">CommandParserKit</a></li><li><b>Parser Template</b></li></ul><p class="purpose">The parser for turning the text of the typed command into a proposed action by the player.</p>
<ul class="toc"><li><a href="S-prs.html#SP1">&#167;1. Grammar Line Variables</a></li><li><a href="S-prs.html#SP2">&#167;2. Grammar Token Variables</a></li><li><a href="S-prs.html#SP3">&#167;3. Match List Variables</a></li><li><a href="S-prs.html#SP4">&#167;4. Words</a></li><li><a href="S-prs.html#SP5">&#167;5. Snippets</a></li><li><a href="S-prs.html#SP6">&#167;6. Unpacking Grammar Lines</a></li><li><a href="S-prs.html#SP7">&#167;7. Keyboard Primitive</a></li><li><a href="S-prs.html#SP8">&#167;8. Reading the Command</a></li><li><a href="S-prs.html#SP9">&#167;9. Parser Proper</a></li><li><a href="S-prs.html#SP10">&#167;10. Parser Letter A</a></li><li><a href="S-prs.html#SP11">&#167;11. Parser Letter B</a></li><li><a href="S-prs.html#SP12">&#167;12. Parser Letter C</a></li><li><a href="S-prs.html#SP13">&#167;13. Parser Letter D</a></li><li><a href="S-prs.html#SP14">&#167;14. Parser Letter E</a></li><li><a href="S-prs.html#SP15">&#167;15. Parser Letter F</a></li><li><a href="S-prs.html#SP16">&#167;16. Parser Letter G</a></li><li><a href="S-prs.html#SP17">&#167;17. Parser Letter H</a></li><li><a href="S-prs.html#SP18">&#167;18. Parser Letter I</a></li><li><a href="S-prs.html#SP19">&#167;19. Parser Letter J</a></li><li><a href="S-prs.html#SP20">&#167;20. Parser Letter K</a></li><li><a href="S-prs.html#SP21">&#167;21. End of Parser Proper</a></li><li><a href="S-prs.html#SP22">&#167;22. Internal Rule</a></li><li><a href="S-prs.html#SP23">&#167;23. Parse Token</a></li><li><a href="S-prs.html#SP24">&#167;24. Parse Token Letter A</a></li><li><a href="S-prs.html#SP25">&#167;25. Parse Token Letter B</a></li><li><a href="S-prs.html#SP26">&#167;26. Parse Token Letter C</a></li><li><a href="S-prs.html#SP27">&#167;27. Parse Token Letter D</a></li><li><a href="S-prs.html#SP28">&#167;28. Parse Token Letter E</a></li><li><a href="S-prs.html#SP29">&#167;29. Parse Token Letter F</a></li><li><a href="S-prs.html#SP30">&#167;30. Descriptors</a></li><li><a href="S-prs.html#SP31">&#167;31. Parsing Descriptors</a></li><li><a href="S-prs.html#SP32">&#167;32. Preposition Chain</a></li><li><a href="S-prs.html#SP33">&#167;33. Creature</a></li><li><a href="S-prs.html#SP34">&#167;34. Noun Domain</a></li><li><a href="S-prs.html#SP35">&#167;35. Adjudicate</a></li><li><a href="S-prs.html#SP36">&#167;36. ReviseMulti</a></li><li><a href="S-prs.html#SP37">&#167;37. Match List</a></li><li><a href="S-prs.html#SP38">&#167;38. ScoreMatchL</a></li><li><a href="S-prs.html#SP39">&#167;39. BestGuess</a></li><li><a href="S-prs.html#SP40">&#167;40. SingleBestGuess</a></li><li><a href="S-prs.html#SP41">&#167;41. Identical</a></li><li><a href="S-prs.html#SP42">&#167;42. Print Command</a></li><li><a href="S-prs.html#SP43">&#167;43. CantSee</a></li><li><a href="S-prs.html#SP44">&#167;44. Multiple Object List</a></li><li><a href="S-prs.html#SP45">&#167;45. Scope</a></li><li><a href="S-prs.html#SP46">&#167;46. Scope Level 0</a></li><li><a href="S-prs.html#SP47">&#167;47. SearchScope</a></li><li><a href="S-prs.html#SP48">&#167;48. ScopeWithin</a></li><li><a href="S-prs.html#SP49">&#167;49. DoScopeActionAndRecurse</a></li><li><a href="S-prs.html#SP50">&#167;50. DoScopeAction</a></li><li><a href="S-prs.html#SP51">&#167;51. Parsing Object Names</a></li><li><a href="S-prs.html#SP52">&#167;52. TryGivenObject</a></li><li><a href="S-prs.html#SP53">&#167;53. Refers</a></li><li><a href="S-prs.html#SP54">&#167;54. NounWord</a></li><li><a href="S-prs.html#SP55">&#167;55. TryNumber</a></li><li><a href="S-prs.html#SP56">&#167;56. Gender</a></li><li><a href="S-prs.html#SP57">&#167;57. Noticing Plurals</a></li><li><a href="S-prs.html#SP58">&#167;58. Pronoun Handling</a></li><li><a href="S-prs.html#SP59">&#167;59. Yes/No Questions</a></li><li><a href="S-prs.html#SP60">&#167;60. Number Words</a></li><li><a href="S-prs.html#SP61">&#167;61. Choose Objects</a></li><li><a href="S-prs.html#SP62">&#167;62. Default Topic</a></li><li><a href="S-prs.html#SP63">&#167;63. Recognition-only-GPR</a></li><li><a href="S-prs.html#SP64">&#167;64. RunRoutines</a></li><li><a href="S-prs.html#SP65">&#167;65. Set
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Grammar Line Variables. </b>This is the I6 library parser in mostly untouched form: reformatted for template
file use, and with paragraph divisions, but otherwise hardly changed at all.
It is a complex algorithm but one which is known to produce good results for
the most part, and it is well understood from (at time of writing) fifteen
years of use. A few I7 additions have been made, but none disrupting the
basic method. For instance, I7's system for resolving ambiguities is
implemented by providing a <code class="display"><span class="extract">ChooseObjects</span></code> routine, just as a user of the
I6 library would do.
</p>
<p class="inwebparagraph">The I6 parser uses a huge number of global variables, which is not to modern
programming tastes: in the early days of Inform, the parser was essentially
written in assembly-language only lightly structured by C-like syntaxes,
and the Z-machine's 240 globals were more or less registers. The I6 library
made no distinction between which were "private" to the parser and which
allowed to be accessed by the user's code at large. The I7 template does
impose that boundary, though not very strongly: the variables defined
in "Output.i6t" are for general access, while the ones below should only
be read or written by the parser.
</p>
<pre class="display">
2020-04-07 03:06:09 +03:00
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">best_etype</span><span class="plain">; </span><span class="comment">Preferred error number so far</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">nextbest_etype</span><span class="plain">; </span><span class="comment">Preferred one, if ASKSCOPE_PE disallowed</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">parser_inflection</span><span class="plain">; </span><span class="comment">A property (usually "name") to find object names in</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">pattern</span><span class="plain"> --&gt; </span><span class="constant">32</span><span class="plain">; </span><span class="comment">For the current pattern match</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">pcount</span><span class="plain">; </span><span class="comment">and a marker within it</span>
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">pattern2</span><span class="plain"> --&gt; </span><span class="constant">32</span><span class="plain">; </span><span class="comment">And another, which stores the best match</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">pcount2</span><span class="plain">; </span><span class="comment">so far</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">line_ttype</span><span class="plain">--&gt;32; </span><span class="comment">For storing an analysed grammar line</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">line_tdata</span><span class="plain">--&gt;32;</span>
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">line_token</span><span class="plain">--&gt;32;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">nsns</span><span class="plain">; </span><span class="comment">Number of special_numbers entered so far</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">params_wanted</span><span class="plain">; </span><span class="comment">Number of parameters needed (which may change in parsing)</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">inferfrom</span><span class="plain">; </span><span class="comment">The point from which the rest of the command must be inferred</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">inferword</span><span class="plain">; </span><span class="comment">And the preposition inferred</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">dont_infer</span><span class="plain">; </span><span class="comment">Another dull flag</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">cobj_flag</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">oops_from</span><span class="plain">; </span><span class="comment">The "first mistake" word number</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">saved_oops</span><span class="plain">; </span><span class="comment">Used in working this out</span>
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">oops_workspace</span><span class="plain"> -&gt; </span><span class="constant">64</span><span class="plain">; </span><span class="comment">Used temporarily by "oops" routine</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">held_back_mode</span><span class="plain">; </span><span class="comment">Flag: is there some input from last time</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">hb_wn</span><span class="plain">; </span><span class="comment">left over? (And a save value for wn.)</span>
<span class="comment">(Used for full stops and "then".)</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">usual_grammar_after</span><span class="plain">; </span><span class="comment">Point from which usual grammar is parsed (it may vary from</span>
<span class="comment">the above if user's routines match multi-word verbs)</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. Grammar Token Variables. </b>More globals, but dealing at the level of individual tokens now.
</p>
<pre class="display">
2020-04-07 03:06:09 +03:00
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">PATTERN_NULL</span><span class="plain"> = </span><span class="constant">$ffff</span><span class="plain">; </span><span class="comment">Entry for a token producing no text</span>
2020-01-13 13:02:57 +02:00
2020-04-07 03:06:09 +03:00
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">found_ttype</span><span class="plain">; </span><span class="comment">Used to break up tokens into type</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">found_tdata</span><span class="plain">; </span><span class="comment">and data (by AnalyseToken)</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">token_filter</span><span class="plain">; </span><span class="comment">For noun filtering by user routines</span>
2020-01-13 13:02:57 +02:00
2020-04-07 03:06:09 +03:00
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">length_of_noun</span><span class="plain">; </span><span class="comment">Set by NounDomain to no of words in noun</span>
2020-01-13 13:02:57 +02:00
2020-04-07 03:06:09 +03:00
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">lookahead</span><span class="plain">; </span><span class="comment">The token after the one now being matched</span>
2020-01-13 13:02:57 +02:00
2020-04-07 03:06:09 +03:00
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">multi_mode</span><span class="plain">; </span><span class="comment">Multiple mode</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">multi_wanted</span><span class="plain">; </span><span class="comment">Number of things needed in multitude</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">multi_had</span><span class="plain">; </span><span class="comment">Number of things actually found</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">multi_context</span><span class="plain">; </span><span class="comment">What token the multi-obj was accepted for</span>
2020-01-13 13:02:57 +02:00
2020-04-07 03:06:09 +03:00
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">indef_type</span><span class="plain">; </span><span class="comment">Bit-map holding types of specification</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">indef_wanted</span><span class="plain">; </span><span class="comment">Number of items wanted (INDEF_ALL_WANTED for all)</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">INDEF_ALL_WANTED</span><span class="plain"> = </span><span class="constant">32767</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">indef_guess_p</span><span class="plain">; </span><span class="comment">Plural-guessing flag</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">indef_owner</span><span class="plain">; </span><span class="comment">Object which must hold these items</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">indef_cases</span><span class="plain">; </span><span class="comment">Possible gender and numbers of them</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">indef_possambig</span><span class="plain">; </span><span class="comment">Has a possibly dangerous assumption</span>
<span class="comment">been made about meaning of a descriptor?</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">indef_nspec_at</span><span class="plain">; </span><span class="comment">Word at which a number like "two" was parsed</span>
<span class="comment">(for backtracking)</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">allow_plurals</span><span class="plain">; </span><span class="comment">Whether plurals presently allowed or not</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">take_all_rule</span><span class="plain">; </span><span class="comment">Slightly different rules apply to "take all" than other uses</span>
<span class="comment">of multiple objects, to make adjudication produce more</span>
<span class="comment">pragmatically useful results</span>
<span class="comment">(Not a flag: possible values 0, 1, 2)</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">dict_flags_of_noun</span><span class="plain">; </span><span class="comment">Of the noun currently being parsed</span>
<span class="comment">(a bitmap in #dict_par1 format)</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">pronoun__word</span><span class="plain">; </span><span class="comment">Saved value</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">pronoun__obj</span><span class="plain">; </span><span class="comment">Saved value</span>
2020-04-14 19:56:54 +03:00
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">comma_word</span><span class="plain"> = </span><span class="character">'comma,'</span><span class="plain">; ! </span><span class="identifier">An</span><span class="plain"> </span><span class="string">"untypeable word"</span><span class="plain"> </span><span class="identifier">used</span><span class="plain"> </span><span class="reserved">to</span><span class="plain"> </span><span class="identifier">substitute</span>
2020-04-07 03:06:09 +03:00
<span class="comment">for commas in parse buffers</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. Match List Variables. </b>The most difficult tokens to match are those which refer to objects, since
there is such a variety of names which can be given to any individual object,
and we don't of course know which object or objects are meant. We store the
possibilities (up to <code class="display"><span class="extract">MATCH_LIST_WORDS</span></code>, anyway) in a data structure called the match list.
</p>
<pre class="display">
2020-04-07 03:06:09 +03:00
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">match_list</span><span class="plain"> --&gt; </span><span class="identifier">MATCH_LIST_WORDS</span><span class="plain">; </span><span class="comment">An array of matched objects so far</span>
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">match_classes</span><span class="plain"> --&gt; </span><span class="identifier">MATCH_LIST_WORDS</span><span class="plain">; </span><span class="comment">An array of equivalence classes for them</span>
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">match_scores</span><span class="plain"> --&gt; </span><span class="identifier">MATCH_LIST_WORDS</span><span class="plain">; </span><span class="comment">An array of match scores for them</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">number_matched</span><span class="plain">; </span><span class="comment">How many items in it? (0 means none)</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">number_of_classes</span><span class="plain">; </span><span class="comment">How many equivalence classes?</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">match_length</span><span class="plain">; </span><span class="comment">How many words long are these matches?</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">match_from</span><span class="plain">; </span><span class="comment">At what word of the input do they begin?</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Words. </b>The player's command is broken down into a numbered sequence of words, which
break at spaces or certain punctuation (see the DM4). The numbering runs
upwards from 1 to <code class="display"><span class="extract">WordCount()</span></code>. The following utility routines provide
access to words in the current command; because buffers have different
definitions in Z and Glulx, so these routines must vary also.
</p>
<p class="inwebparagraph">The actual text of each word is stored as a sequence of ZSCII values in
a <code class="display"><span class="extract">-&gt;</span></code> (byte) array, with address <code class="display"><span class="extract">WordAddress(x)</span></code> and length <code class="display"><span class="extract">WordLength(x)</span></code>.
</p>
<p class="inwebparagraph">We picture the command as a stream of words to be read one at a time, with
the global variable <code class="display"><span class="extract">wn</span></code> being the "current word" marker. <code class="display"><span class="extract">NextWord</span></code>, which
takes no arguments, returns:
</p>
<ul class="items"><li>(a) 0 if the word at <code class="display"><span class="extract">wn</span></code> is unrecognised by the dictionary or <code class="display"><span class="extract">wn</span></code> is out
of range,
</li><li>(b) <code class="display"><span class="extract">comma_word</span></code> if the word was a comma,
</li><li>(c) <code class="display"><span class="extract">THEN1__WD</span></code> if it was a full stop (because of the Infocom tradition that
a full stop abbreviates for the word "then": e.g., TAKE BOX. EAST was read
as two commands in succession),
</li><li>(d) or the dictionary address if the word was recognised.
</li></ul>
<p class="inwebparagraph">The current word marker <code class="display"><span class="extract">wn</span></code> is always advanced.
</p>
2020-04-14 19:56:54 +03:00
<p class="inwebparagraph"><code class="display"><span class="extract">NextWordStopped</span></code> does the same, but returns \(-1\) when <code class="display"><span class="extract">wn</span></code> is out of range
(e.g., by having advanced past the last word in the command).
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="plain">[ </span><span class="identifier">WordCount</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">parse</span><span class="plain">-&gt;1; ];</span>
<span class="plain">[ </span><span class="identifier">WordAddress</span><span class="plain"> </span><span class="identifier">wordnum</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">buffer</span><span class="plain"> + </span><span class="identifier">parse</span><span class="plain">-&gt;(</span><span class="identifier">wordnum</span><span class="plain">*4+1); ];</span>
<span class="plain">[ </span><span class="identifier">WordLength</span><span class="plain"> </span><span class="identifier">wordnum</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">parse</span><span class="plain">-&gt;(</span><span class="identifier">wordnum</span><span class="plain">*4); ];</span>
<span class="plain">#</span><span class="identifier">Ifnot</span><span class="plain">;</span>
<span class="plain">[ </span><span class="identifier">WordCount</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">parse</span><span class="plain">--&gt;0; ];</span>
<span class="plain">[ </span><span class="identifier">WordAddress</span><span class="plain"> </span><span class="identifier">wordnum</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">buffer</span><span class="plain"> + </span><span class="identifier">parse</span><span class="plain">--&gt;(</span><span class="identifier">wordnum</span><span class="plain">*3); ];</span>
2020-04-07 03:06:09 +03:00
<span class="plain">[ </span><span class="identifier">WordLength</span><span class="plain"> </span><span class="identifier">wordnum</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">parse</span><span class="plain">--&gt;(</span><span class="identifier">wordnum</span><span class="plain">*3 - </span><span class="constant">1</span><span class="plain">); ];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">;</span>
<span class="plain">[ </span><span class="identifier">WordFrom</span><span class="plain"> </span><span class="identifier">w</span><span class="plain"> </span><span class="identifier">p</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">j</span><span class="plain"> </span><span class="identifier">wc</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">; </span><span class="identifier">wc</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-&gt;1; </span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">w</span><span class="plain">*2-1;</span>
<span class="plain">#</span><span class="identifier">Ifnot</span><span class="plain">; </span><span class="identifier">wc</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">--&gt;0; </span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">w</span><span class="plain">*3-2; #</span><span class="identifier">Endif</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">w</span><span class="plain"> &lt; </span><span class="constant">1</span><span class="plain">) || (</span><span class="identifier">w</span><span class="plain"> &gt; </span><span class="identifier">wc</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">j</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain"> == </span><span class="character">',//'</span><span class="plain">) </span><span class="identifier">j</span><span class="plain"> = </span><span class="identifier">comma_word</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain"> == </span><span class="character">'.//'</span><span class="plain">) </span><span class="identifier">j</span><span class="plain"> = </span><span class="identifier">THEN1__WD</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">NextWord</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">j</span><span class="plain"> </span><span class="identifier">wc</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">; </span><span class="identifier">wc</span><span class="plain"> = </span><span class="identifier">parse</span><span class="plain">-&gt;1; </span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">*2-1;</span>
<span class="plain">#</span><span class="identifier">Ifnot</span><span class="plain">; </span><span class="identifier">wc</span><span class="plain"> = </span><span class="identifier">parse</span><span class="plain">--&gt;0; </span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">*3-2; #</span><span class="identifier">Endif</span><span class="plain">;</span>
<span class="identifier">wn</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">wn</span><span class="plain"> &lt; </span><span class="constant">2</span><span class="plain">) || (</span><span class="identifier">wn</span><span class="plain"> &gt; </span><span class="identifier">wc</span><span class="plain">+1)) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">j</span><span class="plain"> = </span><span class="identifier">parse</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain"> == </span><span class="character">',//'</span><span class="plain">) </span><span class="identifier">j</span><span class="plain"> = </span><span class="identifier">comma_word</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain"> == </span><span class="character">'.//'</span><span class="plain">) </span><span class="identifier">j</span><span class="plain"> = </span><span class="identifier">THEN1__WD</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">NextWordStopped</span><span class="plain"> </span><span class="identifier">wc</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">; </span><span class="identifier">wc</span><span class="plain"> = </span><span class="identifier">parse</span><span class="plain">-&gt;1; #</span><span class="identifier">Ifnot</span><span class="plain">; </span><span class="identifier">wc</span><span class="plain"> = </span><span class="identifier">parse</span><span class="plain">--&gt;0; #</span><span class="identifier">Endif</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">wn</span><span class="plain"> &lt; </span><span class="constant">1</span><span class="plain">) || (</span><span class="identifier">wn</span><span class="plain"> &gt; </span><span class="identifier">wc</span><span class="plain">)) { </span><span class="identifier">wn</span><span class="plain">++; </span><span class="reserved">return</span><span class="plain"> -1; }</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NextWord</span><span class="plain">();</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Snippets. </b>Although the idea is arguably implicit in I6, the formal concept of
"snippet" is new in I7. A snippet is a value which represents a word
range in the command most recently typed by the player. These words number
consecutively upwards from 1, as noted above. The correspondence between
2020-04-14 19:56:54 +03:00
\((w_1, w_2)\), the word range, and \(V\), the number used to represent it as
an I6 value, is:
2020-04-14 19:56:54 +03:00
$$ V = 100w_1 + (w_2-w_1+1) $$
so that the remainder mod 100 is the number of words in the range. We
2020-04-14 19:56:54 +03:00
require that \(1\leq w_1\leq w_2\leq N\), where \(N\) is the number of words in
the current player's command. The entire command is therefore represented by:
2020-04-14 19:56:54 +03:00
$$ C = 100 + N $$
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">PrintSnippet</span><span class="plain"> </span><span class="identifier">snip</span><span class="plain"> </span><span class="identifier">from</span><span class="plain"> </span><span class="reserved">to</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">w1</span><span class="plain"> </span><span class="identifier">w2</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">w1</span><span class="plain"> = </span><span class="identifier">snip</span><span class="plain">/100; </span><span class="identifier">w2</span><span class="plain"> = </span><span class="identifier">w1</span><span class="plain"> + (</span><span class="identifier">snip</span><span class="plain">%100) - </span><span class="constant">1</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">w2</span><span class="plain">&lt;</span><span class="identifier">w1</span><span class="plain">) || (</span><span class="identifier">w1</span><span class="plain">&lt;1) || (</span><span class="identifier">w2</span><span class="plain">&gt;</span><span class="identifier">WordCount</span><span class="plain">())) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">w1</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) &amp;&amp; (</span><span class="identifier">w2</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">)) </span><span class="reserved">rfalse</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">RunTimeProblem</span><span class="plain">(</span><span class="identifier">RTP_SAYINVALIDSNIPPET</span><span class="plain">, </span><span class="identifier">w1</span><span class="plain">, </span><span class="identifier">w2</span><span class="plain">);</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">from</span><span class="plain"> = </span><span class="identifier">WordAddress</span><span class="plain">(</span><span class="identifier">w1</span><span class="plain">); </span><span class="reserved">to</span><span class="plain"> = </span><span class="identifier">WordAddress</span><span class="plain">(</span><span class="identifier">w2</span><span class="plain">) + </span><span class="identifier">WordLength</span><span class="plain">(</span><span class="identifier">w2</span><span class="plain">) - </span><span class="constant">1</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=</span><span class="identifier">from</span><span class="plain">: </span><span class="identifier">i</span><span class="plain">&lt;=</span><span class="reserved">to</span><span class="plain">: </span><span class="identifier">i</span><span class="plain">++) </span><span class="reserved">print</span><span class="plain"> (</span><span class="identifier">char</span><span class="plain">) </span><span class="identifier">i</span><span class="plain">-&gt;0;</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">SpliceSnippet</span><span class="plain"> </span><span class="identifier">snip</span><span class="plain"> </span><span class="identifier">t</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">w1</span><span class="plain"> </span><span class="identifier">w2</span><span class="plain"> </span><span class="identifier">nextw</span><span class="plain"> </span><span class="identifier">at</span><span class="plain"> </span><span class="identifier">endsnippet</span><span class="plain"> </span><span class="identifier">newlen</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">w1</span><span class="plain"> = </span><span class="identifier">snip</span><span class="plain">/100; </span><span class="identifier">w2</span><span class="plain"> = </span><span class="identifier">w1</span><span class="plain"> + (</span><span class="identifier">snip</span><span class="plain">%100) - </span><span class="constant">1</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">w2</span><span class="plain">&lt;</span><span class="identifier">w1</span><span class="plain">) || (</span><span class="identifier">w1</span><span class="plain">&lt;1)) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">w1</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) &amp;&amp; (</span><span class="identifier">w2</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">RunTimeProblem</span><span class="plain">(</span><span class="identifier">RTP_SPLICEINVALIDSNIPPET</span><span class="plain">, </span><span class="identifier">w1</span><span class="plain">, </span><span class="identifier">w2</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="plain">@</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">say__p</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">say__pc</span><span class="plain">;</span>
<span class="identifier">nextw</span><span class="plain"> = </span><span class="identifier">w2</span><span class="plain"> + </span><span class="constant">1</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">at</span><span class="plain"> = </span><span class="identifier">WordAddress</span><span class="plain">(</span><span class="identifier">w1</span><span class="plain">) - </span><span class="identifier">buffer</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nextw</span><span class="plain"> &lt;= </span><span class="identifier">WordCount</span><span class="plain">()) </span><span class="identifier">endsnippet</span><span class="plain"> = </span><span class="constant">100</span><span class="plain">*</span><span class="identifier">nextw</span><span class="plain"> + (</span><span class="identifier">WordCount</span><span class="plain">() - </span><span class="identifier">nextw</span><span class="plain"> + </span><span class="constant">1</span><span class="plain">);</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">buffer2</span><span class="plain">--&gt;0 = </span><span class="constant">120</span><span class="plain">;</span>
<span class="identifier">newlen</span><span class="plain"> = </span><span class="identifier">VM_PrintToBuffer</span><span class="plain">(</span><span class="identifier">buffer2</span><span class="plain">, </span><span class="constant">120</span><span class="plain">, </span><span class="identifier">SpliceSnippet__TextPrinter</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">endsnippet</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0: (</span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">newlen</span><span class="plain">) &amp;&amp; (</span><span class="identifier">at</span><span class="plain">+</span><span class="identifier">i</span><span class="plain">&lt;120): </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">buffer</span><span class="plain">-&gt;(</span><span class="identifier">at</span><span class="plain">+</span><span class="identifier">i</span><span class="plain">) = </span><span class="identifier">buffer2</span><span class="plain">-&gt;(</span><span class="identifier">WORDSIZE</span><span class="plain">+</span><span class="identifier">i</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">; </span><span class="identifier">buffer</span><span class="plain">-&gt;1 = </span><span class="identifier">at</span><span class="plain">+</span><span class="identifier">i</span><span class="plain">; #</span><span class="identifier">ifnot</span><span class="plain">; </span><span class="identifier">buffer</span><span class="plain">--&gt;0 = </span><span class="identifier">at</span><span class="plain">+</span><span class="identifier">i</span><span class="plain">; #</span><span class="identifier">endif</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (:</span><span class="identifier">at</span><span class="plain">+</span><span class="identifier">i</span><span class="plain">&lt;120:</span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">buffer</span><span class="plain">-&gt;(</span><span class="identifier">at</span><span class="plain">+</span><span class="identifier">i</span><span class="plain">) = </span><span class="character">' '</span><span class="plain">;</span>
<span class="identifier">VM_Tokenise</span><span class="plain">(</span><span class="identifier">buffer</span><span class="plain">, </span><span class="identifier">parse</span><span class="plain">);</span>
<span class="identifier">players_command</span><span class="plain"> = </span><span class="constant">100</span><span class="plain"> + </span><span class="identifier">WordCount</span><span class="plain">();</span>
<span class="plain">@</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">say__pc</span><span class="plain">; @</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">say__p</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">SpliceSnippet__TextPrinter</span><span class="plain"> </span><span class="identifier">t</span><span class="plain"> </span><span class="identifier">endsnippet</span><span class="plain">;</span>
<span class="identifier">TEXT_TY_Say</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">endsnippet</span><span class="plain">) { </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" "</span><span class="plain">; </span><span class="identifier">PrintSnippet</span><span class="plain">(</span><span class="identifier">endsnippet</span><span class="plain">); }</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">SnippetIncludes</span><span class="plain"> </span><span class="identifier">test</span><span class="plain"> </span><span class="identifier">snippet</span><span class="plain"> </span><span class="identifier">w1</span><span class="plain"> </span><span class="identifier">w2</span><span class="plain"> </span><span class="identifier">wlen</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">w1</span><span class="plain"> = </span><span class="identifier">snippet</span><span class="plain">/100; </span><span class="identifier">w2</span><span class="plain"> = </span><span class="identifier">w1</span><span class="plain"> + (</span><span class="identifier">snippet</span><span class="plain">%100) - </span><span class="constant">1</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">w2</span><span class="plain">&lt;</span><span class="identifier">w1</span><span class="plain">) || (</span><span class="identifier">w1</span><span class="plain">&lt;1)) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">w1</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) &amp;&amp; (</span><span class="identifier">w2</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">)) </span><span class="reserved">rfalse</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">RunTimeProblem</span><span class="plain">(</span><span class="identifier">RTP_INCLUDEINVALIDSNIPPET</span><span class="plain">, </span><span class="identifier">w1</span><span class="plain">, </span><span class="identifier">w2</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="reserved">metaclass</span><span class="plain">(</span><span class="identifier">test</span><span class="plain">) == </span><span class="identifier">Routine</span><span class="plain">) {</span>
<span class="identifier">wlen</span><span class="plain"> = </span><span class="identifier">snippet</span><span class="plain">%100;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=</span><span class="identifier">w1</span><span class="plain">, </span><span class="identifier">j</span><span class="plain">=</span><span class="identifier">wlen</span><span class="plain">: </span><span class="identifier">j</span><span class="plain">&gt;0: </span><span class="identifier">i</span><span class="plain">++, </span><span class="identifier">j</span><span class="plain">--) {</span>
<span class="reserved">if</span><span class="plain"> (((</span><span class="identifier">test</span><span class="plain">)(</span><span class="identifier">i</span><span class="plain">, </span><span class="constant">0</span><span class="plain">)) ~= </span><span class="identifier">GPR_FAIL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">*100+</span><span class="identifier">wn</span><span class="plain">-</span><span class="identifier">i</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">SnippetMatches</span><span class="plain"> </span><span class="identifier">snippet</span><span class="plain"> </span><span class="identifier">topic_gpr</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="identifier">wn</span><span class="plain">=1;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">topic_gpr</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">rfalse</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="reserved">metaclass</span><span class="plain">(</span><span class="identifier">topic_gpr</span><span class="plain">) == </span><span class="identifier">Routine</span><span class="plain">) {</span>
<span class="identifier">rv</span><span class="plain"> = (</span><span class="identifier">topic_gpr</span><span class="plain">)(</span><span class="identifier">snippet</span><span class="plain">/100, </span><span class="identifier">snippet</span><span class="plain">%100);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rv</span><span class="plain"> ~= </span><span class="identifier">GPR_FAIL</span><span class="plain">) </span><span class="reserved">rtrue</span><span class="plain">;</span>
<span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">RunTimeProblem</span><span class="plain">(</span><span class="identifier">RTP_BADTOPIC</span><span class="plain">);</span>
<span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Unpacking Grammar Lines. </b>Grammar lines are sequences of tokens in an array built into the story file,
but in a format which differs depending on the virtual machine in use, so
the following code unpacks the data into more convenient if larger arrays
which are VM-independent.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">UnpackGrammarLine</span><span class="plain"> </span><span class="identifier">line_address</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">size</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;32 : </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">line_token</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">ENDIT_TOKEN</span><span class="plain">;</span>
<span class="identifier">line_ttype</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">ELEMENTARY_TT</span><span class="plain">;</span>
<span class="identifier">line_tdata</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">ENDIT_TOKEN</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="identifier">action_to_be</span><span class="plain"> = </span><span class="constant">256</span><span class="plain">*(</span><span class="identifier">line_address</span><span class="plain">-&gt;0) + </span><span class="identifier">line_address</span><span class="plain">-&gt;1;</span>
<span class="identifier">action_reversed</span><span class="plain"> = ((</span><span class="identifier">action_to_be</span><span class="plain"> &amp; </span><span class="constant">$400</span><span class="plain">) ~= </span><span class="constant">0</span><span class="plain">);</span>
<span class="identifier">action_to_be</span><span class="plain"> = </span><span class="identifier">action_to_be</span><span class="plain"> &amp; </span><span class="constant">$3ff</span><span class="plain">;</span>
<span class="identifier">line_address</span><span class="plain">--;</span>
<span class="identifier">size</span><span class="plain"> = </span><span class="constant">3</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Ifnot</span><span class="plain">; </span><span class="comment">GLULX</span>
2020-01-13 13:02:57 +02:00
<span class="plain">@</span><span class="identifier">aloads</span><span class="plain"> </span><span class="identifier">line_address</span><span class="plain"> </span><span class="constant">0</span><span class="plain"> </span><span class="identifier">action_to_be</span><span class="plain">;</span>
<span class="identifier">action_reversed</span><span class="plain"> = (((</span><span class="identifier">line_address</span><span class="plain">-&gt;2) &amp; </span><span class="constant">1</span><span class="plain">) ~= </span><span class="constant">0</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">line_address</span><span class="plain"> = </span><span class="identifier">line_address</span><span class="plain"> - </span><span class="constant">2</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">size</span><span class="plain"> = </span><span class="constant">5</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">;</span>
<span class="identifier">params_wanted</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : : </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">line_address</span><span class="plain"> = </span><span class="identifier">line_address</span><span class="plain"> + </span><span class="identifier">size</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">line_address</span><span class="plain">-&gt;0 == </span><span class="identifier">ENDIT_TOKEN</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="identifier">line_token</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">line_address</span><span class="plain">;</span>
<span class="identifier">AnalyseToken</span><span class="plain">(</span><span class="identifier">line_address</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">found_ttype</span><span class="plain"> ~= </span><span class="identifier">PREPOSITION_TT</span><span class="plain">) </span><span class="identifier">params_wanted</span><span class="plain">++;</span>
<span class="identifier">line_ttype</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">found_ttype</span><span class="plain">;</span>
<span class="identifier">line_tdata</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">found_tdata</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">line_address</span><span class="plain"> + </span><span class="constant">1</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">AnalyseToken</span><span class="plain"> </span><span class="identifier">token</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">token</span><span class="plain"> == </span><span class="identifier">ENDIT_TOKEN</span><span class="plain">) {</span>
<span class="identifier">found_ttype</span><span class="plain"> = </span><span class="identifier">ELEMENTARY_TT</span><span class="plain">;</span>
<span class="identifier">found_tdata</span><span class="plain"> = </span><span class="identifier">ENDIT_TOKEN</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">found_ttype</span><span class="plain"> = (</span><span class="identifier">token</span><span class="plain">-&gt;0) &amp; </span><span class="constant">$$1111</span><span class="plain">;</span>
<span class="identifier">found_tdata</span><span class="plain"> = (</span><span class="identifier">token</span><span class="plain">+1)--&gt;0;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Keyboard Primitive. </b>This is the primitive routine to read from the keyboard: it usually delegates
this to a routine specific to the virtual machine being used, but sometimes
uses a hacked version to allow TEST commands to work. (When a TEST is running,
the text in the walk-through provided is fed into the buffer as if it had
been typed at the keyboard.)
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">KeyboardPrimitive</span><span class="plain"> </span><span class="identifier">a_buffer</span><span class="plain"> </span><span class="identifier">a_table</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TestKeyboardPrimitive</span><span class="plain">(</span><span class="identifier">a_buffer</span><span class="plain">, </span><span class="identifier">a_table</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">VM_ReadKeyboard</span><span class="plain">(</span><span class="identifier">a_buffer</span><span class="plain">, </span><span class="identifier">a_table</span><span class="plain">);</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. Reading the Command. </b>The <code class="display"><span class="extract">Keyboard</span></code> routine actually receives the player's words, putting the
words in <code class="display"><span class="extract">a_buffer</span></code> and their dictionary addresses in <code class="display"><span class="extract">a_table</span></code>. It is
assumed that the table is the same one on each (standard) call. Much
of the code handles the OOPS and UNDO commands, which are not actions and
do not pass through the rest of the parser. The undo state is saved &mdash;
it is essentially an internal saved game, in the VM interpreter's memory
rather than in an external file &mdash; and note that this is therefore also
where execution picks up if an UNDO has been typed. Since UNDO recreates
the former machine state perfectly, it might seem impossible to tell that
an UNDO had occurred, but in fact the VM passes information back in the
form of a return code from the relevant instruction, and this allows us
to detect an undo. (We deal with it by printing the current location and
asking another command.)
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">Keyboard</span></code> can also be used by miscellaneous routines in the game to ask
yes/no questions and the like, without invoking the rest of the parser.
</p>
<p class="inwebparagraph">The return value is the number of words typed.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">Keyboard</span><span class="plain"> </span><span class="identifier">a_buffer</span><span class="plain"> </span><span class="identifier">a_table</span><span class="plain"> </span><span class="identifier">nw</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">w</span><span class="plain"> </span><span class="identifier">w2</span><span class="plain"> </span><span class="identifier">x1</span><span class="plain"> </span><span class="identifier">x2</span><span class="plain">;</span>
<span class="identifier">sline1</span><span class="plain"> = </span><span class="identifier">score</span><span class="plain">; </span><span class="identifier">sline2</span><span class="plain"> = </span><span class="identifier">turns</span><span class="plain">;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="reserved">true</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Save the start of the buffer, in case "oops" needs to restore it</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;64 : </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">oops_workspace</span><span class="plain">-&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">a_buffer</span><span class="plain">-&gt;</span><span class="identifier">i</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">In case of an array entry corruption that shouldn't happen, but would be</span>
<span class="comment">disastrous if it did:</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="identifier">a_buffer</span><span class="plain">-&gt;0 = </span><span class="identifier">INPUT_BUFFER_LEN</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">a_table</span><span class="plain">-&gt;0 = </span><span class="constant">15</span><span class="plain">; </span><span class="comment">Allow to split input into this many words</span>
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">TARGET_</span>
2020-01-13 13:02:57 +02:00
2020-04-07 03:06:09 +03:00
<span class="comment">Print the prompt, and read in the words and dictionary addresses</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">PrintPrompt</span><span class="plain">();</span>
<span class="identifier">DrawStatusLine</span><span class="plain">();</span>
<span class="identifier">KeyboardPrimitive</span><span class="plain">(</span><span class="identifier">a_buffer</span><span class="plain">, </span><span class="identifier">a_table</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Set nw to the number of words</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">; </span><span class="identifier">nw</span><span class="plain"> = </span><span class="identifier">a_table</span><span class="plain">-&gt;1; #</span><span class="identifier">Ifnot</span><span class="plain">; </span><span class="identifier">nw</span><span class="plain"> = </span><span class="identifier">a_table</span><span class="plain">--&gt;0; #</span><span class="identifier">Endif</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">If the line was blank, get a fresh line</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nw</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="plain">@</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">etype</span><span class="plain">; </span><span class="identifier">etype</span><span class="plain"> = </span><span class="identifier">BLANKLINE_PE</span><span class="plain">;</span>
<span class="identifier">players_command</span><span class="plain"> = </span><span class="constant">100</span><span class="plain">;</span>
<span class="identifier">BeginActivity</span><span class="plain">(</span><span class="identifier">PRINTING_A_PARSER_ERROR_ACT</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ForActivity</span><span class="plain">(</span><span class="identifier">PRINTING_A_PARSER_ERROR_ACT</span><span class="plain">) == </span><span class="reserved">false</span><span class="plain">) {</span>
<span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'X'</span><span class="plain">, </span><span class="identifier">noun</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">EndActivity</span><span class="plain">(</span><span class="identifier">PRINTING_A_PARSER_ERROR_ACT</span><span class="plain">);</span>
<span class="plain">@</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">etype</span><span class="plain">;</span>
<span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Unless the opening word was OOPS, return</span>
<span class="comment">Conveniently, a_table--&gt;1 is the first word on both the Z-machine and Glulx</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">w</span><span class="plain"> = </span><span class="identifier">a_table</span><span class="plain">--&gt;1;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">w</span><span class="plain"> == </span><span class="identifier">OOPS1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">OOPS2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">OOPS3__WD</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">oops_from</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) { </span><span class="identifier">PARSER_COMMAND_INTERNAL_RM</span><span class="plain">(</span><span class="character">'A'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; </span><span class="reserved">continue</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nw</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) { </span><span class="identifier">PARSER_COMMAND_INTERNAL_RM</span><span class="plain">(</span><span class="character">'B'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; </span><span class="reserved">continue</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nw</span><span class="plain"> &gt; </span><span class="constant">2</span><span class="plain">) { </span><span class="identifier">PARSER_COMMAND_INTERNAL_RM</span><span class="plain">(</span><span class="character">'C'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; </span><span class="reserved">continue</span><span class="plain">; }</span>
2020-04-07 03:06:09 +03:00
<span class="comment">So now we know: there was a previous mistake, and the player has</span>
<span class="comment">attempted to correct a single word of it.</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">INPUT_BUFFER_LEN</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">buffer2</span><span class="plain">-&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">a_buffer</span><span class="plain">-&gt;</span><span class="identifier">i</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">x1</span><span class="plain"> = </span><span class="identifier">a_table</span><span class="plain">-&gt;9; </span><span class="comment">Start of word following "oops"</span>
<span class="identifier">x2</span><span class="plain"> = </span><span class="identifier">a_table</span><span class="plain">-&gt;8; </span><span class="comment">Length of word following "oops"</span>
<span class="plain">#</span><span class="identifier">Ifnot</span><span class="plain">; </span><span class="comment">TARGET_GLULX</span>
<span class="identifier">x1</span><span class="plain"> = </span><span class="identifier">a_table</span><span class="plain">--&gt;6; </span><span class="comment">Start of word following "oops"</span>
<span class="identifier">x2</span><span class="plain"> = </span><span class="identifier">a_table</span><span class="plain">--&gt;5; </span><span class="comment">Length of word following "oops"</span>
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">TARGET_</span>
<span class="comment">Repair the buffer to the text that was in it before the "oops"</span>
<span class="comment">was typed:</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;64 : </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">a_buffer</span><span class="plain">-&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">oops_workspace</span><span class="plain">-&gt;</span><span class="identifier">i</span><span class="plain">;</span>
<span class="identifier">VM_Tokenise</span><span class="plain">(</span><span class="identifier">a_buffer</span><span class="plain">,</span><span class="identifier">a_table</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Work out the position in the buffer of the word to be corrected:</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">w</span><span class="plain"> = </span><span class="identifier">a_table</span><span class="plain">-&gt;(4*</span><span class="identifier">oops_from</span><span class="plain"> + </span><span class="constant">1</span><span class="plain">); </span><span class="comment">Start of word to go</span>
<span class="identifier">w2</span><span class="plain"> = </span><span class="identifier">a_table</span><span class="plain">-&gt;(4*</span><span class="identifier">oops_from</span><span class="plain">); </span><span class="comment">Length of word to go</span>
<span class="plain">#</span><span class="identifier">Ifnot</span><span class="plain">; </span><span class="comment">TARGET_GLULX</span>
<span class="identifier">w</span><span class="plain"> = </span><span class="identifier">a_table</span><span class="plain">--&gt;(3*</span><span class="identifier">oops_from</span><span class="plain">); </span><span class="comment">Start of word to go</span>
<span class="identifier">w2</span><span class="plain"> = </span><span class="identifier">a_table</span><span class="plain">--&gt;(3*</span><span class="identifier">oops_from</span><span class="plain"> - </span><span class="constant">1</span><span class="plain">); </span><span class="comment">Length of word to go</span>
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">TARGET_</span>
<span class="comment">Write spaces over the word to be corrected:</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">w2</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">a_buffer</span><span class="plain">-&gt;(</span><span class="identifier">i</span><span class="plain">+</span><span class="identifier">w</span><span class="plain">) = </span><span class="character">' '</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">w2</span><span class="plain"> &lt; </span><span class="identifier">x2</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="comment">If the replacement is longer than the original, move up...</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=</span><span class="identifier">INPUT_BUFFER_LEN</span><span class="plain">-1 : </span><span class="identifier">i</span><span class="plain">&gt;=</span><span class="identifier">w</span><span class="plain">+</span><span class="identifier">x2</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">--)</span>
<span class="identifier">a_buffer</span><span class="plain">-&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">a_buffer</span><span class="plain">-&gt;(</span><span class="identifier">i</span><span class="plain">-</span><span class="identifier">x2</span><span class="plain">+</span><span class="identifier">w2</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="comment">...increasing buffer size accordingly.</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="identifier">a_buffer</span><span class="plain">-&gt;1 = (</span><span class="identifier">a_buffer</span><span class="plain">-&gt;1) + (</span><span class="identifier">x2</span><span class="plain">-</span><span class="identifier">w2</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Ifnot</span><span class="plain">; </span><span class="comment">TARGET_GLULX</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">a_buffer</span><span class="plain">--&gt;0 = (</span><span class="identifier">a_buffer</span><span class="plain">--&gt;0) + (</span><span class="identifier">x2</span><span class="plain">-</span><span class="identifier">w2</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">TARGET_</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Write the correction in:</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">x2</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">a_buffer</span><span class="plain">-&gt;(</span><span class="identifier">i</span><span class="plain">+</span><span class="identifier">w</span><span class="plain">) = </span><span class="identifier">buffer2</span><span class="plain">-&gt;(</span><span class="identifier">i</span><span class="plain">+</span><span class="identifier">x1</span><span class="plain">);</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">VM_Tokenise</span><span class="plain">(</span><span class="identifier">a_buffer</span><span class="plain">, </span><span class="identifier">a_table</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">; </span><span class="identifier">nw</span><span class="plain"> = </span><span class="identifier">a_table</span><span class="plain">-&gt;1; #</span><span class="identifier">Ifnot</span><span class="plain">; </span><span class="identifier">nw</span><span class="plain"> = </span><span class="identifier">a_table</span><span class="plain">--&gt;0; #</span><span class="identifier">Endif</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">nw</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Undo handling</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">w</span><span class="plain"> == </span><span class="identifier">UNDO1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">UNDO2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">UNDO3__WD</span><span class="plain">) &amp;&amp; (</span><span class="identifier">nw</span><span class="plain">==1)) {</span>
<span class="identifier">Perform_Undo</span><span class="plain">();</span>
<span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">VM_Save_Undo</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TEMPLATE_CONFIGURATION_BITMAP</span><span class="plain"> &amp; </span><span class="identifier">PREVENT_UNDO_TCBIT</span><span class="plain">) </span><span class="identifier">undo_flag</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">undo_flag</span><span class="plain"> = </span><span class="constant">2</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == -1) </span><span class="identifier">undo_flag</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">undo_flag</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="constant">2</span><span class="plain">) {</span>
<span class="identifier">VM_RestoreWindowColours</span><span class="plain">();</span>
<span class="identifier">VM_Style</span><span class="plain">(</span><span class="identifier">SUBHEADER_VMSTY</span><span class="plain">);</span>
<span class="identifier">SL_Location</span><span class="plain">(); </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">print (name) location, "^";</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">VM_Style</span><span class="plain">(</span><span class="identifier">NORMAL_VMSTY</span><span class="plain">);</span>
<span class="identifier">IMMEDIATELY_UNDO_RM</span><span class="plain">(</span><span class="character">'E'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">;</span>
<span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">nw</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Parser Proper. </b>The main parser routine is something of a leviathan, and it has traditionally
been divided into 11 lettered parts:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(A) Get the input, do OOPS and AGAIN
</li><li>(B) Is it a direction, and so an implicit GO? If so go to (K)
</li><li>(C) Is anyone being addressed?
</li><li>(D) Get the command verb: try all the syntax lines for that verb
</li><li>(E) Break down a syntax line into analysed tokens
</li><li>(F) Look ahead for advance warning for <code class="display"><span class="extract">multiexcept</span></code>/<code class="display"><span class="extract">multiinside</span></code>
</li><li>(G) Parse each token in turn (calling <code class="display"><span class="extract">ParseToken</span></code> to do most of the work)
</li><li>(H) Cheaply parse otherwise unrecognised conversation and return
</li><li>(I) Print best possible error message
</li><li>(J) Retry the whole lot
</li><li>(K) Last thing: check for THEN and further instructions(s), return.
</li></ul>
<p class="inwebparagraph">This lettering has been preserved here, with the code under each letter
now being the body of "Parser Letter A", "Parser Letter B" and so on.
</p>
<p class="inwebparagraph">Note that there are three different places where a return can happen.
The routine returns only when a sensible request has been made; for a
fairly thorough description of its output, which is written into the
<code class="display"><span class="extract">parser_results</span></code> array and also into several globals (see "OrderOfPlay.i6t").
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">Parser__parse</span>
<span class="identifier">syntax</span><span class="plain"> </span><span class="identifier">line</span><span class="plain"> </span><span class="identifier">num_lines</span><span class="plain"> </span><span class="identifier">line_address</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">j</span><span class="plain"> </span><span class="identifier">k</span><span class="plain"> </span><span class="identifier">token</span><span class="plain"> </span><span class="identifier">l</span><span class="plain"> </span><span class="identifier">m</span><span class="plain"> </span><span class="identifier">inferred_go</span><span class="plain">;</span>
<span class="identifier">cobj_flag</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">ACTION_PRES</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">NO_INPS_PRES</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP1_PRES</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP2_PRES</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">meta</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. Parser Letter A. </b>Get the input, do OOPS and AGAIN.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">held_back_mode</span><span class="plain">) {</span>
<span class="identifier">held_back_mode</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">; </span><span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">hb_wn</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">verb_wordnum</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">WordAddress</span><span class="plain">(</span><span class="identifier">verb_wordnum</span><span class="plain">); </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">WordAddress</span><span class="plain">(1);</span>
<span class="identifier">j</span><span class="plain"> = </span><span class="identifier">WordAddress</span><span class="plain">(</span><span class="identifier">wn</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">&lt;=</span><span class="identifier">j</span><span class="plain">) </span><span class="reserved">for</span><span class="plain"> (: </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">j</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">i</span><span class="plain">-&gt;0 = </span><span class="character">' '</span><span class="plain">;</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">NextWord</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="identifier">AGAIN1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">AGAIN2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">AGAIN3__WD</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Delete the words "then again" from the again buffer,</span>
<span class="comment">in which we have just realised that it must occur:</span>
<span class="comment">prevents an infinite loop on "i. again"</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">WordAddress</span><span class="plain">(</span><span class="identifier">wn</span><span class="plain">-2)-</span><span class="identifier">buffer</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wn</span><span class="plain"> &gt; </span><span class="identifier">num_words</span><span class="plain">) </span><span class="identifier">j</span><span class="plain"> = </span><span class="identifier">INPUT_BUFFER_LEN</span><span class="plain">-1;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">j</span><span class="plain"> = </span><span class="identifier">WordAddress</span><span class="plain">(</span><span class="identifier">wn</span><span class="plain">)-</span><span class="identifier">buffer</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (: </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">j</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">buffer3</span><span class="plain">-&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="character">' '</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">VM_Tokenise</span><span class="plain">(</span><span class="identifier">buffer</span><span class="plain">, </span><span class="identifier">parse</span><span class="plain">);</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">ReParse</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> .</span><span class="identifier">ReType</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">cobj_flag</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">actors_location</span><span class="plain"> = </span><span class="identifier">ScopeCeiling</span><span class="plain">(</span><span class="identifier">player</span><span class="plain">);</span>
<span class="identifier">BeginActivity</span><span class="plain">(</span><span class="identifier">READING_A_COMMAND_ACT</span><span class="plain">); </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ForActivity</span><span class="plain">(</span><span class="identifier">READING_A_COMMAND_ACT</span><span class="plain">)==</span><span class="reserved">false</span><span class="plain">) {</span>
<span class="identifier">Keyboard</span><span class="plain">(</span><span class="identifier">buffer</span><span class="plain">,</span><span class="identifier">parse</span><span class="plain">);</span>
<span class="identifier">num_words</span><span class="plain"> = </span><span class="identifier">WordCount</span><span class="plain">(); </span><span class="identifier">players_command</span><span class="plain"> = </span><span class="constant">100</span><span class="plain"> + </span><span class="identifier">num_words</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">EndActivity</span><span class="plain">(</span><span class="identifier">READING_A_COMMAND_ACT</span><span class="plain">)) </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">ReType</span><span class="plain">;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> .</span><span class="identifier">ReParse</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">parser_inflection</span><span class="plain"> = </span><span class="identifier">name</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Initially assume the command is aimed at the player, and the verb</span>
<span class="comment">is the first word</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">num_words</span><span class="plain"> = </span><span class="identifier">WordCount</span><span class="plain">(); </span><span class="identifier">players_command</span><span class="plain"> = </span><span class="constant">100</span><span class="plain"> + </span><span class="identifier">num_words</span><span class="plain">;</span>
<span class="identifier">wn</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="identifier">inferred_go</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
<span class="identifier">LanguageToInformese</span><span class="plain">();</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Re-tokenise:</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">VM_Tokenise</span><span class="plain">(</span><span class="identifier">buffer</span><span class="plain">,</span><span class="identifier">parse</span><span class="plain">);</span>
<span class="identifier">num_words</span><span class="plain"> = </span><span class="identifier">WordCount</span><span class="plain">(); </span><span class="identifier">players_command</span><span class="plain"> = </span><span class="constant">100</span><span class="plain"> + </span><span class="identifier">num_words</span><span class="plain">;</span>
<span class="identifier">k</span><span class="plain">=0;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">2</span><span class="plain">) {</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"[ "</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">num_words</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="identifier">j</span><span class="plain"> = </span><span class="identifier">parse</span><span class="plain">--&gt;(</span><span class="identifier">i</span><span class="plain">*2 + </span><span class="constant">1</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Ifnot</span><span class="plain">; </span><span class="comment">TARGET_GLULX</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">j</span><span class="plain"> = </span><span class="identifier">parse</span><span class="plain">--&gt;(</span><span class="identifier">i</span><span class="plain">*3 + </span><span class="constant">1</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">TARGET_</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">k</span><span class="plain"> = </span><span class="identifier">WordAddress</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">+1);</span>
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">WordLength</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">+1);</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"~"</span><span class="plain">; </span><span class="reserved">for</span><span class="plain"> (</span><span class="identifier">m</span><span class="plain">=0 : </span><span class="identifier">m</span><span class="plain">&lt;</span><span class="identifier">l</span><span class="plain"> : </span><span class="identifier">m</span><span class="plain">++) </span><span class="reserved">print</span><span class="plain"> (</span><span class="identifier">char</span><span class="plain">) </span><span class="identifier">k</span><span class="plain">-&gt;</span><span class="identifier">m</span><span class="plain">; </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"~ "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"?"</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">UnsignedCompare</span><span class="plain">(</span><span class="identifier">j</span><span class="plain">, </span><span class="identifier">HDR_DICTIONARY</span><span class="plain">--&gt;0) &gt;= </span><span class="constant">0</span><span class="plain"> &amp;&amp;</span>
<span class="identifier">UnsignedCompare</span><span class="plain">(</span><span class="identifier">j</span><span class="plain">, </span><span class="identifier">HDR_HIGHMEMORY</span><span class="plain">--&gt;0) &lt; </span><span class="constant">0</span><span class="plain">)</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="reserved">print</span><span class="plain"> (</span><span class="identifier">address</span><span class="plain">) </span><span class="identifier">j</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">print</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Ifnot</span><span class="plain">; </span><span class="comment">TARGET_GLULX</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">-&gt;0 == </span><span class="constant">$60</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> (</span><span class="identifier">address</span><span class="plain">) </span><span class="identifier">j</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">print</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">TARGET_</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> ~= </span><span class="identifier">num_words</span><span class="plain">-1) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" / "</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">print</span><span class="plain"> </span><span class="string">" ]^"</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">verb_wordnum</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="identifier">actor</span><span class="plain"> = </span><span class="identifier">player</span><span class="plain">;</span>
<span class="identifier">actors_location</span><span class="plain"> = </span><span class="identifier">ScopeCeiling</span><span class="plain">(</span><span class="identifier">player</span><span class="plain">);</span>
<span class="identifier">usual_grammar_after</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> .</span><span class="identifier">AlmostReParse</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">scope_token</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">action_to_be</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Begin from what we currently think is the verb word</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> .</span><span class="identifier">BeginCommand</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">verb_wordnum</span><span class="plain">;</span>
<span class="identifier">verb_word</span><span class="plain"> = </span><span class="identifier">NextWordStopped</span><span class="plain">();</span>
2020-04-07 03:06:09 +03:00
<span class="comment">If there's no input here, we must have something like "person,".</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">verb_word</span><span class="plain"> == -1) {</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">best_etype</span><span class="plain"> = </span><span class="identifier">STUCK_PE</span><span class="plain">; </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">GiveError</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">verb_word</span><span class="plain"> == </span><span class="identifier">comma_word</span><span class="plain">) {</span>
<span class="identifier">best_etype</span><span class="plain"> = </span><span class="identifier">COMMABEGIN_PE</span><span class="plain">; </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">GiveError</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Now try for "again" or "g", which are special cases: don't allow "again" if nothing</span>
<span class="comment">has previously been typed; simply copy the previous text across</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">verb_word</span><span class="plain"> == </span><span class="identifier">AGAIN2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">AGAIN3__WD</span><span class="plain">) </span><span class="identifier">verb_word</span><span class="plain"> = </span><span class="identifier">AGAIN1__WD</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">verb_word</span><span class="plain"> == </span><span class="identifier">AGAIN1__WD</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">actor</span><span class="plain"> ~= </span><span class="identifier">player</span><span class="plain">) {</span>
<span class="identifier">best_etype</span><span class="plain"> = </span><span class="identifier">ANIMAAGAIN_PE</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">GiveError</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">buffer3</span><span class="plain">-&gt;1 == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">PARSER_COMMAND_INTERNAL_RM</span><span class="plain">(</span><span class="character">'D'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">ReType</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Ifnot</span><span class="plain">; </span><span class="comment">TARGET_GLULX</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">buffer3</span><span class="plain">--&gt;0 == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">PARSER_COMMAND_INTERNAL_RM</span><span class="plain">(</span><span class="character">'D'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">ReType</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">TARGET_</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">INPUT_BUFFER_LEN</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">buffer</span><span class="plain">-&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">buffer3</span><span class="plain">-&gt;</span><span class="identifier">i</span><span class="plain">;</span>
<span class="identifier">VM_Tokenise</span><span class="plain">(</span><span class="identifier">buffer</span><span class="plain">,</span><span class="identifier">parse</span><span class="plain">);</span>
<span class="identifier">num_words</span><span class="plain"> = </span><span class="identifier">WordCount</span><span class="plain">(); </span><span class="identifier">players_command</span><span class="plain"> = </span><span class="constant">100</span><span class="plain"> + </span><span class="identifier">num_words</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">ReParse</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Save the present input in case of an "again" next time</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">verb_word</span><span class="plain"> ~= </span><span class="identifier">AGAIN1__WD</span><span class="plain">)</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">INPUT_BUFFER_LEN</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">buffer3</span><span class="plain">-&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">buffer</span><span class="plain">-&gt;</span><span class="identifier">i</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">usual_grammar_after</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">j</span><span class="plain"> = </span><span class="identifier">verb_wordnum</span><span class="plain">;</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">RunRoutines</span><span class="plain">(</span><span class="identifier">actor</span><span class="plain">, </span><span class="identifier">grammar</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">2</span><span class="plain"> &amp;&amp; </span><span class="identifier">actor</span><span class="plain">.</span><span class="identifier">grammar</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" [Grammar property returned "</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="string">"]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">i</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">1</span><span class="plain">) &amp;&amp; (</span><span class="identifier">VM_InvalidDictionaryAddress</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">))) {</span>
<span class="identifier">usual_grammar_after</span><span class="plain"> = </span><span class="identifier">verb_wordnum</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">=-</span><span class="identifier">i</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) {</span>
<span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">ACTION_PRES</span><span class="plain"> = </span><span class="identifier">action</span><span class="plain">;</span>
<span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">NO_INPS_PRES</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP1_PRES</span><span class="plain"> = </span><span class="identifier">noun</span><span class="plain">;</span>
<span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP2_PRES</span><span class="plain"> = </span><span class="identifier">second</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">noun</span><span class="plain">) </span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">NO_INPS_PRES</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">second</span><span class="plain">) </span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">NO_INPS_PRES</span><span class="plain"> = </span><span class="constant">2</span><span class="plain">;</span>
<span class="reserved">rtrue</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) { </span><span class="identifier">verb_word</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">; </span><span class="identifier">wn</span><span class="plain">--; </span><span class="identifier">verb_wordnum</span><span class="plain">--; }</span>
<span class="reserved">else</span><span class="plain"> { </span><span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">verb_wordnum</span><span class="plain">; </span><span class="identifier">verb_word</span><span class="plain"> = </span><span class="identifier">NextWord</span><span class="plain">(); }</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">usual_grammar_after</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. Parser Letter B. </b>Is the command a direction name, and so an implicit GO? If so, go to (K).
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">verb_word</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">; </span><span class="identifier">verb_word</span><span class="plain"> = </span><span class="identifier">LanguageIsVerb</span><span class="plain">(</span><span class="identifier">buffer</span><span class="plain">, </span><span class="identifier">parse</span><span class="plain">, </span><span class="identifier">verb_wordnum</span><span class="plain">);</span>
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">If the first word is not listed as a verb, it must be a direction</span>
<span class="comment">or the name of someone to talk to</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">verb_word</span><span class="plain"> == </span><span class="constant">0</span><span class="plain"> || ((</span><span class="identifier">verb_word</span><span class="plain">-&gt;#</span><span class="identifier">dict_par1</span><span class="plain">) &amp; </span><span class="constant">1</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="comment">So is the first word an object contained in the special object "compass"</span>
<span class="comment">(i.e., a direction)? This needs use of NounDomain, a routine which</span>
<span class="comment">does the object matching, returning the object number, or 0 if none found,</span>
<span class="comment">or REPARSE_CODE if it has restructured the parse table so the whole parse</span>
<span class="comment">must be begun again...</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">verb_wordnum</span><span class="plain">; </span><span class="identifier">indef_mode</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">; </span><span class="identifier">token_filter</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">parameters</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">@</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">actor</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">action</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">action_to_be</span><span class="plain">;</span>
<span class="identifier">actor</span><span class="plain"> = </span><span class="identifier">player</span><span class="plain">; </span><span class="identifier">meta</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">; </span><span class="identifier">action</span><span class="plain"> = ##</span><span class="identifier">Go</span><span class="plain">; </span><span class="identifier">action_to_be</span><span class="plain"> = ##</span><span class="identifier">Go</span><span class="plain">;</span>
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">NounDomain</span><span class="plain">(</span><span class="identifier">Compass</span><span class="plain">, </span><span class="constant">0</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="plain">@</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">action_to_be</span><span class="plain">; @</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">action</span><span class="plain">; @</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">actor</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="identifier">REPARSE_CODE</span><span class="plain">) </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">ReParse</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">If it is a direction, send back the results:</span>
<span class="comment">action=GoSub, no of arguments=1, argument 1=the direction.</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">l</span><span class="plain">~=0) &amp;&amp; (</span><span class="identifier">l</span><span class="plain"> </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">K3_direction</span><span class="plain">)) {</span>
<span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">ACTION_PRES</span><span class="plain"> = ##</span><span class="identifier">Go</span><span class="plain">;</span>
<span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">NO_INPS_PRES</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP1_PRES</span><span class="plain"> = </span><span class="identifier">l</span><span class="plain">;</span>
<span class="identifier">inferred_go</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">LookForMore</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="plain">} </span><span class="comment">end of first-word-not-a-verb</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. Parser Letter C. </b>Is anyone being addressed?
</p>
<pre class="display">
2020-04-07 03:06:09 +03:00
<span class="comment">Only check for a comma (a "someone, do something" command) if we are</span>
<span class="comment">not already in the middle of one. (This simplification stops us from</span>
<span class="comment">worrying about "robot, wizard, you are an idiot", telling the robot to</span>
<span class="comment">tell the wizard that she is an idiot.)</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">actor</span><span class="plain"> == </span><span class="identifier">player</span><span class="plain">) {</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=2 : </span><span class="identifier">j</span><span class="plain">&lt;=</span><span class="identifier">num_words</span><span class="plain"> : </span><span class="identifier">j</span><span class="plain">++) {</span>
<span class="identifier">i</span><span class="plain">=</span><span class="identifier">NextWord</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="identifier">comma_word</span><span class="plain">) </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">Conversation</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">NotConversation</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">NextWord nudges the word number wn on by one each time, so we've now</span>
<span class="comment">advanced past a comma. (A comma is a word all on its own in the table.)</span>
2020-01-13 13:02:57 +02:00
<span class="plain">.</span><span class="identifier">Conversation</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">j</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain"> - </span><span class="constant">1</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Use NounDomain (in the context of "animate creature") to see if the</span>
<span class="comment">words make sense as the name of someone held or nearby</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">wn</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="identifier">lookahead</span><span class="plain"> = </span><span class="identifier">HELD_TOKEN</span><span class="plain">;</span>
<span class="identifier">scope_reason</span><span class="plain"> = </span><span class="identifier">TALKING_REASON</span><span class="plain">;</span>
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">NounDomain</span><span class="plain">(</span><span class="identifier">player</span><span class="plain">,</span><span class="identifier">actors_location</span><span class="plain">,6);</span>
<span class="identifier">scope_reason</span><span class="plain"> = </span><span class="identifier">PARSING_REASON</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="identifier">REPARSE_CODE</span><span class="plain">) </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">ReParse</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">verb_word</span><span class="plain"> &amp;&amp; ((</span><span class="identifier">verb_word</span><span class="plain">-&gt;#</span><span class="identifier">dict_par1</span><span class="plain">) &amp; </span><span class="constant">1</span><span class="plain">)) </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">NotConversation</span><span class="plain">;</span>
<span class="identifier">best_etype</span><span class="plain"> = </span><span class="identifier">MISSINGPERSON_PE</span><span class="plain">; </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">GiveError</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="plain">.</span><span class="identifier">Conversation2</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">The object addressed must at least be "talkable" if not actually "animate"</span>
<span class="comment">(the distinction allows, for instance, a microphone to be spoken to,</span>
<span class="comment">without the parser thinking that the microphone is human).</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> </span><span class="reserved">hasnt</span><span class="plain"> </span><span class="identifier">animate</span><span class="plain"> &amp;&amp; </span><span class="identifier">l</span><span class="plain"> </span><span class="reserved">hasnt</span><span class="plain"> </span><span class="identifier">talkable</span><span class="plain">) {</span>
<span class="identifier">best_etype</span><span class="plain"> = </span><span class="identifier">ANIMALISTEN_PE</span><span class="plain">; </span><span class="identifier">noun</span><span class="plain"> = </span><span class="identifier">l</span><span class="plain">; </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">GiveError</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Check that there aren't any mystery words between the end of the person's</span>
<span class="comment">name and the comma (eg, throw out "dwarf sdfgsdgs, go north").</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wn</span><span class="plain"> ~= </span><span class="identifier">j</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">verb_word</span><span class="plain"> &amp;&amp; ((</span><span class="identifier">verb_word</span><span class="plain">-&gt;#</span><span class="identifier">dict_par1</span><span class="plain">) &amp; </span><span class="constant">1</span><span class="plain">)) </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">NotConversation</span><span class="plain">;</span>
<span class="identifier">best_etype</span><span class="plain"> = </span><span class="identifier">TOTALK_PE</span><span class="plain">; </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">GiveError</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">The player has now successfully named someone. Adjust "him", "her", "it":</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">PronounNotice</span><span class="plain">(</span><span class="identifier">l</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Set the global variable "actor", adjust the number of the first word,</span>
<span class="comment">and begin parsing again from there.</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">verb_wordnum</span><span class="plain"> = </span><span class="identifier">j</span><span class="plain"> + </span><span class="constant">1</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Stop things like "me, again":</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="identifier">player</span><span class="plain">) {</span>
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">verb_wordnum</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">NextWordStopped</span><span class="plain">() == </span><span class="identifier">AGAIN1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">AGAIN2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">AGAIN3__WD</span><span class="plain">) {</span>
<span class="identifier">best_etype</span><span class="plain"> = </span><span class="identifier">ANIMAAGAIN_PE</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">GiveError</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">actor</span><span class="plain"> = </span><span class="identifier">l</span><span class="plain">;</span>
<span class="identifier">actors_location</span><span class="plain"> = </span><span class="identifier">ScopeCeiling</span><span class="plain">(</span><span class="identifier">l</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">1</span><span class="plain">)</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"[Actor is "</span><span class="plain">, (</span><span class="identifier">the</span><span class="plain">) </span><span class="identifier">actor</span><span class="plain">, </span><span class="string">" in "</span><span class="plain">, (</span><span class="identifier">name</span><span class="plain">) </span><span class="identifier">actors_location</span><span class="plain">, </span><span class="string">"]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">BeginCommand</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. Parser Letter D. </b>Get the verb: try all the syntax lines for that verb.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">.</span><span class="identifier">NotConversation</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">verb_word</span><span class="plain"> == </span><span class="constant">0</span><span class="plain"> || ((</span><span class="identifier">verb_word</span><span class="plain">-&gt;#</span><span class="identifier">dict_par1</span><span class="plain">) &amp; </span><span class="constant">1</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">verb_word</span><span class="plain"> = </span><span class="identifier">UnknownVerb</span><span class="plain">(</span><span class="identifier">verb_word</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">verb_word</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">VerbAccepted</span><span class="plain">;</span>
<span class="identifier">best_etype</span><span class="plain"> = </span><span class="identifier">VERB_PE</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">GiveError</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="plain">.</span><span class="identifier">VerbAccepted</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">We now definitely have a verb, not a direction, whether we got here by the</span>
<span class="comment">"take ..." or "person, take ..." method. Get the meta flag for this verb:</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">meta</span><span class="plain"> = ((</span><span class="identifier">verb_word</span><span class="plain">-&gt;#</span><span class="identifier">dict_par1</span><span class="plain">) &amp; </span><span class="constant">2</span><span class="plain">)/2;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">You can't order other people to "full score" for you, and so on...</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">meta</span><span class="plain"> == </span><span class="constant">1</span><span class="plain"> &amp;&amp; </span><span class="identifier">actor</span><span class="plain"> ~= </span><span class="identifier">player</span><span class="plain">) {</span>
<span class="identifier">best_etype</span><span class="plain"> = </span><span class="identifier">VERB_PE</span><span class="plain">;</span>
<span class="identifier">meta</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">GiveError</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Now let i be the corresponding verb number...</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">DictionaryWordToVerbNum</span><span class="plain">(</span><span class="identifier">verb_word</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="comment">...then look up the i-th entry in the verb table, whose address is at word</span>
<span class="comment">7 in the Z-machine (in the header), so as to get the address of the syntax</span>
<span class="comment">table for the given verb...</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="identifier">syntax</span><span class="plain"> = (</span><span class="identifier">HDR_STATICMEMORY</span><span class="plain">--&gt;0)--&gt;</span><span class="identifier">i</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Ifnot</span><span class="plain">; </span><span class="comment">TARGET_GLULX</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">syntax</span><span class="plain"> = (#</span><span class="identifier">grammar_table</span><span class="plain">)--&gt;(</span><span class="identifier">i</span><span class="plain">+1);</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">TARGET_</span>
2020-04-07 03:06:09 +03:00
<span class="comment">...and then see how many lines (ie, different patterns corresponding to the</span>
<span class="comment">same verb) are stored in the parse table...</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">num_lines</span><span class="plain"> = (</span><span class="identifier">syntax</span><span class="plain">-&gt;0) - </span><span class="constant">1</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">...and now go through them all, one by one.</span>
<span class="comment">To prevent pronoun_word 0 being misunderstood,</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">pronoun_word</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">pronoun_obj</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">1</span><span class="plain">)</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"[Parsing for the verb '"</span><span class="plain">, (</span><span class="identifier">address</span><span class="plain">) </span><span class="identifier">verb_word</span><span class="plain">, </span><span class="string">"' ("</span><span class="plain">, </span><span class="identifier">num_lines</span><span class="plain">+1, </span><span class="string">" lines)]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">best_etype</span><span class="plain"> = </span><span class="identifier">STUCK_PE</span><span class="plain">; </span><span class="identifier">nextbest_etype</span><span class="plain"> = </span><span class="identifier">STUCK_PE</span><span class="plain">;</span>
<span class="identifier">multiflag</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">"best_etype" is the current failure-to-match error - it is by default</span>
<span class="comment">the least informative one, "don't understand that sentence".</span>
<span class="comment">"nextbest_etype" remembers the best alternative to having to ask a</span>
<span class="comment">scope token for an error message (i.e., the best not counting ASKSCOPE_PE).</span>
<span class="comment">multiflag is used here to prevent inappropriate MULTI_PE errors</span>
<span class="comment">in addition to its unrelated duties passing information to action routines</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. Parser Letter E. </b>Break down a syntax line into analysed tokens.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="identifier">line_address</span><span class="plain"> = </span><span class="identifier">syntax</span><span class="plain"> + </span><span class="constant">1</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">line</span><span class="plain">=0 : </span><span class="identifier">line</span><span class="plain">&lt;=</span><span class="identifier">num_lines</span><span class="plain"> : </span><span class="identifier">line</span><span class="plain">++) {</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Unpack the syntax line from Inform format into three arrays; ensure that</span>
<span class="comment">the sequence of tokens ends in an ENDIT_TOKEN.</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">line_address</span><span class="plain"> = </span><span class="identifier">UnpackGrammarLine</span><span class="plain">(</span><span class="identifier">line_address</span><span class="plain">);</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">1</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">2</span><span class="plain">) </span><span class="reserved">new_line</span><span class="plain">;</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"[line "</span><span class="plain">, </span><span class="identifier">line</span><span class="plain">; </span><span class="identifier">DebugGrammarLine</span><span class="plain">();</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"]^"</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-04-07 03:06:09 +03:00
<span class="comment">We aren't in "not holding" or inferring modes, and haven't entered</span>
<span class="comment">any parameters on the line yet, or any special numbers; the multiple</span>
<span class="comment">object is still empty.</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">inferfrom</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">parameters</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">nsns</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">special_word</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">multiple_object</span><span class="plain">--&gt;0 = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">multi_context</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">etype</span><span class="plain"> = </span><span class="identifier">STUCK_PE</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Put the word marker back to just after the verb</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">verb_wordnum</span><span class="plain">+1;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. Parser Letter F. </b>Look ahead for advance warning for <code class="display"><span class="extract">multiexcept</span></code>/<code class="display"><span class="extract">multiinside</span></code>.
</p>
<p class="inwebparagraph">There are two special cases where parsing a token now has to be affected by
the result of parsing another token later, and these two cases (multiexcept
and multiinside tokens) are helped by a quick look ahead, to work out the
future token now. We can only carry this out in the simple (but by far the
most common) case:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">multiexcept &lt;one or more prepositions&gt; noun</span>
</pre>
<p class="inwebparagraph">and similarly for <code class="display"><span class="extract">multiinside</span></code>.
</p>
<pre class="display">
2020-04-07 03:06:09 +03:00
<span class="identifier">advance_warning</span><span class="plain"> = -1; </span><span class="identifier">indef_mode</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0,</span><span class="identifier">m</span><span class="plain">=</span><span class="reserved">false</span><span class="plain">,</span><span class="identifier">pcount</span><span class="plain">=0 : </span><span class="identifier">line_token</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain"> ~= </span><span class="identifier">ENDIT_TOKEN</span><span class="plain"> : </span><span class="identifier">pcount</span><span class="plain">++) {</span>
<span class="identifier">scope_token</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">line_ttype</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain"> ~= </span><span class="identifier">PREPOSITION_TT</span><span class="plain">) </span><span class="identifier">i</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">line_ttype</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain"> == </span><span class="identifier">ELEMENTARY_TT</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">line_tdata</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain"> == </span><span class="identifier">MULTI_TOKEN</span><span class="plain">) </span><span class="identifier">m</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">line_tdata</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain"> == </span><span class="identifier">MULTIEXCEPT_TOKEN</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">MULTIINSIDE_TOKEN</span><span class="plain"> &amp;&amp; </span><span class="identifier">i</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="comment">First non-preposition is "multiexcept" or</span>
<span class="comment">"multiinside", so look ahead.</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">2</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" [Trying look-ahead]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
2020-04-07 03:06:09 +03:00
<span class="comment">We need this to be followed by 1 or more prepositions.</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">pcount</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">line_ttype</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain"> == </span><span class="identifier">PREPOSITION_TT</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="comment">skip ahead to a preposition word in the input</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">do</span><span class="plain"> {</span>
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">NextWord</span><span class="plain">();</span>
<span class="plain">} </span><span class="reserved">until</span><span class="plain"> ((</span><span class="identifier">wn</span><span class="plain"> &gt; </span><span class="identifier">num_words</span><span class="plain">) ||</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> (</span><span class="identifier">l</span><span class="plain"> &amp;&amp; (</span><span class="identifier">l</span><span class="plain">-&gt;#</span><span class="identifier">dict_par1</span><span class="plain">) &amp; </span><span class="constant">8</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">));</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wn</span><span class="plain"> &gt; </span><span class="identifier">num_words</span><span class="plain">) {</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">2</span><span class="plain">)</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" [Look-ahead aborted: prepositions missing]^"</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">EmptyLine</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">do</span><span class="plain"> {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PrepositionChain</span><span class="plain">(</span><span class="identifier">l</span><span class="plain">, </span><span class="identifier">pcount</span><span class="plain">) ~= -1) {</span>
<span class="comment">advance past the chain</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">line_token</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain">)-&gt;0 &amp; </span><span class="constant">$20</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">pcount</span><span class="plain">++;</span>
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">line_token</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain"> ~= </span><span class="identifier">ENDIT_TOKEN</span><span class="plain">) &amp;&amp;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> ((</span><span class="identifier">line_token</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain">)-&gt;0 &amp; </span><span class="constant">$10</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">))</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">pcount</span><span class="plain">++;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">pcount</span><span class="plain">++;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
2020-04-07 03:06:09 +03:00
<span class="comment">try to find another preposition word</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">do</span><span class="plain"> {</span>
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">NextWord</span><span class="plain">();</span>
<span class="plain">} </span><span class="reserved">until</span><span class="plain"> ((</span><span class="identifier">wn</span><span class="plain"> &gt;= </span><span class="identifier">num_words</span><span class="plain">) ||</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> (</span><span class="identifier">l</span><span class="plain"> &amp;&amp; (</span><span class="identifier">l</span><span class="plain">-&gt;#</span><span class="identifier">dict_par1</span><span class="plain">) &amp; </span><span class="constant">8</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">));</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> &amp;&amp; (</span><span class="identifier">l</span><span class="plain">-&gt;#</span><span class="identifier">dict_par1</span><span class="plain">) &amp; </span><span class="constant">8</span><span class="plain">) </span><span class="reserved">continue</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">lookahead failed</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">2</span><span class="plain">)</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" [Look-ahead aborted: prepositions don't match]^"</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">LineFailed</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wn</span><span class="plain"> &lt;= </span><span class="identifier">num_words</span><span class="plain">) </span><span class="identifier">l</span><span class="plain"> = </span><span class="identifier">NextWord</span><span class="plain">();</span>
<span class="plain">} </span><span class="reserved">until</span><span class="plain"> (</span><span class="identifier">line_ttype</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain"> ~= </span><span class="identifier">PREPOSITION_TT</span><span class="plain">);</span>
<span class="plain">.</span><span class="identifier">EmptyLine</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">put back the non-preposition we just read</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">wn</span><span class="plain">--;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">line_ttype</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain"> == </span><span class="identifier">ELEMENTARY_TT</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">line_tdata</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain"> == </span><span class="identifier">NOUN_TOKEN</span><span class="plain">)) {</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">Descriptors</span><span class="plain">(); </span><span class="comment">skip past THE etc</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain">~=0) </span><span class="identifier">etype</span><span class="plain">=</span><span class="identifier">l</span><span class="plain">; </span><span class="comment">don't allow multiple objects</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">k</span><span class="plain"> = </span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP1_PRES</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">parameters</span><span class="plain">;</span>
<span class="identifier">parameters</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP1_PRES</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">NounDomain</span><span class="plain">(</span><span class="identifier">actors_location</span><span class="plain">, </span><span class="identifier">actor</span><span class="plain">, </span><span class="identifier">NOUN_TOKEN</span><span class="plain">, </span><span class="reserved">true</span><span class="plain">);</span>
<span class="plain">@</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">parameters</span><span class="plain">; @</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">; </span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP1_PRES</span><span class="plain"> = </span><span class="identifier">k</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">2</span><span class="plain">) {</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" [Advanced to ~noun~ token: "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="identifier">REPARSE_CODE</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"re-parse request]^"</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"but multiple found]^"</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"error "</span><span class="plain">, </span><span class="identifier">etype</span><span class="plain">, </span><span class="string">"]^"</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> &gt;= </span><span class="constant">2</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> (</span><span class="identifier">the</span><span class="plain">) </span><span class="identifier">l</span><span class="plain">, </span><span class="string">"]^"</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="identifier">REPARSE_CODE</span><span class="plain">) </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">ReParse</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> &gt;= </span><span class="constant">2</span><span class="plain">) </span><span class="identifier">advance_warning</span><span class="plain"> = </span><span class="identifier">l</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Slightly different line-parsing rules will apply to "take multi", to</span>
<span class="comment">prevent "take all" behaving correctly but misleadingly when there's</span>
<span class="comment">nothing to take.</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">take_all_rule</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">m</span><span class="plain"> &amp;&amp; </span><span class="identifier">params_wanted</span><span class="plain"> == </span><span class="constant">1</span><span class="plain"> &amp;&amp; </span><span class="identifier">action_to_be</span><span class="plain"> == ##</span><span class="identifier">Take</span><span class="plain">)</span>
<span class="identifier">take_all_rule</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">And now start again, properly, forearmed or not as the case may be.</span>
<span class="comment">As a precaution, we clear all the variables again (they may have been</span>
<span class="comment">disturbed by the call to NounDomain, which may have called outside</span>
2020-04-14 19:56:54 +03:00
<span class="comment">code, which may have done anything!).</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">inferfrom</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">parameters</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">nsns</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">special_word</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">multiple_object</span><span class="plain">--&gt;0 = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">etype</span><span class="plain"> = </span><span class="identifier">STUCK_PE</span><span class="plain">;</span>
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">verb_wordnum</span><span class="plain">+1;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. Parser Letter G. </b>Parse each token in turn (calling <code class="display"><span class="extract">ParseToken</span></code> to do most of the work).
</p>
<p class="inwebparagraph">The <code class="display"><span class="extract">pattern</span></code> gradually accumulates what has been recognised so far,
so that it may be reprinted by the parser later on.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="identifier">m</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">pcount</span><span class="plain">=1 : : </span><span class="identifier">pcount</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">line_token</span><span class="plain">--&gt;(</span><span class="identifier">pcount</span><span class="plain">-1) == </span><span class="identifier">ENDIT_TOKEN</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pcount</span><span class="plain"> &gt;= </span><span class="constant">2</span><span class="plain">) {</span>
<span class="reserved">while</span><span class="plain"> ((((</span><span class="identifier">line_token</span><span class="plain">--&gt;(</span><span class="identifier">pcount</span><span class="plain">-2))-&gt;0) &amp; </span><span class="constant">$10</span><span class="plain">) ~= </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">pcount</span><span class="plain">--;</span>
<span class="identifier">AnalyseToken</span><span class="plain">(</span><span class="identifier">line_token</span><span class="plain">--&gt;(</span><span class="identifier">pcount</span><span class="plain">-2));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">found_ttype</span><span class="plain"> == </span><span class="identifier">PREPOSITION_TT</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">l</span><span class="plain"> = -1;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">while</span><span class="plain"> (</span><span class="reserved">true</span><span class="plain">) {</span>
<span class="identifier">m</span><span class="plain"> = </span><span class="identifier">NextWordStopped</span><span class="plain">();</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">m</span><span class="plain"> == -1) </span><span class="reserved">break</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">m</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PrepositionChain</span><span class="plain">(</span><span class="identifier">l</span><span class="plain">, </span><span class="identifier">pcount</span><span class="plain">-2) == -1) {</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">m</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">2</span><span class="plain">)</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"[line rejected for not ending with correct preposition]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">m</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">verb_wordnum</span><span class="plain">+1;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">m</span><span class="plain">) </span><span class="reserved">for</span><span class="plain"> (</span><span class="identifier">pcount</span><span class="plain">=1 : : </span><span class="identifier">pcount</span><span class="plain">++) {</span>
<span class="identifier">pattern</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain"> = </span><span class="identifier">PATTERN_NULL</span><span class="plain">; </span><span class="identifier">scope_token</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">token</span><span class="plain"> = </span><span class="identifier">line_token</span><span class="plain">--&gt;(</span><span class="identifier">pcount</span><span class="plain">-1);</span>
<span class="identifier">lookahead</span><span class="plain"> = </span><span class="identifier">line_token</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">2</span><span class="plain">)</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" [line "</span><span class="plain">, </span><span class="identifier">line</span><span class="plain">, </span><span class="string">" token "</span><span class="plain">, </span><span class="identifier">pcount</span><span class="plain">, </span><span class="string">" word "</span><span class="plain">, </span><span class="identifier">wn</span><span class="plain">, </span><span class="string">" : "</span><span class="plain">, (</span><span class="identifier">DebugToken</span><span class="plain">) </span><span class="identifier">token</span><span class="plain">,</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="string">"]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">token</span><span class="plain"> ~= </span><span class="identifier">ENDIT_TOKEN</span><span class="plain">) {</span>
<span class="identifier">scope_reason</span><span class="plain"> = </span><span class="identifier">PARSING_REASON</span><span class="plain">;</span>
<span class="identifier">AnalyseToken</span><span class="plain">(</span><span class="identifier">token</span><span class="plain">);</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">ParseToken</span><span class="plain">(</span><span class="identifier">found_ttype</span><span class="plain">, </span><span class="identifier">found_tdata</span><span class="plain">, </span><span class="identifier">pcount</span><span class="plain">-1, </span><span class="identifier">token</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">l</span><span class="plain"> &gt;= </span><span class="identifier">GPR_NOUN</span><span class="plain">) &amp;&amp; (</span><span class="identifier">l</span><span class="plain"> &lt; -1)) </span><span class="identifier">l</span><span class="plain"> = </span><span class="identifier">ParseToken</span><span class="plain">(</span><span class="identifier">ELEMENTARY_TT</span><span class="plain">, </span><span class="identifier">l</span><span class="plain"> + </span><span class="constant">256</span><span class="plain">);</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">scope_reason</span><span class="plain"> = </span><span class="identifier">PARSING_REASON</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="identifier">GPR_PREPOSITION</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">found_ttype</span><span class="plain">~=</span><span class="identifier">PREPOSITION_TT</span><span class="plain"> &amp;&amp; (</span><span class="identifier">found_ttype</span><span class="plain">~=</span><span class="identifier">ELEMENTARY_TT</span><span class="plain"> ||</span>
<span class="identifier">found_tdata</span><span class="plain">~=</span><span class="identifier">TOPIC_TOKEN</span><span class="plain">)) </span><span class="identifier">params_wanted</span><span class="plain">--;</span>
<span class="identifier">l</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">else</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> &lt; </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">l</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
<span class="reserved">else</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> ~= </span><span class="identifier">GPR_REPARSE</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="identifier">GPR_NUMBER</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nsns</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">special_number1</span><span class="plain"> = </span><span class="identifier">parsed_number</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">special_number2</span><span class="plain"> = </span><span class="identifier">parsed_number</span><span class="plain">;</span>
<span class="identifier">nsns</span><span class="plain">++; </span><span class="identifier">l</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="identifier">GPR_MULTIPLE</span><span class="plain">) </span><span class="identifier">l</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">parser_results</span><span class="plain">--&gt;(</span><span class="identifier">parameters</span><span class="plain">+</span><span class="identifier">INP1_PRES</span><span class="plain">) = </span><span class="identifier">l</span><span class="plain">;</span>
<span class="identifier">parameters</span><span class="plain">++;</span>
<span class="identifier">pattern</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain"> = </span><span class="identifier">l</span><span class="plain">;</span>
<span class="identifier">l</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">3</span><span class="plain">) {</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" [token resulted in "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="identifier">REPARSE_CODE</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"re-parse request]^"</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"failure with error type "</span><span class="plain">, </span><span class="identifier">etype</span><span class="plain">, </span><span class="string">"]^"</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"success]^"</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="identifier">REPARSE_CODE</span><span class="plain">) </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">ReParse</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="reserved">false</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">else</span><span class="plain"> {</span>
2020-04-07 03:06:09 +03:00
<span class="comment">If the player has entered enough already but there's still</span>
<span class="comment">text to wade through: store the pattern away so as to be able to produce</span>
<span class="comment">a decent error message if this turns out to be the best we ever manage,</span>
<span class="comment">and in the mean time give up on this line</span>
2020-01-13 13:02:57 +02:00
2020-04-07 03:06:09 +03:00
<span class="comment">However, if the superfluous text begins with a comma or "then" then</span>
<span class="comment">take that to be the start of another instruction</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wn</span><span class="plain"> &lt;= </span><span class="identifier">num_words</span><span class="plain">) {</span>
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">NextWord</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="identifier">THEN1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">THEN2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">THEN3__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">comma_word</span><span class="plain">) {</span>
<span class="identifier">held_back_mode</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">; </span><span class="identifier">hb_wn</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">-1;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">m</span><span class="plain">=0 : </span><span class="identifier">m</span><span class="plain">&lt;32 : </span><span class="identifier">m</span><span class="plain">++) </span><span class="identifier">pattern2</span><span class="plain">--&gt;</span><span class="identifier">m</span><span class="plain"> = </span><span class="identifier">pattern</span><span class="plain">--&gt;</span><span class="identifier">m</span><span class="plain">;</span>
<span class="identifier">pcount2</span><span class="plain"> = </span><span class="identifier">pcount</span><span class="plain">;</span>
<span class="identifier">etype</span><span class="plain"> = </span><span class="identifier">UPTO_PE</span><span class="plain">;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Now, we may need to revise the multiple object because of the single one</span>
<span class="comment">we now know (but didn't when the list was drawn up).</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parameters</span><span class="plain"> &gt;= </span><span class="constant">1</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP1_PRES</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">ReviseMulti</span><span class="plain">(</span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP2_PRES</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) { </span><span class="identifier">etype</span><span class="plain"> = </span><span class="identifier">l</span><span class="plain">; </span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">ACTION_PRES</span><span class="plain"> = </span><span class="identifier">action_to_be</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">; }</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parameters</span><span class="plain"> &gt;= </span><span class="constant">2</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP2_PRES</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">ReviseMulti</span><span class="plain">(</span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP1_PRES</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) { </span><span class="identifier">etype</span><span class="plain"> = </span><span class="identifier">l</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">; }</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">k</span><span class="plain"> = </span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP1_PRES</span><span class="plain">; </span><span class="identifier">l</span><span class="plain"> = </span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP2_PRES</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">k</span><span class="plain"> &amp;&amp; </span><span class="identifier">l</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">multi_context</span><span class="plain">==</span><span class="identifier">MULTIEXCEPT_TOKEN</span><span class="plain"> &amp;&amp; </span><span class="identifier">k</span><span class="plain"> == </span><span class="identifier">l</span><span class="plain">) ||</span>
<span class="plain">((</span><span class="identifier">multi_context</span><span class="plain">==</span><span class="identifier">MULTIINSIDE_TOKEN</span><span class="plain"> &amp;&amp; </span><span class="identifier">k</span><span class="plain"> </span><span class="reserved">notin</span><span class="plain"> </span><span class="identifier">l</span><span class="plain"> &amp;&amp; </span><span class="identifier">l</span><span class="plain"> </span><span class="reserved">notin</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">))) {</span>
<span class="identifier">best_etype</span><span class="plain"> = </span><span class="identifier">NOTHING_PE</span><span class="plain">;</span>
<span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">ACTION_PRES</span><span class="plain"> = </span><span class="identifier">action_to_be</span><span class="plain">; </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">GiveError</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">To trap the case of "take all" inferring only "yourself" when absolutely</span>
<span class="comment">nothing else is in the vicinity...</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">take_all_rule</span><span class="plain"> == </span><span class="constant">2</span><span class="plain"> &amp;&amp; </span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP1_PRES</span><span class="plain"> == </span><span class="identifier">actor</span><span class="plain">) {</span>
<span class="identifier">best_etype</span><span class="plain"> = </span><span class="identifier">NOTHING_PE</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">GiveError</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">1</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"[Line successfully parsed]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-04-07 03:06:09 +03:00
<span class="comment">The line has successfully matched the text. Declare the input error-free...</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">oops_from</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">...explain any inferences made (using the pattern)...</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inferfrom</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">PrintInferredCommand</span><span class="plain">(</span><span class="identifier">inferfrom</span><span class="plain">);</span>
<span class="identifier">ClearParagraphing</span><span class="plain">(20);</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">...copy the action number, and the number of parameters...</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">ACTION_PRES</span><span class="plain"> = </span><span class="identifier">action_to_be</span><span class="plain">;</span>
<span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">NO_INPS_PRES</span><span class="plain"> = </span><span class="identifier">parameters</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">...reverse first and second parameters if need be...</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">action_reversed</span><span class="plain"> &amp;&amp; </span><span class="identifier">parameters</span><span class="plain"> == </span><span class="constant">2</span><span class="plain">) {</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP1_PRES</span><span class="plain">;</span>
<span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP1_PRES</span><span class="plain"> = </span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP2_PRES</span><span class="plain">;</span>
<span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP2_PRES</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nsns</span><span class="plain"> == </span><span class="constant">2</span><span class="plain">) {</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">special_number1</span><span class="plain">; </span><span class="identifier">special_number1</span><span class="plain"> = </span><span class="identifier">special_number2</span><span class="plain">;</span>
<span class="identifier">special_number2</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">...and to reset "it"-style objects to the first of these parameters, if</span>
<span class="comment">there is one (and it really is an object)...</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parameters</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain"> &amp;&amp; </span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP1_PRES</span><span class="plain"> &gt;= </span><span class="constant">2</span><span class="plain">)</span>
<span class="identifier">PronounNotice</span><span class="plain">(</span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP1_PRES</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="comment">...and return from the parser altogether, having successfully matched</span>
<span class="comment">a line.</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">held_back_mode</span><span class="plain">) {</span>
<span class="identifier">wn</span><span class="plain">=</span><span class="identifier">hb_wn</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">LookForMore</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">rtrue</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">} </span><span class="comment">end of if(token ~= ENDIT_TOKEN) else</span>
<span class="plain">} </span><span class="comment">end of for(pcount++)</span>
2020-01-13 13:02:57 +02:00
<span class="plain">.</span><span class="identifier">LineFailed</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">The line has failed to match.</span>
<span class="comment">We continue the outer "for" loop, trying the next line in the grammar.</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> &gt; </span><span class="identifier">best_etype</span><span class="plain">) </span><span class="identifier">best_etype</span><span class="plain"> = </span><span class="identifier">etype</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> ~= </span><span class="identifier">ASKSCOPE_PE</span><span class="plain"> &amp;&amp; </span><span class="identifier">etype</span><span class="plain"> &gt; </span><span class="identifier">nextbest_etype</span><span class="plain">) </span><span class="identifier">nextbest_etype</span><span class="plain"> = </span><span class="identifier">etype</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">...unless the line was something like "take all" which failed because</span>
<span class="comment">nothing matched the "all", in which case we stop and give an error now.</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">take_all_rule</span><span class="plain"> == </span><span class="constant">2</span><span class="plain"> &amp;&amp; </span><span class="identifier">etype</span><span class="plain">==</span><span class="identifier">NOTHING_PE</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">} </span><span class="comment">end of for(line++)</span>
2020-04-07 03:06:09 +03:00
<span class="comment">The grammar is exhausted: every line has failed to match.</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. Parser Letter H. </b>Cheaply parse otherwise unrecognised conversation and return.
</p>
<p class="inwebparagraph">(Errors are handled differently depending on who was talking. If the command
was addressed to somebody else (eg, DWARF, SFGH) then it is taken as
conversation which the parser has no business in disallowing.)
</p>
<p class="inwebparagraph">The parser used to return the fake action <code class="display"><span class="extract">##NotUnderstood</span></code> when a
command in the form PERSON, ARFLE BARFLE GLOOP is parsed, where a character
is addressed but with an instruction which the parser can't understand.
(If a command such as ARFLE BARFLE GLOOP is not an instruction to someone
else, the parser prints an error and requires the player to type another
command: thus <code class="display"><span class="extract">##NotUnderstood</span></code> was only returned when <code class="display"><span class="extract">actor</span></code> is not the
player.) And I6 had elaborate object-oriented ways to deal with this, but we
won't use any of that: we simply convert to a <code class="display"><span class="extract">##Answer</span></code> action, which
communicates a snippet of words to another character, just as if the
player had typed ANSWER ARFLE BARFLE GLOOP TO PERSON. For I7 purposes, the
fake action <code class="display"><span class="extract">##NotUnderstood</span></code> does not exist.
</p>
<pre class="display">
2020-04-08 01:02:44 +03:00
<span class="plain"> .</span><span class="identifier">GiveError</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">etype</span><span class="plain"> = </span><span class="identifier">best_etype</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">actor</span><span class="plain"> ~= </span><span class="identifier">player</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">usual_grammar_after</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">verb_wordnum</span><span class="plain"> = </span><span class="identifier">usual_grammar_after</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">AlmostReParse</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">verb_wordnum</span><span class="plain">;</span>
<span class="identifier">special_word</span><span class="plain"> = </span><span class="identifier">NextWord</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">special_word</span><span class="plain"> == </span><span class="identifier">comma_word</span><span class="plain">) {</span>
<span class="identifier">special_word</span><span class="plain"> = </span><span class="identifier">NextWord</span><span class="plain">();</span>
<span class="identifier">verb_wordnum</span><span class="plain">++;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">ACTION_PRES</span><span class="plain"> = ##</span><span class="identifier">Answer</span><span class="plain">;</span>
<span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">NO_INPS_PRES</span><span class="plain"> = </span><span class="constant">2</span><span class="plain">;</span>
<span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP1_PRES</span><span class="plain"> = </span><span class="identifier">actor</span><span class="plain">;</span>
<span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP2_PRES</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="identifier">special_number1</span><span class="plain"> = </span><span class="identifier">special_word</span><span class="plain">;</span>
<span class="identifier">actor</span><span class="plain"> = </span><span class="identifier">player</span><span class="plain">;</span>
<span class="identifier">consult_from</span><span class="plain"> = </span><span class="identifier">verb_wordnum</span><span class="plain">; </span><span class="identifier">consult_words</span><span class="plain"> = </span><span class="identifier">num_words</span><span class="plain">-</span><span class="identifier">consult_from</span><span class="plain">+1;</span>
<span class="reserved">rtrue</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. Parser Letter I. </b>Print best possible error message.
</p>
<pre class="display">
2020-04-07 03:06:09 +03:00
<span class="comment">If the player was the actor (eg, in "take dfghh") the error must be printed,</span>
<span class="comment">and fresh input called for. In three cases the oops word must be jiggled.</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">etype</span><span class="plain"> </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">Routine</span><span class="plain">) || (</span><span class="identifier">etype</span><span class="plain"> </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">String</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParserError</span><span class="plain">(</span><span class="identifier">etype</span><span class="plain">) ~= </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">ReType</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">verb_wordnum</span><span class="plain"> == </span><span class="constant">0</span><span class="plain"> &amp;&amp; </span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">CANTSEE_PE</span><span class="plain">) </span><span class="identifier">etype</span><span class="plain"> = </span><span class="identifier">VERB_PE</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">players_command</span><span class="plain"> = </span><span class="constant">100</span><span class="plain"> + </span><span class="identifier">WordCount</span><span class="plain">(); </span><span class="comment">The snippet variable "player's command"</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">BeginActivity</span><span class="plain">(</span><span class="identifier">PRINTING_A_PARSER_ERROR_ACT</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ForActivity</span><span class="plain">(</span><span class="identifier">PRINTING_A_PARSER_ERROR_ACT</span><span class="plain">)) </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">SkipParserError</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">pronoun_word</span><span class="plain"> = </span><span class="identifier">pronoun__word</span><span class="plain">; </span><span class="identifier">pronoun_obj</span><span class="plain"> = </span><span class="identifier">pronoun__obj</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">STUCK_PE</span><span class="plain">) { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'A'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; </span><span class="identifier">oops_from</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">UPTO_PE</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inferred_go</span><span class="plain">) </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'C'</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'B'</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">m</span><span class="plain">=0 : </span><span class="identifier">m</span><span class="plain">&lt;32 : </span><span class="identifier">m</span><span class="plain">++) </span><span class="identifier">pattern</span><span class="plain">--&gt;</span><span class="identifier">m</span><span class="plain"> = </span><span class="identifier">pattern2</span><span class="plain">--&gt;</span><span class="identifier">m</span><span class="plain">;</span>
<span class="identifier">pcount</span><span class="plain"> = </span><span class="identifier">pcount2</span><span class="plain">; </span><span class="identifier">PrintCommand</span><span class="plain">(0);</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">".^"</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">NUMBER_PE</span><span class="plain">) { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'D'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">CANTSEE_PE</span><span class="plain">) { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'E'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; </span><span class="identifier">oops_from</span><span class="plain">=</span><span class="identifier">saved_oops</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">TOOLIT_PE</span><span class="plain">) { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'F'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">NOTHELD_PE</span><span class="plain">) { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'G'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; </span><span class="identifier">oops_from</span><span class="plain">=</span><span class="identifier">saved_oops</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">MULTI_PE</span><span class="plain">) { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'H'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">MMULTI_PE</span><span class="plain">) { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'I'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">VAGUE_PE</span><span class="plain">) { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'J'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">ITGONE_PE</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pronoun_obj</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'J'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">else</span><span class="plain"> { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'K'</span><span class="plain">, </span><span class="identifier">noun</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">EXCEPT_PE</span><span class="plain">) { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'L'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">ANIMA_PE</span><span class="plain">) { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'M'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">VERB_PE</span><span class="plain">) { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'N'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">SCENERY_PE</span><span class="plain">) { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'O'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">JUNKAFTER_PE</span><span class="plain">) { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'P'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">TOOFEW_PE</span><span class="plain">) { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'Q'</span><span class="plain">, </span><span class="identifier">multi_had</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">NOTHING_PE</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">ACTION_PRES</span><span class="plain"> == ##</span><span class="identifier">Remove</span><span class="plain"> &amp;&amp;</span>
<span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP2_PRES</span><span class="plain"> </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">Object</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">noun</span><span class="plain"> = </span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP2_PRES</span><span class="plain">; </span><span class="comment">ensure valid for messages</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">noun</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">animate</span><span class="plain">) { </span><span class="identifier">PARSER_N_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'C'</span><span class="plain">, </span><span class="identifier">noun</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">noun</span><span class="plain"> </span><span class="reserved">hasnt</span><span class="plain"> </span><span class="identifier">container</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">supporter</span><span class="plain">) { </span><span class="identifier">PARSER_N_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'D'</span><span class="plain">, </span><span class="identifier">noun</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">noun</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">container</span><span class="plain"> &amp;&amp; </span><span class="identifier">noun</span><span class="plain"> </span><span class="reserved">hasnt</span><span class="plain"> </span><span class="identifier">open</span><span class="plain">) { </span><span class="identifier">PARSER_N_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'E'</span><span class="plain">, </span><span class="identifier">noun</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="reserved">children</span><span class="plain">(</span><span class="identifier">noun</span><span class="plain">)==0) { </span><span class="identifier">PARSER_N_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'F'</span><span class="plain">, </span><span class="identifier">noun</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">ACTION_PRES</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">ACTION_PRES</span><span class="plain"> ~= ##</span><span class="identifier">Remove</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">multi_wanted</span><span class="plain">==100) { </span><span class="identifier">PARSER_N_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'A'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">else</span><span class="plain"> { </span><span class="identifier">PARSER_N_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'B'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">NOTINCONTEXT_PE</span><span class="plain">) { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'R'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">ANIMAAGAIN_PE</span><span class="plain">) { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'S'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">COMMABEGIN_PE</span><span class="plain">) { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'T'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">MISSINGPERSON_PE</span><span class="plain">) { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'U'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">ANIMALISTEN_PE</span><span class="plain">) { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'V'</span><span class="plain">, </span><span class="identifier">noun</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">TOTALK_PE</span><span class="plain">) { </span><span class="identifier">PARSER_ERROR_INTERNAL_RM</span><span class="plain">(</span><span class="character">'W'</span><span class="plain">); </span><span class="reserved">new_line</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">ASKSCOPE_PE</span><span class="plain">) {</span>
<span class="identifier">scope_stage</span><span class="plain"> = </span><span class="constant">3</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="reserved">indirect</span><span class="plain">(</span><span class="identifier">scope_error</span><span class="plain">) == -1) {</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">best_etype</span><span class="plain"> = </span><span class="identifier">nextbest_etype</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (~~((</span><span class="identifier">etype</span><span class="plain"> </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">Routine</span><span class="plain">) || (</span><span class="identifier">etype</span><span class="plain"> </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">String</span><span class="plain">)))</span>
<span class="identifier">EndActivity</span><span class="plain">(</span><span class="identifier">PRINTING_A_PARSER_ERROR_ACT</span><span class="plain">);</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">GiveError</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="plain">.</span><span class="identifier">SkipParserError</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">etype</span><span class="plain"> </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">Routine</span><span class="plain">) || (</span><span class="identifier">etype</span><span class="plain"> </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">String</span><span class="plain">)) </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">ReType</span><span class="plain">;</span>
<span class="identifier">say__p</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="identifier">EndActivity</span><span class="plain">(</span><span class="identifier">PRINTING_A_PARSER_ERROR_ACT</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. Parser Letter J. </b>Retry the whole lot.
</p>
<pre class="display">
2020-04-07 03:06:09 +03:00
<span class="comment">And go (almost) right back to square one...</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">ReType</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">...being careful not to go all the way back, to avoid infinite repetition</span>
<span class="comment">of a deferred command causing an error.</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP20"></a><b>&#167;20. Parser Letter K. </b>Last thing: check for THEN and further instructions(s), return.
</p>
<pre class="display">
2020-04-07 03:06:09 +03:00
<span class="comment">At this point, the return value is all prepared, and we are only looking</span>
<span class="comment">to see if there is a "then" followed by subsequent instruction(s).</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> .</span><span class="identifier">LookForMore</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wn</span><span class="plain"> &gt; </span><span class="identifier">num_words</span><span class="plain">) </span><span class="reserved">rtrue</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">NextWord</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="identifier">THEN1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">THEN2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">THEN3__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">comma_word</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wn</span><span class="plain"> &gt; </span><span class="identifier">num_words</span><span class="plain">) {</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="identifier">held_back_mode</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
<span class="plain"> </span><span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">hb_wn</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">;</span>
<span class="identifier">held_back_mode</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">best_etype</span><span class="plain"> = </span><span class="identifier">UPTO_PE</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">GiveError</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP21"></a><b>&#167;21. End of Parser Proper. </b></p>
<pre class="display">
2020-04-07 03:06:09 +03:00
<span class="plain">]; </span><span class="comment">end of Parser__parse</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP22"></a><b>&#167;22. Internal Rule. </b>As a hook on which to hang responses.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">PARSER_ERROR_INTERNAL_R</span><span class="plain">; ];</span>
<span class="plain">[ </span><span class="identifier">PARSER_N_ERROR_INTERNAL_R</span><span class="plain">; ];</span>
<span class="plain">[ </span><span class="identifier">PARSER_COMMAND_INTERNAL_R</span><span class="plain">; ];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP23"></a><b>&#167;23. Parse Token. </b>The main parsing routine above tried a sequence of "grammar lines" in turn,
matching each against the text typed until one fitted. A grammar line is
itself a sequence of "grammar tokens". Here we have to parse the tokens.
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">ParseToken(type, data)</span></code> tries the match text beginning at the current
word marker <code class="display"><span class="extract">wn</span></code> against a token of the given <code class="display"><span class="extract">type</span></code>, with the given <code class="display"><span class="extract">data</span></code>.
The optional further arguments <code class="display"><span class="extract">token_n</span></code> and <code class="display"><span class="extract">token</span></code> supply the token
number in the current grammar line (because some tokens do depend on what
has happened before or is needed later) and the address of the dictionary
word which makes up the <code class="display"><span class="extract">token</span></code>, in the case where it's a "preposition".
</p>
<p class="inwebparagraph">The return values are:
</p>
<ul class="items"><li>(a) <code class="display"><span class="extract">GPR_REPARSE</span></code> for "I have rewritten the command, please re-parse from scratch";
</li><li>(b) <code class="display"><span class="extract">GPR_PREPOSITION</span></code> for "token accepted with no result";
2020-04-14 19:56:54 +03:00
</li><li>(c) \(-256 + x\) for "please parse <code class="display"><span class="extract">ParseToken(ELEMENTARY_TT, x)</span></code> instead";
</li><li>(d) 0 for "token accepted, result is the multiple object list";
</li><li>(e) 1 for "token accepted, result is the number in <code class="display"><span class="extract">parsed_number</span></code>";
</li><li>(f) an object number for "token accepted with this object as result";
2020-04-14 19:56:54 +03:00
</li><li>(g) \(-1\) for "token rejected".
</li></ul>
<p class="inwebparagraph">Strictly speaking <code class="display"><span class="extract">ParseToken</span></code> is a shell routine which saves the current
state on the stack, and calling <code class="display"><span class="extract">ParseToken__</span></code> to do the actual work.
</p>
<p class="inwebparagraph">Once again the routine is traditionally divided into six letters, here named under
paragraphs "Parse Token Letter A", and so on.
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(A) Analyse the token; handle all tokens not involving object lists and
break down others into elementary tokens
</li><li>(B) Begin parsing an object list
</li><li>(C) Parse descriptors (articles, pronouns, etc.) in the list
</li><li>(D) Parse an object name
</li><li>(E) Parse connectives (AND, BUT, etc.) and go back to (C)
</li><li>(F) Return the conclusion of parsing an object list
</li></ul>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">ParseTokenStopped</span><span class="plain"> </span><span class="identifier">x</span><span class="plain"> </span><span class="identifier">y</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wn</span><span class="plain">&gt;</span><span class="identifier">WordCount</span><span class="plain">()) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">GPR_FAIL</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ParseToken</span><span class="plain">(</span><span class="identifier">x</span><span class="plain">,</span><span class="identifier">y</span><span class="plain">);</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">parsetoken_nesting</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">[ </span><span class="identifier">ParseToken</span><span class="plain"> </span><span class="identifier">given_ttype</span><span class="plain"> </span><span class="identifier">given_tdata</span><span class="plain"> </span><span class="identifier">token_n</span><span class="plain"> </span><span class="identifier">token</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">t</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parsetoken_nesting</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="comment">save match globals</span>
2020-01-13 13:02:57 +02:00
<span class="plain">@</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">match_from</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">token_filter</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">match_length</span><span class="plain">;</span>
<span class="plain">@</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">number_of_classes</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">oops_from</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0: </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">number_matched</span><span class="plain">: </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">t</span><span class="plain"> = </span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">;</span>
<span class="identifier">t</span><span class="plain"> = </span><span class="identifier">match_classes</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">;</span>
<span class="identifier">t</span><span class="plain"> = </span><span class="identifier">match_scores</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="plain">@</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">number_matched</span><span class="plain">;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> }</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">parsetoken_nesting</span><span class="plain">++;</span>
<span class="identifier">rv</span><span class="plain"> = </span><span class="identifier">ParseToken__</span><span class="plain">(</span><span class="identifier">given_ttype</span><span class="plain">, </span><span class="identifier">given_tdata</span><span class="plain">, </span><span class="identifier">token_n</span><span class="plain">, </span><span class="identifier">token</span><span class="plain">);</span>
<span class="identifier">parsetoken_nesting</span><span class="plain">--;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parsetoken_nesting</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="comment">restore match globals</span>
2020-01-13 13:02:57 +02:00
<span class="plain">@</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">number_matched</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=</span><span class="identifier">number_matched</span><span class="plain">-1: </span><span class="identifier">i</span><span class="plain">&gt;=0: </span><span class="identifier">i</span><span class="plain">--) {</span>
<span class="plain">@</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">; </span><span class="identifier">match_scores</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">;</span>
<span class="plain">@</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">; </span><span class="identifier">match_classes</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">;</span>
<span class="plain">@</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">; </span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="plain">@</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">oops_from</span><span class="plain">; @</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">number_of_classes</span><span class="plain">;</span>
<span class="plain">@</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">match_length</span><span class="plain">; @</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">token_filter</span><span class="plain">; @</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">match_from</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">ParseToken__</span><span class="plain"> </span><span class="identifier">given_ttype</span><span class="plain"> </span><span class="identifier">given_tdata</span><span class="plain"> </span><span class="identifier">token_n</span><span class="plain"> </span><span class="identifier">token</span>
<span class="identifier">l</span><span class="plain"> </span><span class="identifier">o</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">j</span><span class="plain"> </span><span class="identifier">k</span><span class="plain"> </span><span class="identifier">and_parity</span><span class="plain"> </span><span class="identifier">single_object</span><span class="plain"> </span><span class="identifier">desc_wn</span><span class="plain"> </span><span class="identifier">many_flag</span>
<span class="identifier">token_allows_multiple</span><span class="plain"> </span><span class="identifier">prev_indef_wanted</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP24"></a><b>&#167;24. Parse Token Letter A. </b>Analyse token; handle all not involving object lists, break down others.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="identifier">token_filter</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">parser_inflection</span><span class="plain"> = </span><span class="identifier">name</span><span class="plain">;</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">given_ttype</span><span class="plain">) {</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="identifier">ELEMENTARY_TT</span><span class="plain">:</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">given_tdata</span><span class="plain">) {</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="identifier">SPECIAL_TOKEN</span><span class="plain">:</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">TryNumber</span><span class="plain">(</span><span class="identifier">wn</span><span class="plain">);</span>
<span class="identifier">special_word</span><span class="plain"> = </span><span class="identifier">NextWord</span><span class="plain">();</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> ~= -1000)</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">3</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" [Read special as the number "</span><span class="plain">, </span><span class="identifier">l</span><span class="plain">, </span><span class="string">"]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == -1000) {</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">3</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" [Read special word at word number "</span><span class="plain">, </span><span class="identifier">wn</span><span class="plain">, </span><span class="string">"]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">special_word</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">parsed_number</span><span class="plain"> = </span><span class="identifier">l</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">GPR_NUMBER</span><span class="plain">;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="identifier">NUMBER_TOKEN</span><span class="plain">:</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">l</span><span class="plain">=</span><span class="identifier">TryNumber</span><span class="plain">(</span><span class="identifier">wn</span><span class="plain">++);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == -1000) {</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">etype</span><span class="plain"> = </span><span class="identifier">NUMBER_PE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">GPR_FAIL</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain">&gt;=3) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" [Read number as "</span><span class="plain">, </span><span class="identifier">l</span><span class="plain">, </span><span class="string">"]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">parsed_number</span><span class="plain"> = </span><span class="identifier">l</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">GPR_NUMBER</span><span class="plain">;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="identifier">CREATURE_TOKEN</span><span class="plain">:</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">action_to_be</span><span class="plain"> == ##</span><span class="identifier">Answer</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> ##</span><span class="identifier">Ask</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> ##</span><span class="identifier">AskFor</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> ##</span><span class="identifier">Tell</span><span class="plain">)</span>
<span class="identifier">scope_reason</span><span class="plain"> = </span><span class="identifier">TALKING_REASON</span><span class="plain">;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="identifier">TOPIC_TOKEN</span><span class="plain">:</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">consult_from</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">line_ttype</span><span class="plain">--&gt;(</span><span class="identifier">token_n</span><span class="plain">+1) ~= </span><span class="identifier">PREPOSITION_TT</span><span class="plain">) &amp;&amp;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> (</span><span class="identifier">line_token</span><span class="plain">--&gt;(</span><span class="identifier">token_n</span><span class="plain">+1) ~= </span><span class="identifier">ENDIT_TOKEN</span><span class="plain">)) {</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">RunTimeProblem</span><span class="plain">(</span><span class="identifier">RTP_TEXTTOKENTOOHARD</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">GPR_PREPOSITION</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">do</span><span class="plain"> {</span>
<span class="identifier">o</span><span class="plain"> = </span><span class="identifier">NextWordStopped</span><span class="plain">();</span>
2020-04-07 03:06:09 +03:00
<span class="plain">} </span><span class="reserved">until</span><span class="plain"> (</span><span class="identifier">o</span><span class="plain"> == -1 || </span><span class="identifier">PrepositionChain</span><span class="plain">(</span><span class="identifier">o</span><span class="plain">, </span><span class="identifier">token_n</span><span class="plain">+1) ~= -1);</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">wn</span><span class="plain">--;</span>
<span class="identifier">consult_words</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">-</span><span class="identifier">consult_from</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">consult_words</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">GPR_FAIL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">action_to_be</span><span class="plain"> == ##</span><span class="identifier">Ask</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> ##</span><span class="identifier">Answer</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> ##</span><span class="identifier">Tell</span><span class="plain">) {</span>
<span class="identifier">o</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">; </span><span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">consult_from</span><span class="plain">; </span><span class="identifier">parsed_number</span><span class="plain"> = </span><span class="identifier">NextWord</span><span class="plain">();</span>
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">o</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">1</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">o</span><span class="plain">==-1 &amp;&amp; (</span><span class="identifier">line_ttype</span><span class="plain">--&gt;(</span><span class="identifier">token_n</span><span class="plain">+1) == </span><span class="identifier">PREPOSITION_TT</span><span class="plain">))</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">GPR_FAIL</span><span class="plain">; </span><span class="comment">don't infer if required preposition is absent</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">GPR_PREPOSITION</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="identifier">PREPOSITION_TT</span><span class="plain">:</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Is it an unnecessary alternative preposition, when a previous choice</span>
<span class="comment">has already been matched?</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">token</span><span class="plain">-&gt;0) &amp; </span><span class="constant">$10</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">GPR_PREPOSITION</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">If we've run out of the player's input, but still have parameters to</span>
<span class="comment">specify, we go into "infer" mode, remembering where we are and the</span>
<span class="comment">preposition we are inferring...</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wn</span><span class="plain"> &gt; </span><span class="identifier">num_words</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inferfrom</span><span class="plain">==0 &amp;&amp; </span><span class="identifier">parameters</span><span class="plain">&lt;</span><span class="identifier">params_wanted</span><span class="plain">) {</span>
<span class="identifier">inferfrom</span><span class="plain"> = </span><span class="identifier">pcount</span><span class="plain">; </span><span class="identifier">inferword</span><span class="plain"> = </span><span class="identifier">token</span><span class="plain">;</span>
<span class="identifier">pattern</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain"> = </span><span class="identifier">REPARSE_CODE</span><span class="plain"> + </span><span class="identifier">VM_DictionaryAddressToNumber</span><span class="plain">(</span><span class="identifier">given_tdata</span><span class="plain">);</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">If we are not inferring, then the line is wrong...</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inferfrom</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> -1;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">If not, then the line is right but we mark in the preposition...</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">pattern</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain"> = </span><span class="identifier">REPARSE_CODE</span><span class="plain"> + </span><span class="identifier">VM_DictionaryAddressToNumber</span><span class="plain">(</span><span class="identifier">given_tdata</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">GPR_PREPOSITION</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">o</span><span class="plain"> = </span><span class="identifier">NextWord</span><span class="plain">();</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">pattern</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain"> = </span><span class="identifier">REPARSE_CODE</span><span class="plain"> + </span><span class="identifier">VM_DictionaryAddressToNumber</span><span class="plain">(</span><span class="identifier">o</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Whereas, if the player has typed something here, see if it is the</span>
<span class="comment">required preposition... if it's wrong, the line must be wrong,</span>
<span class="comment">but if it's right, the token is passed (jump to finish this token).</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">o</span><span class="plain"> == </span><span class="identifier">given_tdata</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">GPR_PREPOSITION</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PrepositionChain</span><span class="plain">(</span><span class="identifier">o</span><span class="plain">, </span><span class="identifier">token_n</span><span class="plain">) ~= -1) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">GPR_PREPOSITION</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> -1;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="identifier">GPR_TT</span><span class="plain">:</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">l</span><span class="plain"> = </span><span class="reserved">indirect</span><span class="plain">(</span><span class="identifier">given_tdata</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">3</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" [Outside parsing routine returned "</span><span class="plain">, </span><span class="identifier">l</span><span class="plain">, </span><span class="string">"]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">l</span><span class="plain">;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="identifier">SCOPE_TT</span><span class="plain">:</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">scope_token</span><span class="plain"> = </span><span class="identifier">given_tdata</span><span class="plain">;</span>
<span class="identifier">scope_stage</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">3</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" [Scope routine called at stage 1]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">l</span><span class="plain"> = </span><span class="reserved">indirect</span><span class="plain">(</span><span class="identifier">scope_token</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">3</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" [Scope routine returned multiple-flag of "</span><span class="plain">, </span><span class="identifier">l</span><span class="plain">, </span><span class="string">"]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) </span><span class="identifier">given_tdata</span><span class="plain"> = </span><span class="identifier">MULTI_TOKEN</span><span class="plain">; </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">given_tdata</span><span class="plain"> = </span><span class="identifier">NOUN_TOKEN</span><span class="plain">;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="identifier">ATTR_FILTER_TT</span><span class="plain">:</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">token_filter</span><span class="plain"> = </span><span class="constant">1</span><span class="plain"> + </span><span class="identifier">given_tdata</span><span class="plain">;</span>
<span class="identifier">given_tdata</span><span class="plain"> = </span><span class="identifier">NOUN_TOKEN</span><span class="plain">;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="identifier">ROUTINE_FILTER_TT</span><span class="plain">:</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">token_filter</span><span class="plain"> = </span><span class="identifier">given_tdata</span><span class="plain">;</span>
<span class="identifier">given_tdata</span><span class="plain"> = </span><span class="identifier">NOUN_TOKEN</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">} </span><span class="comment">end of switch(given_ttype)</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">token</span><span class="plain"> = </span><span class="identifier">given_tdata</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP25"></a><b>&#167;25. Parse Token Letter B. </b>Begin parsing an object list.
</p>
<pre class="display">
2020-04-07 03:06:09 +03:00
<span class="comment">There are now three possible ways we can be here:</span>
2020-04-14 19:56:54 +03:00
<span class="comment"> parsing an elementary token other than "special" or "number";</span>
<span class="comment"> parsing a scope token;</span>
<span class="comment"> parsing a noun-filter token (either by routine or attribute).</span>
2020-04-07 03:06:09 +03:00
<span class="comment">In each case, token holds the type of elementary parse to</span>
<span class="comment">perform in matching one or more objects, and</span>
<span class="comment">token_filter is 0 (default), an attribute + 1 for an attribute filter</span>
<span class="comment">or a routine address for a routine filter.</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">token_allows_multiple</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">token</span><span class="plain"> == </span><span class="identifier">MULTI_TOKEN</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">MULTIHELD_TOKEN</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">MULTIEXCEPT_TOKEN</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">MULTIINSIDE_TOKEN</span><span class="plain">)</span>
<span class="identifier">token_allows_multiple</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="identifier">many_flag</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">; </span><span class="identifier">and_parity</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">; </span><span class="identifier">dont_infer</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP26"></a><b>&#167;26. Parse Token Letter C. </b>Parse descriptors (articles, pronouns, etc.) in the list.
</p>
<pre class="display">
2020-04-07 03:06:09 +03:00
<span class="comment">We expect to find a list of objects next in what the player's typed.</span>
2020-01-13 13:02:57 +02:00
2020-04-08 01:02:44 +03:00
<span class="plain"> .</span><span class="identifier">ObjectList</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">3</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" [Object list from word "</span><span class="plain">, </span><span class="identifier">wn</span><span class="plain">, </span><span class="string">"]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
2020-04-07 03:06:09 +03:00
<span class="comment">Take an advance look at the next word: if it's "it" or "them", and these</span>
<span class="comment">are unset, set the appropriate error number and give up on the line</span>
<span class="comment">(if not, these are still parsed in the usual way - it is not assumed</span>
<span class="comment">that they still refer to something in scope)</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">o</span><span class="plain"> = </span><span class="identifier">NextWord</span><span class="plain">(); </span><span class="identifier">wn</span><span class="plain">--;</span>
<span class="identifier">pronoun_word</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">pronoun_obj</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">PronounValue</span><span class="plain">(</span><span class="identifier">o</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">pronoun_word</span><span class="plain"> = </span><span class="identifier">o</span><span class="plain">; </span><span class="identifier">pronoun_obj</span><span class="plain"> = </span><span class="identifier">l</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Don't assume this is a use of an unset pronoun until the</span>
<span class="comment">descriptors have been checked, because it might be an</span>
<span class="comment">article (or some such) instead</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain">=1 : </span><span class="identifier">l</span><span class="plain">&lt;=</span><span class="identifier">LanguageDescriptors</span><span class="plain">--&gt;0 : </span><span class="identifier">l</span><span class="plain">=</span><span class="identifier">l</span><span class="plain">+4)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">o</span><span class="plain"> == </span><span class="identifier">LanguageDescriptors</span><span class="plain">--&gt;</span><span class="identifier">l</span><span class="plain">) </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">AssumeDescriptor</span><span class="plain">;</span>
<span class="identifier">pronoun__word</span><span class="plain"> = </span><span class="identifier">pronoun_word</span><span class="plain">; </span><span class="identifier">pronoun__obj</span><span class="plain"> = </span><span class="identifier">pronoun_obj</span><span class="plain">;</span>
<span class="identifier">etype</span><span class="plain"> = </span><span class="identifier">VAGUE_PE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">3</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" [Stop: unset pronoun]^"</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">GPR_FAIL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> .</span><span class="identifier">AssumeDescriptor</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">o</span><span class="plain"> == </span><span class="identifier">ME1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">ME2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">ME3__WD</span><span class="plain">) { </span><span class="identifier">pronoun_word</span><span class="plain"> = </span><span class="identifier">o</span><span class="plain">; </span><span class="identifier">pronoun_obj</span><span class="plain"> = </span><span class="identifier">player</span><span class="plain">; }</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">allow_plurals</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">; </span><span class="identifier">desc_wn</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> .</span><span class="identifier">TryAgain</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">First, we parse any descriptive words (like "the", "five" or "every"):</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">Descriptors</span><span class="plain">(</span><span class="identifier">token_allows_multiple</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) { </span><span class="identifier">etype</span><span class="plain"> = </span><span class="identifier">l</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">; }</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> .</span><span class="identifier">TryAgain2</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP27"></a><b>&#167;27. Parse Token Letter D. </b>Parse an object name.
</p>
<pre class="display">
2020-04-07 03:06:09 +03:00
<span class="comment">This is an actual specified object, and is therefore where a typing error</span>
<span class="comment">is most likely to occur, so we set:</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">oops_from</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">So, two cases. Case 1: token not equal to "held" (so, no implicit takes)</span>
<span class="comment">but we may well be dealing with multiple objects</span>
2020-01-13 13:02:57 +02:00
2020-04-07 03:06:09 +03:00
<span class="comment">In either case below we use NounDomain, giving it the token number as</span>
<span class="comment">context, and two places to look: among the actor's possessions, and in the</span>
<span class="comment">present location. (Note that the order depends on which is likeliest.)</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">token</span><span class="plain"> ~= </span><span class="identifier">HELD_TOKEN</span><span class="plain">) {</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">multiple_object</span><span class="plain">--&gt;0;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">3</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" [Calling NounDomain on location and actor]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">NounDomain</span><span class="plain">(</span><span class="identifier">actors_location</span><span class="plain">, </span><span class="identifier">actor</span><span class="plain">, </span><span class="identifier">token</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="identifier">REPARSE_CODE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">l</span><span class="plain">; </span><span class="comment">Reparse after Q&amp;A</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_wanted</span><span class="plain"> == </span><span class="identifier">INDEF_ALL_WANTED</span><span class="plain"> &amp;&amp; </span><span class="identifier">l</span><span class="plain"> == </span><span class="constant">0</span><span class="plain"> &amp;&amp; </span><span class="identifier">number_matched</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">)</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">l</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="comment">ReviseMulti if TAKE ALL FROM empty container</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">token_allows_multiple</span><span class="plain"> &amp;&amp; ~~</span><span class="identifier">multiflag</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">best_etype</span><span class="plain">==</span><span class="identifier">MULTI_PE</span><span class="plain">) </span><span class="identifier">best_etype</span><span class="plain">=</span><span class="identifier">STUCK_PE</span><span class="plain">;</span>
<span class="identifier">multiflag</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_possambig</span><span class="plain">) {</span>
<span class="identifier">ResetDescriptors</span><span class="plain">();</span>
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">desc_wn</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">TryAgain2</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> == </span><span class="identifier">MULTI_PE</span><span class="plain"> &amp;&amp; </span><span class="identifier">multiflag</span><span class="plain">) </span><span class="identifier">etype</span><span class="plain"> = </span><span class="identifier">STUCK_PE</span><span class="plain">;</span>
<span class="identifier">etype</span><span class="plain">=</span><span class="identifier">CantSee</span><span class="plain">();</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">FailToken</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">} </span><span class="comment">Choose best error</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">3</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> &gt; </span><span class="constant">1</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" [ND returned "</span><span class="plain">, (</span><span class="identifier">the</span><span class="plain">) </span><span class="identifier">l</span><span class="plain">, </span><span class="string">"]^"</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" [ND appended to the multiple object list:^"</span><span class="plain">;</span>
<span class="identifier">k</span><span class="plain"> = </span><span class="identifier">multiple_object</span><span class="plain">--&gt;0;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=</span><span class="identifier">i</span><span class="plain">+1 : </span><span class="identifier">j</span><span class="plain">&lt;=</span><span class="identifier">k</span><span class="plain"> : </span><span class="identifier">j</span><span class="plain">++)</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" Entry "</span><span class="plain">, </span><span class="identifier">j</span><span class="plain">, </span><span class="string">": "</span><span class="plain">, (</span><span class="identifier">The</span><span class="plain">) </span><span class="identifier">multiple_object</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain">,</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="string">" ("</span><span class="plain">, </span><span class="identifier">multiple_object</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain">, </span><span class="string">")^"</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">print</span><span class="plain"> </span><span class="string">" List now has size "</span><span class="plain">, </span><span class="identifier">k</span><span class="plain">, </span><span class="string">"]^"</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (~~</span><span class="identifier">many_flag</span><span class="plain">) </span><span class="identifier">many_flag</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">else</span><span class="plain"> { </span><span class="comment">Merge with earlier ones</span>
<span class="identifier">k</span><span class="plain"> = </span><span class="identifier">multiple_object</span><span class="plain">--&gt;0; </span><span class="comment">(with either parity)</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">multiple_object</span><span class="plain">--&gt;0 = </span><span class="identifier">i</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=</span><span class="identifier">i</span><span class="plain">+1 : </span><span class="identifier">j</span><span class="plain">&lt;=</span><span class="identifier">k</span><span class="plain"> : </span><span class="identifier">j</span><span class="plain">++) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">and_parity</span><span class="plain">) </span><span class="identifier">MultiAdd</span><span class="plain">(</span><span class="identifier">multiple_object</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">MultiSub</span><span class="plain">(</span><span class="identifier">multiple_object</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">3</span><span class="plain">)</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" [Merging "</span><span class="plain">, </span><span class="identifier">k</span><span class="plain">-</span><span class="identifier">i</span><span class="plain">, </span><span class="string">" new objects to the "</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="string">" old ones]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">else</span><span class="plain"> {</span>
2020-04-07 03:06:09 +03:00
<span class="comment">A single object was indeed found</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">match_length</span><span class="plain"> == </span><span class="constant">0</span><span class="plain"> &amp;&amp; </span><span class="identifier">indef_possambig</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="comment">So the answer had to be inferred from no textual data,</span>
<span class="comment">and we know that there was an ambiguity in the descriptor</span>
<span class="comment">stage (such as a word which could be a pronoun being</span>
<span class="comment">parsed as an article or possessive). It's worth having</span>
<span class="comment">another go.</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">ResetDescriptors</span><span class="plain">();</span>
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">desc_wn</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">TryAgain2</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">token</span><span class="plain"> == </span><span class="identifier">CREATURE_TOKEN</span><span class="plain">) &amp;&amp; (</span><span class="identifier">CreatureTest</span><span class="plain">(</span><span class="identifier">l</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">)) {</span>
<span class="identifier">etype</span><span class="plain"> = </span><span class="identifier">ANIMA_PE</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">FailToken</span><span class="plain">;</span>
2020-04-14 19:56:54 +03:00
<span class="plain">} </span><span class="comment"> Animation is required</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (~~</span><span class="identifier">many_flag</span><span class="plain">) </span><span class="identifier">single_object</span><span class="plain"> = </span><span class="identifier">l</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">and_parity</span><span class="plain">) </span><span class="identifier">MultiAdd</span><span class="plain">(</span><span class="identifier">l</span><span class="plain">); </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">MultiSub</span><span class="plain">(</span><span class="identifier">l</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">3</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" [Combining "</span><span class="plain">, (</span><span class="identifier">the</span><span class="plain">) </span><span class="identifier">l</span><span class="plain">, </span><span class="string">" with list]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">else</span><span class="plain"> {</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Case 2: token is "held" (which fortunately can't take multiple objects)</span>
<span class="comment">and may generate an implicit take</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">NounDomain</span><span class="plain">(</span><span class="identifier">actor</span><span class="plain">,</span><span class="identifier">actors_location</span><span class="plain">,</span><span class="identifier">token</span><span class="plain">); </span><span class="comment">Same as above...</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="identifier">REPARSE_CODE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">l</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_possambig</span><span class="plain">) {</span>
<span class="identifier">ResetDescriptors</span><span class="plain">();</span>
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">desc_wn</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">TryAgain2</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">etype</span><span class="plain"> = </span><span class="identifier">CantSee</span><span class="plain">(); </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">FailToken</span><span class="plain">; </span><span class="comment">Choose best error</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">...until it produces something not held by the actor. Then an implicit</span>
<span class="comment">take must be tried. If this is already happening anyway, things are too</span>
<span class="comment">confused and we have to give up (but saving the oops marker so as to get</span>
<span class="comment">it on the right word afterwards).</span>
<span class="comment">The point of this last rule is that a sequence like</span>
2020-04-14 19:56:54 +03:00
<span class="comment"> &gt; read newspaper</span>
<span class="comment"> (taking the newspaper first)</span>
<span class="comment"> The dwarf unexpectedly prevents you from taking the newspaper!</span>
2020-04-07 03:06:09 +03:00
<span class="comment">should not be allowed to go into an infinite repeat - read becomes</span>
<span class="comment">take then read, but take has no effect, so read becomes take then read...</span>
<span class="comment">Anyway for now all we do is record the number of the object to take.</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">o</span><span class="plain"> = </span><span class="reserved">parent</span><span class="plain">(</span><span class="identifier">l</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">o</span><span class="plain"> ~= </span><span class="identifier">actor</span><span class="plain">) {</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">3</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" [Allowing object "</span><span class="plain">, (</span><span class="identifier">the</span><span class="plain">) </span><span class="identifier">l</span><span class="plain">, </span><span class="string">" for now]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">single_object</span><span class="plain"> = </span><span class="identifier">l</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">} </span><span class="comment">end of if (token ~= HELD_TOKEN) else</span>
2020-04-07 03:06:09 +03:00
<span class="comment">The following moves the word marker to just past the named object...</span>
2020-04-07 03:06:09 +03:00
<span class="comment">if (match_from ~= oops_from) print match_from, " vs ", oops_from, "^";</span>
2020-04-14 19:56:54 +03:00
<span class="comment"> wn = oops_from + match_length;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">match_from</span><span class="plain"> + </span><span class="identifier">match_length</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP28"></a><b>&#167;28. Parse Token Letter E. </b>Parse connectives (AND, BUT, etc.) and go back to (C).
</p>
<pre class="display">
2020-04-07 03:06:09 +03:00
<span class="comment">Object(s) specified now: is that the end of the list, or have we reached</span>
<span class="comment">"and", "but" and so on? If so, create a multiple-object list if we</span>
<span class="comment">haven't already (and are allowed to).</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> .</span><span class="identifier">NextInList</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">o</span><span class="plain"> = </span><span class="identifier">NextWord</span><span class="plain">();</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">o</span><span class="plain"> == </span><span class="identifier">AND1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">AND2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">AND3__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">BUT1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">BUT2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">BUT3__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">comma_word</span><span class="plain">) {</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">3</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" [Read connective '"</span><span class="plain">, (</span><span class="identifier">address</span><span class="plain">) </span><span class="identifier">o</span><span class="plain">, </span><span class="string">"']^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (~~</span><span class="identifier">token_allows_multiple</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">multiflag</span><span class="plain">) </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">PassToken</span><span class="plain">; </span><span class="comment">give UPTO_PE error</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">etype</span><span class="plain">=</span><span class="identifier">MULTI_PE</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">FailToken</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">o</span><span class="plain"> == </span><span class="identifier">BUT1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">BUT2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">BUT3__WD</span><span class="plain">) </span><span class="identifier">and_parity</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">-</span><span class="identifier">and_parity</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (~~</span><span class="identifier">many_flag</span><span class="plain">) {</span>
<span class="identifier">multiple_object</span><span class="plain">--&gt;0 = </span><span class="constant">1</span><span class="plain">;</span>
<span class="identifier">multiple_object</span><span class="plain">--&gt;1 = </span><span class="identifier">single_object</span><span class="plain">;</span>
<span class="identifier">many_flag</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">3</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" [Making new list from "</span><span class="plain">, (</span><span class="identifier">the</span><span class="plain">) </span><span class="identifier">single_object</span><span class="plain">, </span><span class="string">"]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">dont_infer</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">; </span><span class="identifier">inferfrom</span><span class="plain">=0; </span><span class="comment">Don't print (inferences)</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">ObjectList</span><span class="plain">; </span><span class="comment">And back around</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">wn</span><span class="plain">--; </span><span class="comment">Word marker back to first not-understood word</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP29"></a><b>&#167;29. Parse Token Letter F. </b>Return the conclusion of parsing an object list.
</p>
<pre class="display">
2020-04-07 03:06:09 +03:00
<span class="comment">Happy or unhappy endings:</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> .</span><span class="identifier">PassToken</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">many_flag</span><span class="plain">) {</span>
<span class="identifier">single_object</span><span class="plain"> = </span><span class="identifier">GPR_MULTIPLE</span><span class="plain">;</span>
<span class="identifier">multi_context</span><span class="plain"> = </span><span class="identifier">token</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_mode</span><span class="plain"> == </span><span class="constant">1</span><span class="plain"> &amp;&amp; </span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">PLURAL_BIT</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">token</span><span class="plain"> == </span><span class="identifier">MULTIEXCEPT_TOKEN</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">MULTIINSIDE_TOKEN</span><span class="plain">) </span><span class="identifier">multi_context</span><span class="plain"> = </span><span class="identifier">token</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_wanted</span><span class="plain"> &lt; </span><span class="identifier">INDEF_ALL_WANTED</span><span class="plain"> &amp;&amp; </span><span class="identifier">indef_wanted</span><span class="plain"> &gt; </span><span class="constant">1</span><span class="plain">) {</span>
<span class="identifier">multi_had</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="identifier">multi_wanted</span><span class="plain"> = </span><span class="identifier">indef_wanted</span><span class="plain">;</span>
<span class="identifier">etype</span><span class="plain"> = </span><span class="identifier">TOOFEW_PE</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">FailToken</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">single_object</span><span class="plain">;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> .</span><span class="identifier">FailToken</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
2020-04-07 03:06:09 +03:00
<span class="comment">If we were only guessing about it being a plural, try again but only</span>
<span class="comment">allowing singulars (so that words like "six" are not swallowed up as</span>
<span class="comment">Descriptors)</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">allow_plurals</span><span class="plain"> &amp;&amp; </span><span class="identifier">indef_guess_p</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) {</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">4</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" [Retrying singulars after failure "</span><span class="plain">, </span><span class="identifier">etype</span><span class="plain">, </span><span class="string">"]^"</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">;</span>
<span class="identifier">prev_indef_wanted</span><span class="plain"> = </span><span class="identifier">indef_wanted</span><span class="plain">;</span>
<span class="identifier">allow_plurals</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">desc_wn</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">TryAgain</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">indef_wanted</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain"> || </span><span class="identifier">prev_indef_wanted</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) &amp;&amp; (~~</span><span class="identifier">multiflag</span><span class="plain">)) </span><span class="identifier">etype</span><span class="plain"> = </span><span class="identifier">MULTI_PE</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">GPR_FAIL</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">]; </span><span class="comment">end of ParseToken__</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP30"></a><b>&#167;30. Descriptors. </b>In grammatical terms, a descriptor appears at the front of an English noun
phrase and clarifies the quantity or specific identity of what is referred
2020-04-14 19:56:54 +03:00
to: for instance, {\it my} mirror, {\it the} dwarf, {\it that} woman.
(Numbers, as in {\it four} duets, are also descriptors in linguistics:
but the I6 parser doesn't handle them that way.)
</p>
<p class="inwebparagraph">Slightly unfortunately, the bitmap constants used for descriptors in the
I6 parser have names in the form <code class="display"><span class="extract">*_BIT</span></code>, coinciding with the names of
style bits in the list-writer: but they never occur in the same context.
</p>
<p class="inwebparagraph">The actual words used as descriptors are read from tables in the language
definition. <code class="display"><span class="extract">ArticleDescriptors</span></code> uses this table to move current word
marker past a run of one or more descriptors which refer to the definite
or indefinite article.
</p>
<pre class="display">
2020-04-14 19:56:54 +03:00
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">OTHER_BIT</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="comment"> These will be used in Adjudicate()</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">MY_BIT</span><span class="plain"> = </span><span class="constant">2</span><span class="plain">; </span><span class="comment"> to disambiguate choices</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">THAT_BIT</span><span class="plain"> = </span><span class="constant">4</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">PLURAL_BIT</span><span class="plain"> = </span><span class="constant">8</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">LIT_BIT</span><span class="plain"> = </span><span class="constant">16</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">UNLIT_BIT</span><span class="plain"> = </span><span class="constant">32</span><span class="plain">;</span>
<span class="plain">[ </span><span class="identifier">ResetDescriptors</span><span class="plain">;</span>
<span class="identifier">indef_mode</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">indef_type</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">indef_wanted</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">indef_guess_p</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">indef_possambig</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
<span class="identifier">indef_owner</span><span class="plain"> = </span><span class="reserved">nothing</span><span class="plain">;</span>
<span class="identifier">indef_cases</span><span class="plain"> = </span><span class="constant">$$111111111111</span><span class="plain">;</span>
<span class="identifier">indef_nspec_at</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">ArticleDescriptors</span><span class="plain"> </span><span class="identifier">o</span><span class="plain"> </span><span class="identifier">x</span><span class="plain"> </span><span class="identifier">flag</span><span class="plain"> </span><span class="identifier">cto</span><span class="plain"> </span><span class="identifier">type</span><span class="plain"> </span><span class="identifier">n</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wn</span><span class="plain"> &gt; </span><span class="identifier">num_words</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">flag</span><span class="plain">=</span><span class="reserved">true</span><span class="plain"> : </span><span class="identifier">flag</span><span class="plain"> :) {</span>
<span class="identifier">o</span><span class="plain"> = </span><span class="identifier">NextWordStopped</span><span class="plain">(); </span><span class="identifier">flag</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="reserved">for</span><span class="plain"> (</span><span class="identifier">x</span><span class="plain">=1 : </span><span class="identifier">x</span><span class="plain">&lt;=</span><span class="identifier">LanguageDescriptors</span><span class="plain">--&gt;0 : </span><span class="identifier">x</span><span class="plain">=</span><span class="identifier">x</span><span class="plain">+4)</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">o</span><span class="plain"> == </span><span class="identifier">LanguageDescriptors</span><span class="plain">--&gt;</span><span class="identifier">x</span><span class="plain">) {</span>
<span class="identifier">type</span><span class="plain"> = </span><span class="identifier">LanguageDescriptors</span><span class="plain">--&gt;(</span><span class="identifier">x</span><span class="plain">+2);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">type</span><span class="plain"> == </span><span class="identifier">DEFART_PK</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">INDEFART_PK</span><span class="plain">) </span><span class="identifier">flag</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">wn</span><span class="plain">--;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP31"></a><b>&#167;31. Parsing Descriptors. </b>The <code class="display"><span class="extract">Descriptors()</span></code> routine parses the descriptors at the head of a noun
phrase, leaving the current word marker <code class="display"><span class="extract">wn</span></code> at the first word of the
noun phrase's body. It is allowed to set up for a plural only if <code class="display"><span class="extract">allow_p</span></code>
is set; it returns a parser error number, or 0 if no error occurred.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">Descriptors</span><span class="plain"> </span><span class="identifier">o</span><span class="plain"> </span><span class="identifier">x</span><span class="plain"> </span><span class="identifier">flag</span><span class="plain"> </span><span class="identifier">cto</span><span class="plain"> </span><span class="identifier">type</span><span class="plain"> </span><span class="identifier">n</span><span class="plain">;</span>
<span class="identifier">ResetDescriptors</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wn</span><span class="plain"> &gt; </span><span class="identifier">num_words</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">flag</span><span class="plain">=</span><span class="reserved">true</span><span class="plain"> : </span><span class="identifier">flag</span><span class="plain"> :) {</span>
<span class="identifier">o</span><span class="plain"> = </span><span class="identifier">NextWordStopped</span><span class="plain">(); </span><span class="identifier">flag</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="reserved">for</span><span class="plain"> (</span><span class="identifier">x</span><span class="plain">=1 : </span><span class="identifier">x</span><span class="plain">&lt;=</span><span class="identifier">LanguageDescriptors</span><span class="plain">--&gt;0 : </span><span class="identifier">x</span><span class="plain">=</span><span class="identifier">x</span><span class="plain">+4)</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">o</span><span class="plain"> == </span><span class="identifier">LanguageDescriptors</span><span class="plain">--&gt;</span><span class="identifier">x</span><span class="plain">) {</span>
<span class="identifier">flag</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="identifier">type</span><span class="plain"> = </span><span class="identifier">LanguageDescriptors</span><span class="plain">--&gt;(</span><span class="identifier">x</span><span class="plain">+2);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">type</span><span class="plain"> ~= </span><span class="identifier">DEFART_PK</span><span class="plain">) </span><span class="identifier">indef_mode</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="identifier">indef_possambig</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="identifier">indef_cases</span><span class="plain"> = </span><span class="identifier">indef_cases</span><span class="plain"> &amp; (</span><span class="identifier">LanguageDescriptors</span><span class="plain">--&gt;(</span><span class="identifier">x</span><span class="plain">+1));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">type</span><span class="plain"> == </span><span class="identifier">POSSESS_PK</span><span class="plain">) {</span>
<span class="identifier">cto</span><span class="plain"> = </span><span class="identifier">LanguageDescriptors</span><span class="plain">--&gt;(</span><span class="identifier">x</span><span class="plain">+3);</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">cto</span><span class="plain">) {</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="constant">0</span><span class="plain">: </span><span class="identifier">indef_type</span><span class="plain"> = </span><span class="identifier">indef_type</span><span class="plain"> | </span><span class="identifier">MY_BIT</span><span class="plain">;</span>
<span class="plain"> </span><span class="constant">1</span><span class="plain">: </span><span class="identifier">indef_type</span><span class="plain"> = </span><span class="identifier">indef_type</span><span class="plain"> | </span><span class="identifier">THAT_BIT</span><span class="plain">;</span>
<span class="plain"> </span><span class="reserved">default</span><span class="plain">:</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">indef_owner</span><span class="plain"> = </span><span class="identifier">PronounValue</span><span class="plain">(</span><span class="identifier">cto</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_owner</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">indef_owner</span><span class="plain"> = </span><span class="identifier">InformParser</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">type</span><span class="plain"> == </span><span class="identifier">light</span><span class="plain">) </span><span class="identifier">indef_type</span><span class="plain"> = </span><span class="identifier">indef_type</span><span class="plain"> | </span><span class="identifier">LIT_BIT</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">type</span><span class="plain"> == -</span><span class="identifier">light</span><span class="plain">) </span><span class="identifier">indef_type</span><span class="plain"> = </span><span class="identifier">indef_type</span><span class="plain"> | </span><span class="identifier">UNLIT_BIT</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">o</span><span class="plain"> == </span><span class="identifier">OTHER1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">OTHER2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">OTHER3__WD</span><span class="plain">) {</span>
<span class="identifier">indef_mode</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="identifier">flag</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="identifier">indef_type</span><span class="plain"> = </span><span class="identifier">indef_type</span><span class="plain"> | </span><span class="identifier">OTHER_BIT</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">o</span><span class="plain"> == </span><span class="identifier">ALL1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">ALL2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">ALL3__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">ALL4__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">ALL5__WD</span><span class="plain">) {</span>
<span class="identifier">indef_mode</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="identifier">flag</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="identifier">indef_wanted</span><span class="plain"> = </span><span class="identifier">INDEF_ALL_WANTED</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">take_all_rule</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) </span><span class="identifier">take_all_rule</span><span class="plain"> = </span><span class="constant">2</span><span class="plain">;</span>
<span class="identifier">indef_type</span><span class="plain"> = </span><span class="identifier">indef_type</span><span class="plain"> | </span><span class="identifier">PLURAL_BIT</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">allow_plurals</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">NextWordStopped</span><span class="plain">() ~= -1 </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">THEN1__WD</span><span class="plain">) { </span><span class="identifier">wn</span><span class="plain">--; </span><span class="identifier">n</span><span class="plain"> = </span><span class="identifier">TryNumber</span><span class="plain">(</span><span class="identifier">wn</span><span class="plain">-1); } </span><span class="reserved">else</span><span class="plain"> { </span><span class="identifier">n</span><span class="plain">=0; </span><span class="identifier">wn</span><span class="plain">--; }</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">n</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) { </span><span class="identifier">indef_mode</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="identifier">flag</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">n</span><span class="plain"> &gt; </span><span class="constant">1</span><span class="plain">) {</span>
<span class="identifier">indef_guess_p</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="identifier">indef_mode</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="identifier">flag</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="identifier">indef_wanted</span><span class="plain"> = </span><span class="identifier">n</span><span class="plain">;</span>
<span class="identifier">indef_nspec_at</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">-1;</span>
<span class="identifier">indef_type</span><span class="plain"> = </span><span class="identifier">indef_type</span><span class="plain"> | </span><span class="identifier">PLURAL_BIT</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">flag</span><span class="plain"> == </span><span class="constant">1</span><span class="plain"> &amp;&amp; </span><span class="identifier">NextWordStopped</span><span class="plain">() ~= </span><span class="identifier">OF1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">OF2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">OF3__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">OF4__WD</span><span class="plain">)</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">wn</span><span class="plain">--; </span><span class="comment">Skip 'of' after these</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">wn</span><span class="plain">--;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">SafeSkipDescriptors</span><span class="plain">;</span>
<span class="plain">@</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">indef_mode</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">indef_type</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">indef_wanted</span><span class="plain">;</span>
<span class="plain">@</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">indef_guess_p</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">indef_possambig</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">indef_owner</span><span class="plain">;</span>
<span class="plain">@</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">indef_cases</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">indef_nspec_at</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">Descriptors</span><span class="plain">();</span>
2020-01-13 13:02:57 +02:00
<span class="plain">@</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">indef_nspec_at</span><span class="plain">; @</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">indef_cases</span><span class="plain">;</span>
<span class="plain">@</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">indef_owner</span><span class="plain">; @</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">indef_possambig</span><span class="plain">; @</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">indef_guess_p</span><span class="plain">;</span>
<span class="plain">@</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">indef_wanted</span><span class="plain">; @</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">indef_type</span><span class="plain">; @</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">indef_mode</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP32"></a><b>&#167;32. Preposition Chain. </b>A small utility for runs of prepositions.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">PrepositionChain</span><span class="plain"> </span><span class="identifier">wd</span><span class="plain"> </span><span class="identifier">index</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">line_tdata</span><span class="plain">--&gt;</span><span class="identifier">index</span><span class="plain"> == </span><span class="identifier">wd</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">wd</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">line_token</span><span class="plain">--&gt;</span><span class="identifier">index</span><span class="plain">)-&gt;0 &amp; </span><span class="constant">$20</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> -1;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">do</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">line_tdata</span><span class="plain">--&gt;</span><span class="identifier">index</span><span class="plain"> == </span><span class="identifier">wd</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">wd</span><span class="plain">;</span>
<span class="identifier">index</span><span class="plain">++;</span>
<span class="plain">} </span><span class="reserved">until</span><span class="plain"> ((</span><span class="identifier">line_token</span><span class="plain">--&gt;</span><span class="identifier">index</span><span class="plain"> == </span><span class="identifier">ENDIT_TOKEN</span><span class="plain">) || (((</span><span class="identifier">line_token</span><span class="plain">--&gt;</span><span class="identifier">index</span><span class="plain">)-&gt;0 &amp; </span><span class="constant">$10</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">));</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">return</span><span class="plain"> -1;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP33"></a><b>&#167;33. Creature. </b>Will this object do for an I6 <code class="display"><span class="extract">creature</span></code> token? (In I7 terms, this affects
the tokens "[someone]", "[somebody]", "[anyone]" and "[anybody]".)
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">CreatureTest</span><span class="plain"> </span><span class="identifier">obj</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">animate</span><span class="plain">) </span><span class="reserved">rtrue</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain"> </span><span class="reserved">hasnt</span><span class="plain"> </span><span class="identifier">talkable</span><span class="plain">) </span><span class="reserved">rfalse</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">action_to_be</span><span class="plain"> == ##</span><span class="identifier">Ask</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> ##</span><span class="identifier">Answer</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> ##</span><span class="identifier">Tell</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> ##</span><span class="identifier">AskFor</span><span class="plain">) </span><span class="reserved">rtrue</span><span class="plain">;</span>
<span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP34"></a><b>&#167;34. Noun Domain. </b><code class="display"><span class="extract">NounDomain</span></code> does the most substantial part of parsing an object name.
It is given two "domains" &mdash; usually a location and then the actor who is
looking &mdash; and a context (i.e. token type), and returns:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) 0 if no match at all could be made,
</li><li>(b) 1 if a multiple object was made,
2020-04-14 19:56:54 +03:00
</li><li>(c) \(k\) if object \(k\) was the one decided upon,
</li><li>(d) <code class="display"><span class="extract">REPARSE_CODE</span></code> if it asked a question of the player and consequently
rewrote the player's input, so that the whole parser should start again
on the rewritten input.
</li></ul>
<p class="inwebparagraph">In case (c), <code class="display"><span class="extract">NounDomain</span></code> also sets the variable <code class="display"><span class="extract">length_of_noun</span></code> to the
number of words in the input text matched to the noun. In case (b),
the multiple objects are added to <code class="display"><span class="extract">multiple_object</span></code> by hand (not by <code class="display"><span class="extract">MultiAdd</span></code>,
because we want to allow duplicates).
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">NounDomain</span><span class="plain"> </span><span class="identifier">domain1</span><span class="plain"> </span><span class="identifier">domain2</span><span class="plain"> </span><span class="identifier">context</span><span class="plain"> </span><span class="identifier">dont_ask</span>
<span class="identifier">first_word</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">j</span><span class="plain"> </span><span class="identifier">k</span><span class="plain"> </span><span class="identifier">l</span><span class="plain"> </span><span class="identifier">answer_words</span><span class="plain"> </span><span class="identifier">marker</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">4</span><span class="plain">) {</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" [NounDomain called at word "</span><span class="plain">, </span><span class="identifier">wn</span><span class="plain">, </span><span class="string">"^"</span><span class="plain">;</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_mode</span><span class="plain">) {</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"seeking indefinite object: "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">OTHER_BIT</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"other "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">MY_BIT</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"my "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">THAT_BIT</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"that "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">PLURAL_BIT</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"plural "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">LIT_BIT</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"lit "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">UNLIT_BIT</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"unlit "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_owner</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"owner:"</span><span class="plain">, (</span><span class="identifier">name</span><span class="plain">) </span><span class="identifier">indef_owner</span><span class="plain">;</span>
<span class="reserved">new_line</span><span class="plain">;</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" number wanted: "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_wanted</span><span class="plain"> == </span><span class="identifier">INDEF_ALL_WANTED</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"all"</span><span class="plain">; </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">print</span><span class="plain"> </span><span class="identifier">indef_wanted</span><span class="plain">;</span>
<span class="reserved">new_line</span><span class="plain">;</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" most likely GNAs of names: "</span><span class="plain">, </span><span class="identifier">indef_cases</span><span class="plain">, </span><span class="string">"^"</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"seeking definite object^"</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">match_length</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">number_matched</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">match_from</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">SearchScope</span><span class="plain">(</span><span class="identifier">domain1</span><span class="plain">, </span><span class="identifier">domain2</span><span class="plain">, </span><span class="identifier">context</span><span class="plain">);</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">4</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" [ND made "</span><span class="plain">, </span><span class="identifier">number_matched</span><span class="plain">, </span><span class="string">" matches]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">match_from</span><span class="plain">+</span><span class="identifier">match_length</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">If nothing worked at all, leave with the word marker skipped past the</span>
<span class="comment">first unmatched word...</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">number_matched</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) { </span><span class="identifier">wn</span><span class="plain">++; </span><span class="reserved">rfalse</span><span class="plain">; }</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Suppose that there really were some words being parsed (i.e., we did</span>
<span class="comment">not just infer). If so, and if there was only one match, it must be</span>
<span class="comment">right and we return it...</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">match_from</span><span class="plain"> &lt;= </span><span class="identifier">num_words</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">number_matched</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) {</span>
<span class="identifier">i</span><span class="plain">=</span><span class="identifier">match_list</span><span class="plain">--&gt;0;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">...now suppose that there was more typing to come, i.e. suppose that</span>
<span class="comment">the user entered something beyond this noun. If nothing ought to follow,</span>
<span class="comment">then there must be a mistake, (unless what does follow is just a full</span>
<span class="comment">stop, and or comma)</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wn</span><span class="plain"> &lt;= </span><span class="identifier">num_words</span><span class="plain">) {</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">NextWord</span><span class="plain">(); </span><span class="identifier">wn</span><span class="plain">--;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> ~= </span><span class="identifier">AND1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">AND2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">AND3__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">comma_word</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">THEN1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">THEN2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">THEN3__WD</span>
<span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">BUT1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">BUT2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">BUT3__WD</span><span class="plain">) {</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lookahead</span><span class="plain"> == </span><span class="identifier">ENDIT_TOKEN</span><span class="plain">) </span><span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Now look for a good choice, if there's more than one choice...</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">number_of_classes</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">number_matched</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) {</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">match_list</span><span class="plain">--&gt;0;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_mode</span><span class="plain"> == </span><span class="constant">1</span><span class="plain"> &amp;&amp; </span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">PLURAL_BIT</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">context</span><span class="plain"> == </span><span class="identifier">MULTI_TOKEN</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">MULTIHELD_TOKEN</span><span class="plain"> </span><span class="reserved">or</span>
<span class="identifier">MULTIEXCEPT_TOKEN</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">MULTIINSIDE_TOKEN</span><span class="plain"> </span><span class="reserved">or</span>
<span class="identifier">NOUN_TOKEN</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">HELD_TOKEN</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">CREATURE_TOKEN</span><span class="plain">) {</span>
<span class="identifier">BeginActivity</span><span class="plain">(</span><span class="identifier">DECIDING_WHETHER_ALL_INC_ACT</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ForActivity</span><span class="plain">(</span><span class="identifier">DECIDING_WHETHER_ALL_INC_ACT</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">RulebookFailed</span><span class="plain">())) </span><span class="reserved">rfalse</span><span class="plain">;</span>
<span class="identifier">EndActivity</span><span class="plain">(</span><span class="identifier">DECIDING_WHETHER_ALL_INC_ACT</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">number_matched</span><span class="plain"> &gt; </span><span class="constant">1</span><span class="plain">) {</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">number_matched</span><span class="plain"> &gt; </span><span class="constant">1</span><span class="plain">)</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0 : </span><span class="identifier">j</span><span class="plain">&lt;</span><span class="identifier">number_matched</span><span class="plain">-1 : </span><span class="identifier">j</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Identical</span><span class="plain">(</span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain">, </span><span class="identifier">match_list</span><span class="plain">--&gt;(</span><span class="identifier">j</span><span class="plain">+1)) == </span><span class="reserved">false</span><span class="plain">)</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">) </span><span class="identifier">dont_infer</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">Adjudicate</span><span class="plain">(</span><span class="identifier">context</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == -1) </span><span class="reserved">rfalse</span><span class="plain">;</span>
2020-04-14 19:56:54 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) </span><span class="reserved">rtrue</span><span class="plain">; </span><span class="comment"> Adjudicate has made a multiple</span>
<span class="plain"> </span><span class="comment"> object, and we pass it on</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">If i is non-zero here, one of two things is happening: either</span>
<span class="comment">(a) an inference has been successfully made that object i is</span>
2020-04-14 19:56:54 +03:00
<span class="comment"> the intended one from the user's specification, or</span>
2020-04-07 03:06:09 +03:00
<span class="comment">(b) the user finished typing some time ago, but we've decided</span>
2020-04-14 19:56:54 +03:00
<span class="comment"> on i because it's the only possible choice.</span>
2020-04-07 03:06:09 +03:00
<span class="comment">In either case we have to keep the pattern up to date,</span>
<span class="comment">note that an inference has been made and return.</span>
<span class="comment">(Except, we don't note which of a pile of identical objects.)</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dont_infer</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inferfrom</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">inferfrom</span><span class="plain">=</span><span class="identifier">pcount</span><span class="plain">;</span>
<span class="identifier">pattern</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dont_ask</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">match_list</span><span class="plain">--&gt;0;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">If we get here, there was no obvious choice of object to make. If in</span>
<span class="comment">fact we've already gone past the end of the player's typing (which</span>
<span class="comment">means the match list must contain every object in scope, regardless</span>
<span class="comment">of its name), then it's foolish to give an enormous list to choose</span>
<span class="comment">from - instead we go and ask a more suitable question...</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">match_from</span><span class="plain"> &gt; </span><span class="identifier">num_words</span><span class="plain">) </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">Incomplete</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Now we print up the question, using the equivalence classes as worked</span>
<span class="comment">out by Adjudicate() so as not to repeat ourselves on plural objects...</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">BeginActivity</span><span class="plain">(</span><span class="identifier">ASKING_WHICH_DO_YOU_MEAN_ACT</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ForActivity</span><span class="plain">(</span><span class="identifier">ASKING_WHICH_DO_YOU_MEAN_ACT</span><span class="plain">)) </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">SkipWhichQuestion</span><span class="plain">;</span>
<span class="identifier">j</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="identifier">marker</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=1 : </span><span class="identifier">i</span><span class="plain">&lt;=</span><span class="identifier">number_of_classes</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">while</span><span class="plain"> (((</span><span class="identifier">match_classes</span><span class="plain">--&gt;</span><span class="identifier">marker</span><span class="plain">) ~= </span><span class="identifier">i</span><span class="plain">) &amp;&amp; ((</span><span class="identifier">match_classes</span><span class="plain">--&gt;</span><span class="identifier">marker</span><span class="plain">) ~= -</span><span class="identifier">i</span><span class="plain">))</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">marker</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">marker</span><span class="plain"> </span><span class="reserved">hasnt</span><span class="plain"> </span><span class="identifier">animate</span><span class="plain">) </span><span class="identifier">j</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">) </span><span class="identifier">PARSER_CLARIF_INTERNAL_RM</span><span class="plain">(</span><span class="character">'A'</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">PARSER_CLARIF_INTERNAL_RM</span><span class="plain">(</span><span class="character">'B'</span><span class="plain">);</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">j</span><span class="plain"> = </span><span class="identifier">number_of_classes</span><span class="plain">; </span><span class="identifier">marker</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=1 : </span><span class="identifier">i</span><span class="plain">&lt;=</span><span class="identifier">number_of_classes</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">while</span><span class="plain"> (((</span><span class="identifier">match_classes</span><span class="plain">--&gt;</span><span class="identifier">marker</span><span class="plain">) ~= </span><span class="identifier">i</span><span class="plain">) &amp;&amp; ((</span><span class="identifier">match_classes</span><span class="plain">--&gt;</span><span class="identifier">marker</span><span class="plain">) ~= -</span><span class="identifier">i</span><span class="plain">)) </span><span class="identifier">marker</span><span class="plain">++;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">k</span><span class="plain"> = </span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">marker</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">match_classes</span><span class="plain">--&gt;</span><span class="identifier">marker</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> (</span><span class="identifier">the</span><span class="plain">) </span><span class="identifier">k</span><span class="plain">; </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">print</span><span class="plain"> (</span><span class="identifier">a</span><span class="plain">) </span><span class="identifier">k</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> &lt; </span><span class="identifier">j</span><span class="plain">-1) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">", "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="identifier">j</span><span class="plain">-1) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TEMPLATE_CONFIGURATION_BITMAP</span><span class="plain"> &amp; </span><span class="identifier">SERIAL_COMMA_TCBIT</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain"> ~= </span><span class="constant">2</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">","</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">PARSER_CLARIF_INTERNAL_RM</span><span class="plain">(</span><span class="character">'H'</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">print</span><span class="plain"> </span><span class="string">"?^"</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="plain">.</span><span class="identifier">SkipWhichQuestion</span><span class="plain">; </span><span class="identifier">EndActivity</span><span class="plain">(</span><span class="identifier">ASKING_WHICH_DO_YOU_MEAN_ACT</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="comment">...and get an answer:</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> .</span><span class="identifier">WhichOne</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=2 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">INPUT_BUFFER_LEN</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">buffer2</span><span class="plain">-&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="character">' '</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">TARGET_ZCODE</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">answer_words</span><span class="plain">=</span><span class="identifier">Keyboard</span><span class="plain">(</span><span class="identifier">buffer2</span><span class="plain">, </span><span class="identifier">parse2</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Conveniently, parse2--&gt;1 is the first word in both ZCODE and GLULX.</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">first_word</span><span class="plain"> = (</span><span class="identifier">parse2</span><span class="plain">--&gt;1);</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Take care of "all", because that does something too clever here to do</span>
<span class="comment">later on:</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">first_word</span><span class="plain"> == </span><span class="identifier">ALL1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">ALL2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">ALL3__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">ALL4__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">ALL5__WD</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">context</span><span class="plain"> == </span><span class="identifier">MULTI_TOKEN</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">MULTIHELD_TOKEN</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">MULTIEXCEPT_TOKEN</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">MULTIINSIDE_TOKEN</span><span class="plain">) {</span>
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">multiple_object</span><span class="plain">--&gt;0;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">number_matched</span><span class="plain"> &amp;&amp; </span><span class="identifier">l</span><span class="plain">+</span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">MATCH_LIST_WORDS</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">k</span><span class="plain"> = </span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">;</span>
<span class="identifier">multiple_object</span><span class="plain">--&gt;(</span><span class="identifier">i</span><span class="plain">+1+</span><span class="identifier">l</span><span class="plain">) = </span><span class="identifier">k</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">multiple_object</span><span class="plain">--&gt;0 = </span><span class="identifier">i</span><span class="plain">+</span><span class="identifier">l</span><span class="plain">;</span>
<span class="reserved">rtrue</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">PARSER_CLARIF_INTERNAL_RM</span><span class="plain">(</span><span class="character">'C'</span><span class="plain">);</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">WhichOne</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Look for a comma, and interpret this as a fresh conversation command</span>
<span class="comment">if so:</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=1 : </span><span class="identifier">i</span><span class="plain">&lt;=</span><span class="identifier">answer_words</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">WordFrom</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">parse2</span><span class="plain">) == </span><span class="identifier">comma_word</span><span class="plain">) {</span>
<span class="identifier">VM_CopyBuffer</span><span class="plain">(</span><span class="identifier">buffer</span><span class="plain">, </span><span class="identifier">buffer2</span><span class="plain">);</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">RECONSTRUCT_INPUT</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">If the first word of the reply can be interpreted as a verb, then</span>
<span class="comment">assume that the player has ignored the question and given a new</span>
<span class="comment">command altogether.</span>
<span class="comment">(This is one time when it's convenient that the directions are</span>
<span class="comment">not themselves verbs - thus, "north" as a reply to "Which, the north</span>
<span class="comment">or south door" is not treated as a fresh command but as an answer.)</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">first_word</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">j</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">; </span><span class="identifier">first_word</span><span class="plain"> = </span><span class="identifier">LanguageIsVerb</span><span class="plain">(</span><span class="identifier">buffer2</span><span class="plain">, </span><span class="identifier">parse2</span><span class="plain">, </span><span class="constant">1</span><span class="plain">); </span><span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">j</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">first_word</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">j</span><span class="plain"> = </span><span class="identifier">first_word</span><span class="plain">-&gt;#</span><span class="identifier">dict_par1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((0 ~= </span><span class="identifier">j</span><span class="plain">&amp;1) &amp;&amp; ~~</span><span class="identifier">LanguageVerbMayBeName</span><span class="plain">(</span><span class="identifier">first_word</span><span class="plain">)) {</span>
<span class="identifier">VM_CopyBuffer</span><span class="plain">(</span><span class="identifier">buffer</span><span class="plain">, </span><span class="identifier">buffer2</span><span class="plain">);</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">RECONSTRUCT_INPUT</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Now we insert the answer into the original typed command, as</span>
<span class="comment">words additionally describing the same object</span>
<span class="comment">(eg, &gt; take red button</span>
2020-04-14 19:56:54 +03:00
<span class="comment"> Which one, ...</span>
<span class="comment"> &gt; music</span>
2020-04-07 03:06:09 +03:00
<span class="comment">becomes "take music red button". The parser will thus have three</span>
<span class="comment">words to work from next time, not two.)</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">k</span><span class="plain"> = </span><span class="identifier">WordAddress</span><span class="plain">(</span><span class="identifier">match_from</span><span class="plain">) - </span><span class="identifier">buffer</span><span class="plain">; </span><span class="identifier">l</span><span class="plain">=</span><span class="identifier">buffer2</span><span class="plain">-&gt;1+1;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=</span><span class="identifier">buffer</span><span class="plain"> + </span><span class="identifier">buffer</span><span class="plain">-&gt;0 - </span><span class="constant">1</span><span class="plain"> : </span><span class="identifier">j</span><span class="plain">&gt;=</span><span class="identifier">buffer</span><span class="plain">+</span><span class="identifier">k</span><span class="plain">+</span><span class="identifier">l</span><span class="plain"> : </span><span class="identifier">j</span><span class="plain">--) </span><span class="identifier">j</span><span class="plain">-&gt;0 = </span><span class="constant">0</span><span class="plain">-&gt;(</span><span class="identifier">j</span><span class="plain">-</span><span class="identifier">l</span><span class="plain">);</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">l</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">buffer</span><span class="plain">-&gt;(</span><span class="identifier">k</span><span class="plain">+</span><span class="identifier">i</span><span class="plain">) = </span><span class="identifier">buffer2</span><span class="plain">-&gt;(2+</span><span class="identifier">i</span><span class="plain">);</span>
<span class="identifier">buffer</span><span class="plain">-&gt;(</span><span class="identifier">k</span><span class="plain">+</span><span class="identifier">l</span><span class="plain">-1) = </span><span class="character">' '</span><span class="plain">;</span>
<span class="identifier">buffer</span><span class="plain">-&gt;1 = </span><span class="identifier">buffer</span><span class="plain">-&gt;1 + </span><span class="identifier">l</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">buffer</span><span class="plain">-&gt;1 &gt;= (</span><span class="identifier">buffer</span><span class="plain">-&gt;0 - </span><span class="constant">1</span><span class="plain">)) </span><span class="identifier">buffer</span><span class="plain">-&gt;1 = </span><span class="identifier">buffer</span><span class="plain">-&gt;0;</span>
<span class="plain">#</span><span class="identifier">Ifnot</span><span class="plain">; </span><span class="comment">TARGET_GLULX</span>
<span class="identifier">k</span><span class="plain"> = </span><span class="identifier">WordAddress</span><span class="plain">(</span><span class="identifier">match_from</span><span class="plain">) - </span><span class="identifier">buffer</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">l</span><span class="plain"> = (</span><span class="identifier">buffer2</span><span class="plain">--&gt;0) + </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=</span><span class="identifier">buffer</span><span class="plain">+</span><span class="identifier">INPUT_BUFFER_LEN</span><span class="plain">-1 : </span><span class="identifier">j</span><span class="plain">&gt;=</span><span class="identifier">buffer</span><span class="plain">+</span><span class="identifier">k</span><span class="plain">+</span><span class="identifier">l</span><span class="plain"> : </span><span class="identifier">j</span><span class="plain">--) </span><span class="identifier">j</span><span class="plain">-&gt;0 = </span><span class="identifier">j</span><span class="plain">-&gt;(-</span><span class="identifier">l</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">l</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">buffer</span><span class="plain">-&gt;(</span><span class="identifier">k</span><span class="plain">+</span><span class="identifier">i</span><span class="plain">) = </span><span class="identifier">buffer2</span><span class="plain">-&gt;(</span><span class="identifier">WORDSIZE</span><span class="plain">+</span><span class="identifier">i</span><span class="plain">);</span>
<span class="identifier">buffer</span><span class="plain">-&gt;(</span><span class="identifier">k</span><span class="plain">+</span><span class="identifier">l</span><span class="plain">-1) = </span><span class="character">' '</span><span class="plain">;</span>
<span class="identifier">buffer</span><span class="plain">--&gt;0 = </span><span class="identifier">buffer</span><span class="plain">--&gt;0 + </span><span class="identifier">l</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">buffer</span><span class="plain">--&gt;0 &gt; (</span><span class="identifier">INPUT_BUFFER_LEN</span><span class="plain">-</span><span class="identifier">WORDSIZE</span><span class="plain">)) </span><span class="identifier">buffer</span><span class="plain">--&gt;0 = (</span><span class="identifier">INPUT_BUFFER_LEN</span><span class="plain">-</span><span class="identifier">WORDSIZE</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">TARGET_</span>
2020-01-13 13:02:57 +02:00
2020-04-07 03:06:09 +03:00
<span class="comment">Having reconstructed the input, we warn the parser accordingly</span>
<span class="comment">and get out.</span>
2020-01-13 13:02:57 +02:00
<span class="plain">.</span><span class="identifier">RECONSTRUCT_INPUT</span><span class="plain">;</span>
<span class="identifier">num_words</span><span class="plain"> = </span><span class="identifier">WordCount</span><span class="plain">(); </span><span class="identifier">players_command</span><span class="plain"> = </span><span class="constant">100</span><span class="plain"> + </span><span class="identifier">num_words</span><span class="plain">;</span>
<span class="identifier">wn</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">LanguageToInformese</span><span class="plain">;</span>
<span class="identifier">LanguageToInformese</span><span class="plain">();</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Re-tokenise:</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">VM_Tokenise</span><span class="plain">(</span><span class="identifier">buffer</span><span class="plain">,</span><span class="identifier">parse</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">LanguageToInformese</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">num_words</span><span class="plain"> = </span><span class="identifier">WordCount</span><span class="plain">(); </span><span class="identifier">players_command</span><span class="plain"> = </span><span class="constant">100</span><span class="plain"> + </span><span class="identifier">num_words</span><span class="plain">;</span>
<span class="identifier">actors_location</span><span class="plain"> = </span><span class="identifier">ScopeCeiling</span><span class="plain">(</span><span class="identifier">player</span><span class="plain">);</span>
<span class="identifier">FollowRulebook</span><span class="plain">(</span><span class="identifier">Activity_after_rulebooks</span><span class="plain">--&gt;</span><span class="identifier">READING_A_COMMAND_ACT</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">REPARSE_CODE</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Now we come to the question asked when the input has run out</span>
<span class="comment">and can't easily be guessed (eg, the player typed "take" and there</span>
<span class="comment">were plenty of things which might have been meant).</span>
2020-01-13 13:02:57 +02:00
2020-04-08 01:02:44 +03:00
<span class="plain"> .</span><span class="identifier">Incomplete</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">context</span><span class="plain"> == </span><span class="identifier">CREATURE_TOKEN</span><span class="plain">) </span><span class="identifier">PARSER_CLARIF_INTERNAL_RM</span><span class="plain">(</span><span class="character">'D'</span><span class="plain">, </span><span class="identifier">actor</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">PARSER_CLARIF_INTERNAL_RM</span><span class="plain">(</span><span class="character">'E'</span><span class="plain">, </span><span class="identifier">actor</span><span class="plain">);</span>
<span class="reserved">new_line</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=2 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">INPUT_BUFFER_LEN</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">buffer2</span><span class="plain">-&gt;</span><span class="identifier">i</span><span class="plain">=</span><span class="character">' '</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">TARGET_ZCODE</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">answer_words</span><span class="plain"> = </span><span class="identifier">Keyboard</span><span class="plain">(</span><span class="identifier">buffer2</span><span class="plain">, </span><span class="identifier">parse2</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Look for a comma, and interpret this as a fresh conversation command</span>
<span class="comment">if so:</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=1 : </span><span class="identifier">i</span><span class="plain">&lt;=</span><span class="identifier">answer_words</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">WordFrom</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">parse2</span><span class="plain">) == </span><span class="identifier">comma_word</span><span class="plain">) {</span>
<span class="identifier">VM_CopyBuffer</span><span class="plain">(</span><span class="identifier">buffer</span><span class="plain">, </span><span class="identifier">buffer2</span><span class="plain">);</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">RECONSTRUCT_INPUT</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">first_word</span><span class="plain">=(</span><span class="identifier">parse2</span><span class="plain">--&gt;1);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">first_word</span><span class="plain">==0) {</span>
<span class="identifier">j</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">; </span><span class="identifier">first_word</span><span class="plain">=</span><span class="identifier">LanguageIsVerb</span><span class="plain">(</span><span class="identifier">buffer2</span><span class="plain">, </span><span class="identifier">parse2</span><span class="plain">, </span><span class="constant">1</span><span class="plain">); </span><span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">j</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Once again, if the reply looks like a command, give it to the</span>
<span class="comment">parser to get on with and forget about the question...</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">first_word</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">j</span><span class="plain"> = </span><span class="identifier">first_word</span><span class="plain">-&gt;#</span><span class="identifier">dict_par1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((0 ~= </span><span class="identifier">j</span><span class="plain">&amp;1) &amp;&amp; ~~</span><span class="identifier">LanguageVerbMayBeName</span><span class="plain">(</span><span class="identifier">first_word</span><span class="plain">)) {</span>
<span class="identifier">VM_CopyBuffer</span><span class="plain">(</span><span class="identifier">buffer</span><span class="plain">, </span><span class="identifier">buffer2</span><span class="plain">);</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">RECONSTRUCT_INPUT</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">...but if we have a genuine answer, then:</span>
<span class="comment">(1) we must glue in text suitable for anything that's been inferred.</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inferfrom</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) {</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=</span><span class="identifier">inferfrom</span><span class="plain"> : </span><span class="identifier">j</span><span class="plain">&lt;</span><span class="identifier">pcount</span><span class="plain"> : </span><span class="identifier">j</span><span class="plain">++) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pattern</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain"> == </span><span class="identifier">PATTERN_NULL</span><span class="plain">) </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="constant">2</span><span class="plain">+</span><span class="identifier">buffer</span><span class="plain">-&gt;1; (</span><span class="identifier">buffer</span><span class="plain">-&gt;1)++; </span><span class="identifier">buffer</span><span class="plain">-&gt;(</span><span class="identifier">i</span><span class="plain">++) = </span><span class="character">' '</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Ifnot</span><span class="plain">; </span><span class="comment">TARGET_GLULX</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">WORDSIZE</span><span class="plain"> + </span><span class="identifier">buffer</span><span class="plain">--&gt;0;</span>
<span class="plain">(</span><span class="identifier">buffer</span><span class="plain">--&gt;0)++; </span><span class="identifier">buffer</span><span class="plain">-&gt;(</span><span class="identifier">i</span><span class="plain">++) = </span><span class="character">' '</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">TARGET_</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">5</span><span class="plain">)</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"[Gluing in inference with pattern code "</span><span class="plain">, </span><span class="identifier">pattern</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain">, </span><span class="string">"]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
2020-04-07 03:06:09 +03:00
<span class="comment">Conveniently, parse2--&gt;1 is the first word in both ZCODE and GLULX.</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">parse2</span><span class="plain">--&gt;1 = </span><span class="constant">0</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">An inferred object. Best we can do is glue in a pronoun.</span>
<span class="comment">(This is imperfect, but it's very seldom needed anyway.)</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pattern</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain"> &gt;= </span><span class="constant">2</span><span class="plain"> &amp;&amp; </span><span class="identifier">pattern</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain"> &lt; </span><span class="identifier">REPARSE_CODE</span><span class="plain">) {</span>
<span class="identifier">PronounNotice</span><span class="plain">(</span><span class="identifier">pattern</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">k</span><span class="plain">=1 : </span><span class="identifier">k</span><span class="plain">&lt;=</span><span class="identifier">LanguagePronouns</span><span class="plain">--&gt;0 : </span><span class="identifier">k</span><span class="plain">=</span><span class="identifier">k</span><span class="plain">+3)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pattern</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain"> == </span><span class="identifier">LanguagePronouns</span><span class="plain">--&gt;(</span><span class="identifier">k</span><span class="plain">+2)) {</span>
<span class="identifier">parse2</span><span class="plain">--&gt;1 = </span><span class="identifier">LanguagePronouns</span><span class="plain">--&gt;</span><span class="identifier">k</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">5</span><span class="plain">)</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"[Using pronoun '"</span><span class="plain">, (</span><span class="identifier">address</span><span class="plain">) </span><span class="identifier">parse2</span><span class="plain">--&gt;1, </span><span class="string">"']^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">else</span><span class="plain"> {</span>
2020-04-07 03:06:09 +03:00
<span class="comment">An inferred preposition.</span>
<span class="identifier">parse2</span><span class="plain">--&gt;1 = </span><span class="identifier">VM_NumberToDictionaryAddress</span><span class="plain">(</span><span class="identifier">pattern</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain"> - </span><span class="identifier">REPARSE_CODE</span><span class="plain">);</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">5</span><span class="plain">)</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"[Using preposition '"</span><span class="plain">, (</span><span class="identifier">address</span><span class="plain">) </span><span class="identifier">parse2</span><span class="plain">--&gt;1, </span><span class="string">"']^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">parse2--&gt;1 now holds the dictionary address of the word to glue in.</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parse2</span><span class="plain">--&gt;1 ~= </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">k</span><span class="plain"> = </span><span class="identifier">buffer</span><span class="plain"> + </span><span class="identifier">i</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="plain">@</span><span class="identifier">output_stream</span><span class="plain"> </span><span class="constant">3</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="reserved">print</span><span class="plain"> (</span><span class="identifier">address</span><span class="plain">) </span><span class="identifier">parse2</span><span class="plain">--&gt;1;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">@</span><span class="identifier">output_stream</span><span class="plain"> -3;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">k</span><span class="plain"> = </span><span class="identifier">k</span><span class="plain">--&gt;0;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain">=</span><span class="identifier">i</span><span class="plain"> : </span><span class="identifier">l</span><span class="plain">&lt;</span><span class="identifier">i</span><span class="plain">+</span><span class="identifier">k</span><span class="plain"> : </span><span class="identifier">l</span><span class="plain">++) </span><span class="identifier">buffer</span><span class="plain">-&gt;</span><span class="identifier">l</span><span class="plain"> = </span><span class="identifier">buffer</span><span class="plain">-&gt;(</span><span class="identifier">l</span><span class="plain">+2);</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain"> + </span><span class="identifier">k</span><span class="plain">; </span><span class="identifier">buffer</span><span class="plain">-&gt;1 = </span><span class="identifier">i</span><span class="plain">-2;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Ifnot</span><span class="plain">; </span><span class="comment">TARGET_GLULX</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">k</span><span class="plain"> = </span><span class="identifier">Glulx_PrintAnyToArray</span><span class="plain">(</span><span class="identifier">buffer</span><span class="plain">+</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">INPUT_BUFFER_LEN</span><span class="plain">-</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">parse2</span><span class="plain">--&gt;1);</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain"> + </span><span class="identifier">k</span><span class="plain">; </span><span class="identifier">buffer</span><span class="plain">--&gt;0 = </span><span class="identifier">i</span><span class="plain"> - </span><span class="identifier">WORDSIZE</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">TARGET_</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">(2) we must glue the newly-typed text onto the end.</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="constant">2</span><span class="plain">+</span><span class="identifier">buffer</span><span class="plain">-&gt;1; (</span><span class="identifier">buffer</span><span class="plain">-&gt;1)++; </span><span class="identifier">buffer</span><span class="plain">-&gt;(</span><span class="identifier">i</span><span class="plain">++) = </span><span class="character">' '</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0 : </span><span class="identifier">j</span><span class="plain">&lt;</span><span class="identifier">buffer2</span><span class="plain">-&gt;1 : </span><span class="identifier">i</span><span class="plain">++,</span><span class="identifier">j</span><span class="plain">++) {</span>
<span class="identifier">buffer</span><span class="plain">-&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">buffer2</span><span class="plain">-&gt;(</span><span class="identifier">j</span><span class="plain">+2);</span>
<span class="plain">(</span><span class="identifier">buffer</span><span class="plain">-&gt;1)++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">buffer</span><span class="plain">-&gt;1 == </span><span class="identifier">INPUT_BUFFER_LEN</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Ifnot</span><span class="plain">; </span><span class="comment">TARGET_GLULX</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">WORDSIZE</span><span class="plain"> + </span><span class="identifier">buffer</span><span class="plain">--&gt;0;</span>
<span class="plain">(</span><span class="identifier">buffer</span><span class="plain">--&gt;0)++; </span><span class="identifier">buffer</span><span class="plain">-&gt;(</span><span class="identifier">i</span><span class="plain">++) = </span><span class="character">' '</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0 : </span><span class="identifier">j</span><span class="plain">&lt;</span><span class="identifier">buffer2</span><span class="plain">--&gt;0 : </span><span class="identifier">i</span><span class="plain">++,</span><span class="identifier">j</span><span class="plain">++) {</span>
<span class="identifier">buffer</span><span class="plain">-&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">buffer2</span><span class="plain">-&gt;(</span><span class="identifier">j</span><span class="plain">+</span><span class="identifier">WORDSIZE</span><span class="plain">);</span>
<span class="plain">(</span><span class="identifier">buffer</span><span class="plain">--&gt;0)++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">buffer</span><span class="plain">--&gt;0 == </span><span class="identifier">INPUT_BUFFER_LEN</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">TARGET_</span>
2020-04-07 03:06:09 +03:00
<span class="comment">(3) we fill up the buffer with spaces, which is unnecessary, but may</span>
2020-04-14 19:56:54 +03:00
<span class="comment"> help incorrectly-written interpreters to cope.</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (: </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">INPUT_BUFFER_LEN</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">buffer</span><span class="plain">-&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="character">' '</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">TARGET_ZCODE</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">RECONSTRUCT_INPUT</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">]; </span><span class="comment">end of NounDomain</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">PARSER_CLARIF_INTERNAL_R</span><span class="plain">; ];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP35"></a><b>&#167;35. Adjudicate. </b>The <code class="display"><span class="extract">Adjudicate</span></code> routine tries to see if there is an obvious choice, when
faced with a list of objects (the <code class="display"><span class="extract">match_list</span></code>) each of which matches the
player's specification equally well. To do this it makes use of the <code class="display"><span class="extract">context</span></code>
(the token type being worked on).
</p>
<p class="inwebparagraph">It counts up the number of obvious choices for the given context &mdash; all to
do with where a candidate is, except for 6 (<code class="display"><span class="extract">animate</span></code>) which is to
do with whether it is animate or not &mdash; and then:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) if only one obvious choice is found, that is returned;
</li><li>(b) if we are in indefinite mode (don't care which) one of the obvious choices
is returned, or if there is no obvious choice then an unobvious one is made;
</li><li>(c) at this stage, we work out whether the objects are distinguishable from
each other or not: if they are all indistinguishable from each other, then
choose one, it doesn't matter which;
</li><li>(d) otherwise, 0 (meaning, unable to decide) is returned (but remember
that the equivalence classes we've just worked out will be needed by other
routines to clear up this mess, so we can't economise on working them out).
</li></ul>
2020-04-14 19:56:54 +03:00
<p class="inwebparagraph"><code class="display"><span class="extract">Adjudicate</span></code> returns \(-1\) if an error occurred.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">Adjudicate</span><span class="plain"> </span><span class="identifier">context</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">j</span><span class="plain"> </span><span class="identifier">k</span><span class="plain"> </span><span class="identifier">good_ones</span><span class="plain"> </span><span class="identifier">last</span><span class="plain"> </span><span class="identifier">n</span><span class="plain"> </span><span class="identifier">ultimate</span><span class="plain"> </span><span class="identifier">flag</span><span class="plain"> </span><span class="identifier">offset</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">4</span><span class="plain">) {</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" [Adjudicating match list of size "</span><span class="plain">, </span><span class="identifier">number_matched</span><span class="plain">,</span>
<span class="string">" in context "</span><span class="plain">, </span><span class="identifier">context</span><span class="plain">, </span><span class="string">"^"</span><span class="plain">;</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_mode</span><span class="plain">) {</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"indefinite type: "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">OTHER_BIT</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"other "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">MY_BIT</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"my "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">THAT_BIT</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"that "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">PLURAL_BIT</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"plural "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">LIT_BIT</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"lit "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">UNLIT_BIT</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"unlit "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_owner</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"owner:"</span><span class="plain">, (</span><span class="identifier">name</span><span class="plain">) </span><span class="identifier">indef_owner</span><span class="plain">;</span>
<span class="reserved">new_line</span><span class="plain">;</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" number wanted: "</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_wanted</span><span class="plain"> == </span><span class="identifier">INDEF_ALL_WANTED</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"all"</span><span class="plain">; </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">print</span><span class="plain"> </span><span class="identifier">indef_wanted</span><span class="plain">;</span>
<span class="reserved">new_line</span><span class="plain">;</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" most likely GNAs of names: "</span><span class="plain">, </span><span class="identifier">indef_cases</span><span class="plain">, </span><span class="string">"^"</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"definite object^"</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">j</span><span class="plain"> = </span><span class="identifier">number_matched</span><span class="plain">-1; </span><span class="identifier">good_ones</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">last</span><span class="plain"> = </span><span class="identifier">match_list</span><span class="plain">--&gt;0;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;=</span><span class="identifier">j</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">n</span><span class="plain"> = </span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">;</span>
<span class="identifier">match_scores</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">good_ones</span><span class="plain">;</span>
<span class="identifier">ultimate</span><span class="plain"> = </span><span class="identifier">ScopeCeiling</span><span class="plain">(</span><span class="identifier">n</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">context</span><span class="plain">==</span><span class="identifier">HELD_TOKEN</span><span class="plain"> &amp;&amp; </span><span class="reserved">parent</span><span class="plain">(</span><span class="identifier">n</span><span class="plain">)==</span><span class="identifier">actor</span><span class="plain">)</span>
<span class="plain">{ </span><span class="identifier">good_ones</span><span class="plain">++; </span><span class="identifier">last</span><span class="plain">=</span><span class="identifier">n</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">context</span><span class="plain">==</span><span class="identifier">MULTI_TOKEN</span><span class="plain"> &amp;&amp; </span><span class="identifier">ultimate</span><span class="plain">==</span><span class="identifier">ScopeCeiling</span><span class="plain">(</span><span class="identifier">actor</span><span class="plain">)</span>
<span class="plain">&amp;&amp; </span><span class="identifier">n</span><span class="plain">~=</span><span class="identifier">actor</span><span class="plain"> &amp;&amp; </span><span class="identifier">n</span><span class="plain"> </span><span class="reserved">hasnt</span><span class="plain"> </span><span class="identifier">concealed</span><span class="plain"> &amp;&amp; </span><span class="identifier">n</span><span class="plain"> </span><span class="reserved">hasnt</span><span class="plain"> </span><span class="identifier">scenery</span><span class="plain">)</span>
<span class="plain">{ </span><span class="identifier">good_ones</span><span class="plain">++; </span><span class="identifier">last</span><span class="plain">=</span><span class="identifier">n</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">context</span><span class="plain">==</span><span class="identifier">MULTIHELD_TOKEN</span><span class="plain"> &amp;&amp; </span><span class="reserved">parent</span><span class="plain">(</span><span class="identifier">n</span><span class="plain">)==</span><span class="identifier">actor</span><span class="plain">)</span>
<span class="plain">{ </span><span class="identifier">good_ones</span><span class="plain">++; </span><span class="identifier">last</span><span class="plain">=</span><span class="identifier">n</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">context</span><span class="plain">==</span><span class="identifier">MULTIEXCEPT_TOKEN</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">MULTIINSIDE_TOKEN</span><span class="plain">)</span>
<span class="plain">{ </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">advance_warning</span><span class="plain">==-1)</span>
<span class="plain">{ </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">context</span><span class="plain">==</span><span class="identifier">MULTIEXCEPT_TOKEN</span><span class="plain">)</span>
<span class="plain">{ </span><span class="identifier">good_ones</span><span class="plain">++; </span><span class="identifier">last</span><span class="plain">=</span><span class="identifier">n</span><span class="plain">;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> }</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">context</span><span class="plain">==</span><span class="identifier">MULTIINSIDE_TOKEN</span><span class="plain">)</span>
<span class="plain">{ </span><span class="reserved">if</span><span class="plain"> (</span><span class="reserved">parent</span><span class="plain">(</span><span class="identifier">n</span><span class="plain">)~=</span><span class="identifier">actor</span><span class="plain">) { </span><span class="identifier">good_ones</span><span class="plain">++; </span><span class="identifier">last</span><span class="plain">=</span><span class="identifier">n</span><span class="plain">; }</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> }</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">else</span>
<span class="plain">{ </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">context</span><span class="plain">==</span><span class="identifier">MULTIEXCEPT_TOKEN</span><span class="plain"> &amp;&amp; </span><span class="identifier">n</span><span class="plain">~=</span><span class="identifier">advance_warning</span><span class="plain">)</span>
<span class="plain">{ </span><span class="identifier">good_ones</span><span class="plain">++; </span><span class="identifier">last</span><span class="plain">=</span><span class="identifier">n</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">context</span><span class="plain">==</span><span class="identifier">MULTIINSIDE_TOKEN</span><span class="plain"> &amp;&amp; </span><span class="identifier">n</span><span class="plain"> </span><span class="reserved">in</span><span class="plain"> </span><span class="identifier">advance_warning</span><span class="plain">)</span>
<span class="plain">{ </span><span class="identifier">good_ones</span><span class="plain">++; </span><span class="identifier">last</span><span class="plain">=</span><span class="identifier">n</span><span class="plain">; }</span>
<span class="plain">}</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> }</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">context</span><span class="plain">==</span><span class="identifier">CREATURE_TOKEN</span><span class="plain"> &amp;&amp; </span><span class="identifier">CreatureTest</span><span class="plain">(</span><span class="identifier">n</span><span class="plain">)==1)</span>
<span class="plain">{ </span><span class="identifier">good_ones</span><span class="plain">++; </span><span class="identifier">last</span><span class="plain">=</span><span class="identifier">n</span><span class="plain">; }</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">match_scores</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="constant">1000</span><span class="plain">*(</span><span class="identifier">good_ones</span><span class="plain"> - </span><span class="identifier">match_scores</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">good_ones</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_mode</span><span class="plain"> == </span><span class="constant">1</span><span class="plain"> &amp;&amp; </span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">PLURAL_BIT</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain"> &amp;&amp;</span>
<span class="identifier">context</span><span class="plain"> == </span><span class="identifier">MULTI_TOKEN</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">MULTIHELD_TOKEN</span><span class="plain"> </span><span class="reserved">or</span>
<span class="identifier">MULTIEXCEPT_TOKEN</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">MULTIINSIDE_TOKEN</span><span class="plain">) {</span>
<span class="identifier">BeginActivity</span><span class="plain">(</span><span class="identifier">DECIDING_WHETHER_ALL_INC_ACT</span><span class="plain">, </span><span class="identifier">last</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ForActivity</span><span class="plain">(</span><span class="identifier">DECIDING_WHETHER_ALL_INC_ACT</span><span class="plain">, </span><span class="identifier">last</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">RulebookFailed</span><span class="plain">())) </span><span class="identifier">good_ones</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">EndActivity</span><span class="plain">(</span><span class="identifier">DECIDING_WHETHER_ALL_INC_ACT</span><span class="plain">, </span><span class="identifier">last</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">good_ones</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">last</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">last</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">If there is ambiguity about what was typed, but it definitely wasn't</span>
<span class="comment">animate as required, then return anything; higher up in the parser</span>
<span class="comment">a suitable error will be given. (This prevents a question being asked.)</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">context</span><span class="plain"> == </span><span class="identifier">CREATURE_TOKEN</span><span class="plain"> &amp;&amp; </span><span class="identifier">good_ones</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">match_list</span><span class="plain">--&gt;0;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_mode</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">indef_type</span><span class="plain">=0;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">ScoreMatchL</span><span class="plain">(</span><span class="identifier">context</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">number_matched</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> -1;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_mode</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) {</span>
2020-04-14 19:56:54 +03:00
<span class="comment"> Is there now a single highest-scoring object?</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">SingleBestGuess</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) {</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">4</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" Single best-scoring object returned.]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_mode</span><span class="plain"> == </span><span class="constant">1</span><span class="plain"> &amp;&amp; </span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">PLURAL_BIT</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">context</span><span class="plain"> ~= </span><span class="identifier">MULTI_TOKEN</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">MULTIHELD_TOKEN</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">MULTIEXCEPT_TOKEN</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">MULTIINSIDE_TOKEN</span><span class="plain">) {</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">etype</span><span class="plain"> = </span><span class="identifier">MULTI_PE</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">return</span><span class="plain"> -1;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">i</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">offset</span><span class="plain"> = </span><span class="identifier">multiple_object</span><span class="plain">--&gt;0;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=</span><span class="identifier">BestGuess</span><span class="plain">(): </span><span class="identifier">j</span><span class="plain">~=-1 &amp;&amp; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">indef_wanted</span><span class="plain"> &amp;&amp; </span><span class="identifier">i</span><span class="plain">+</span><span class="identifier">offset</span><span class="plain">&lt;</span><span class="identifier">MATCH_LIST_WORDS</span><span class="plain">-1:</span>
<span class="identifier">j</span><span class="plain">=</span><span class="identifier">BestGuess</span><span class="plain">()) {</span>
<span class="identifier">flag</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">BeginActivity</span><span class="plain">(</span><span class="identifier">DECIDING_WHETHER_ALL_INC_ACT</span><span class="plain">, </span><span class="identifier">j</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ForActivity</span><span class="plain">(</span><span class="identifier">DECIDING_WHETHER_ALL_INC_ACT</span><span class="plain">, </span><span class="identifier">j</span><span class="plain">)) == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain"> </span><span class="reserved">hasnt</span><span class="plain"> </span><span class="identifier">concealed</span><span class="plain"> &amp;&amp; </span><span class="identifier">j</span><span class="plain"> </span><span class="reserved">hasnt</span><span class="plain"> </span><span class="identifier">worn</span><span class="plain">) </span><span class="identifier">flag</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">context</span><span class="plain"> == </span><span class="identifier">MULTIHELD_TOKEN</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">MULTIEXCEPT_TOKEN</span><span class="plain"> &amp;&amp; </span><span class="reserved">parent</span><span class="plain">(</span><span class="identifier">j</span><span class="plain">) ~= </span><span class="identifier">actor</span><span class="plain">)</span>
<span class="identifier">flag</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">action_to_be</span><span class="plain"> == ##</span><span class="identifier">Take</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> ##</span><span class="identifier">Remove</span><span class="plain"> &amp;&amp; </span><span class="reserved">parent</span><span class="plain">(</span><span class="identifier">j</span><span class="plain">) == </span><span class="identifier">actor</span><span class="plain">)</span>
<span class="identifier">flag</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">k</span><span class="plain"> = </span><span class="identifier">ChooseObjects</span><span class="plain">(</span><span class="identifier">j</span><span class="plain">, </span><span class="identifier">flag</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">k</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">)</span>
<span class="identifier">flag</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">k</span><span class="plain"> == </span><span class="constant">2</span><span class="plain">) </span><span class="identifier">flag</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">flag</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">RulebookSucceeded</span><span class="plain">()) </span><span class="identifier">flag</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">EndActivity</span><span class="plain">(</span><span class="identifier">DECIDING_WHETHER_ALL_INC_ACT</span><span class="plain">, </span><span class="identifier">j</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">flag</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) {</span>
<span class="identifier">i</span><span class="plain">++; </span><span class="identifier">multiple_object</span><span class="plain">--&gt;(</span><span class="identifier">i</span><span class="plain">+</span><span class="identifier">offset</span><span class="plain">) = </span><span class="identifier">j</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">4</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" Accepting it^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">4</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" Rejecting it^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> &lt; </span><span class="identifier">indef_wanted</span><span class="plain"> &amp;&amp; </span><span class="identifier">indef_wanted</span><span class="plain"> &lt; </span><span class="identifier">INDEF_ALL_WANTED</span><span class="plain">) {</span>
<span class="identifier">etype</span><span class="plain"> = </span><span class="identifier">TOOFEW_PE</span><span class="plain">; </span><span class="identifier">multi_wanted</span><span class="plain"> = </span><span class="identifier">indef_wanted</span><span class="plain">;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">4</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"Too few found^"</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">multi_had</span><span class="plain">=</span><span class="identifier">i</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">return</span><span class="plain"> -1;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">multiple_object</span><span class="plain">--&gt;0 = </span><span class="identifier">i</span><span class="plain">+</span><span class="identifier">offset</span><span class="plain">;</span>
<span class="identifier">multi_context</span><span class="plain"> = </span><span class="identifier">context</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">4</span><span class="plain">)</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" Made multiple object of size "</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="string">"]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="constant">1</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">number_matched</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">match_classes</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">n</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">number_matched</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">match_classes</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">match_classes</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">n</span><span class="plain">++; </span><span class="identifier">flag</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=</span><span class="identifier">i</span><span class="plain">+1 : </span><span class="identifier">j</span><span class="plain">&lt;</span><span class="identifier">number_matched</span><span class="plain"> : </span><span class="identifier">j</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">match_classes</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain"> == </span><span class="constant">0</span><span class="plain"> &amp;&amp; </span><span class="identifier">Identical</span><span class="plain">(</span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain">) == </span><span class="constant">1</span><span class="plain">) {</span>
<span class="identifier">flag</span><span class="plain">=1;</span>
<span class="identifier">match_classes</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain"> = </span><span class="identifier">match_classes</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">flag</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) </span><span class="identifier">match_classes</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">-</span><span class="identifier">n</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="identifier">n</span><span class="plain">--; </span><span class="identifier">number_of_classes</span><span class="plain"> = </span><span class="identifier">n</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">4</span><span class="plain">) {</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" Grouped into "</span><span class="plain">, </span><span class="identifier">n</span><span class="plain">, </span><span class="string">" possibilities by name:^"</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">number_matched</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">match_classes</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">)</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" "</span><span class="plain">, (</span><span class="identifier">The</span><span class="plain">) </span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">, </span><span class="string">" ("</span><span class="plain">, </span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">, </span><span class="string">") --- group "</span><span class="plain">,</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="identifier">match_classes</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">, </span><span class="string">"^"</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_mode</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">n</span><span class="plain"> &gt; </span><span class="constant">1</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">k</span><span class="plain"> = -1;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">number_matched</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">match_scores</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> &gt; </span><span class="identifier">k</span><span class="plain">) {</span>
<span class="identifier">k</span><span class="plain"> = </span><span class="identifier">match_scores</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">;</span>
<span class="identifier">j</span><span class="plain"> = </span><span class="identifier">match_classes</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">; </span><span class="identifier">j</span><span class="plain"> = </span><span class="identifier">j</span><span class="plain">*</span><span class="identifier">j</span><span class="plain">;</span>
<span class="identifier">flag</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">else</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">match_scores</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> == </span><span class="identifier">k</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">match_classes</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">) * (</span><span class="identifier">match_classes</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">) ~= </span><span class="identifier">j</span><span class="plain">)</span>
<span class="identifier">flag</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">flag</span><span class="plain">) {</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">4</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" Unable to choose best group, so ask player.]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">4</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" Best choices are all from the same group.^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-04-14 19:56:54 +03:00
<span class="comment"> When the player is really vague, or there's a single collection of</span>
<span class="comment"> indistinguishable objects to choose from, choose the one the player</span>
<span class="comment"> most recently acquired, or if the player has none of them, then</span>
<span class="comment"> the one most recently put where it is.</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">n</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) </span><span class="identifier">dont_infer</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">BestGuess</span><span class="plain">();</span>
2020-04-07 03:06:09 +03:00
<span class="plain">]; </span><span class="comment">Adjudicate</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP36"></a><b>&#167;36. ReviseMulti. </b><code class="display"><span class="extract">ReviseMulti</span></code> revises the multiple object which already exists, in the
light of information which has come along since then (i.e., the second
parameter). It returns a parser error number, or else 0 if all is well.
This only ever throws things out, never adds new ones.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">ReviseMulti</span><span class="plain"> </span><span class="identifier">second_p</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">low</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">4</span><span class="plain">)</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" Revising multiple object list of size "</span><span class="plain">, </span><span class="identifier">multiple_object</span><span class="plain">--&gt;0,</span>
<span class="string">" with 2nd "</span><span class="plain">, (</span><span class="identifier">name</span><span class="plain">) </span><span class="identifier">second_p</span><span class="plain">, </span><span class="string">"^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">multi_context</span><span class="plain"> == </span><span class="identifier">MULTIEXCEPT_TOKEN</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">MULTIINSIDE_TOKEN</span><span class="plain">) {</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=1,</span><span class="identifier">low</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;=</span><span class="identifier">multiple_object</span><span class="plain">--&gt;0 : </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="reserved">if</span><span class="plain"> ( (</span><span class="identifier">multi_context</span><span class="plain">==</span><span class="identifier">MULTIEXCEPT_TOKEN</span><span class="plain"> &amp;&amp; </span><span class="identifier">multiple_object</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> ~= </span><span class="identifier">second_p</span><span class="plain">) ||</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> (</span><span class="identifier">multi_context</span><span class="plain">==</span><span class="identifier">MULTIINSIDE_TOKEN</span><span class="plain"> &amp;&amp; </span><span class="identifier">multiple_object</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> </span><span class="reserved">in</span><span class="plain"> </span><span class="identifier">second_p</span><span class="plain">)) {</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">low</span><span class="plain">++;</span>
<span class="identifier">multiple_object</span><span class="plain">--&gt;</span><span class="identifier">low</span><span class="plain"> = </span><span class="identifier">multiple_object</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">multiple_object</span><span class="plain">--&gt;0 = </span><span class="identifier">low</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">multi_context</span><span class="plain"> == </span><span class="identifier">MULTI_TOKEN</span><span class="plain"> &amp;&amp; </span><span class="identifier">action_to_be</span><span class="plain"> == ##</span><span class="identifier">Take</span><span class="plain">) {</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">4</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" Token 2 plural case: number with actor "</span><span class="plain">, </span><span class="identifier">low</span><span class="plain">, </span><span class="string">"^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">take_all_rule</span><span class="plain"> == </span><span class="constant">2</span><span class="plain">) {</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=1,</span><span class="identifier">low</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;=</span><span class="identifier">multiple_object</span><span class="plain">--&gt;0 : </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ScopeCeiling</span><span class="plain">(</span><span class="identifier">multiple_object</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">ScopeCeiling</span><span class="plain">(</span><span class="identifier">actor</span><span class="plain">)) {</span>
<span class="identifier">low</span><span class="plain">++;</span>
<span class="identifier">multiple_object</span><span class="plain">--&gt;</span><span class="identifier">low</span><span class="plain"> = </span><span class="identifier">multiple_object</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">multiple_object</span><span class="plain">--&gt;0 = </span><span class="identifier">low</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">multiple_object</span><span class="plain">--&gt;0;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">4</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" Done: new size "</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="string">"^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NOTHING_PE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP37"></a><b>&#167;37. Match List. </b>The match list is an array, <code class="display"><span class="extract">match_list--&gt;</span></code>, which holds the current best
guesses at what object(s) a portion of the command refers to. The global
<code class="display"><span class="extract">number_matched</span></code> is set to the current length of the <code class="display"><span class="extract">match_list</span></code>.
</p>
<p class="inwebparagraph">When the parser sees a possible match of object <code class="display"><span class="extract">obj</span></code> at quality level <code class="display"><span class="extract">q</span></code>,
it calls <code class="display"><span class="extract">MakeMatch(obj, q)</span></code>. If this is the best quality match so far, then
we wipe out all the previous matches and start a new list with this one.
If it's only as good as the best so far, we add it to the list (provided
we haven't run out of space, and provided it isn't in the list already).
If it's worse, we ignore it altogether.
</p>
<p class="inwebparagraph">I6 tokens in the form <code class="display"><span class="extract">noun=Filter</span></code> or <code class="display"><span class="extract">Attribute</span></code> are "noun filter tokens",
and mean that the match list should be filtered to accept only nouns which
are acceptable to the given routine, or have the given attribute. Such a
token is in force if <code class="display"><span class="extract">token_filter</span></code> is used. (I7 makes no use of this in the
attribute case, which is deprecated nowadays.)
</p>
<p class="inwebparagraph">Quality is essentially the number of words in the command referring to
the object: the idea is that "red panic button" is better than "red button"
or "panic".
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">MakeMatch</span><span class="plain"> </span><span class="identifier">obj</span><span class="plain"> </span><span class="identifier">quality</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">6</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" Match with quality "</span><span class="plain">,</span><span class="identifier">quality</span><span class="plain">,</span><span class="string">"^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">token_filter</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain"> &amp;&amp; </span><span class="identifier">ConsultNounFilterToken</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">6</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" Match filtered out: token filter "</span><span class="plain">, </span><span class="identifier">token_filter</span><span class="plain">, </span><span class="string">"^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">rtrue</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">quality</span><span class="plain"> &lt; </span><span class="identifier">match_length</span><span class="plain">) </span><span class="reserved">rtrue</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">quality</span><span class="plain"> &gt; </span><span class="identifier">match_length</span><span class="plain">) { </span><span class="identifier">match_length</span><span class="plain"> = </span><span class="identifier">quality</span><span class="plain">; </span><span class="identifier">number_matched</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; }</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">number_matched</span><span class="plain"> &gt;= </span><span class="identifier">MATCH_LIST_WORDS</span><span class="plain">) </span><span class="reserved">rtrue</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">number_matched</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> == </span><span class="identifier">obj</span><span class="plain">) </span><span class="reserved">rtrue</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">number_matched</span><span class="plain">++ = </span><span class="identifier">obj</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">6</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" Match added to list^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">ConsultNounFilterToken</span><span class="plain"> </span><span class="identifier">obj</span><span class="plain"> </span><span class="identifier">sn</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">token_filter</span><span class="plain"> </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">Routine</span><span class="plain">) {</span>
<span class="identifier">sn</span><span class="plain"> = </span><span class="identifier">noun</span><span class="plain">;</span>
<span class="identifier">noun</span><span class="plain"> = </span><span class="identifier">obj</span><span class="plain">;</span>
<span class="identifier">rv</span><span class="plain"> = </span><span class="reserved">indirect</span><span class="plain">(</span><span class="identifier">token_filter</span><span class="plain">);</span>
<span class="identifier">noun</span><span class="plain"> = </span><span class="identifier">sn</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> (</span><span class="identifier">token_filter</span><span class="plain">-1)) </span><span class="reserved">rtrue</span><span class="plain">;</span>
<span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP38"></a><b>&#167;38. ScoreMatchL. </b><code class="display"><span class="extract">ScoreMatchL</span></code> scores the match list for quality in terms of what the player
has vaguely asked for. Points are awarded for conforming with requirements
like "my", and so on. Remove from the match list any entries which fail
the basic requirements of the descriptors. (The scoring system used to
evaluate the possibilities is discussed in detail in the DM4.)
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">SCORE__CHOOSEOBJ</span><span class="plain"> = </span><span class="constant">1000</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">SCORE__IFGOOD</span><span class="plain"> = </span><span class="constant">500</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">SCORE__UNCONCEALED</span><span class="plain"> = </span><span class="constant">100</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">SCORE__BESTLOC</span><span class="plain"> = </span><span class="constant">60</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">SCORE__NEXTBESTLOC</span><span class="plain"> = </span><span class="constant">40</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">SCORE__NOTCOMPASS</span><span class="plain"> = </span><span class="constant">20</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">SCORE__NOTSCENERY</span><span class="plain"> = </span><span class="constant">10</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">SCORE__NOTACTOR</span><span class="plain"> = </span><span class="constant">5</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">SCORE__GNA</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">SCORE__DIVISOR</span><span class="plain"> = </span><span class="constant">20</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">PREFER_HELD</span><span class="plain">;</span>
<span class="plain">[ </span><span class="identifier">ScoreMatchL</span><span class="plain"> </span><span class="identifier">context</span><span class="plain"> </span><span class="identifier">its_owner</span><span class="plain"> </span><span class="identifier">its_score</span><span class="plain"> </span><span class="identifier">obj</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">j</span><span class="plain"> </span><span class="identifier">threshold</span><span class="plain"> </span><span class="identifier">met</span><span class="plain"> </span><span class="identifier">a_s</span><span class="plain"> </span><span class="identifier">l_s</span><span class="plain">;</span>
2020-04-14 19:56:54 +03:00
<span class="comment"> if (indef_type &amp; OTHER_BIT ~= 0) threshold++;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">MY_BIT</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">threshold</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">THAT_BIT</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">threshold</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">LIT_BIT</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">threshold</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">UNLIT_BIT</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">threshold</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_owner</span><span class="plain"> ~= </span><span class="reserved">nothing</span><span class="plain">) </span><span class="identifier">threshold</span><span class="plain">++;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">4</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" Scoring match list: indef mode "</span><span class="plain">, </span><span class="identifier">indef_mode</span><span class="plain">, </span><span class="string">" type "</span><span class="plain">,</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="identifier">indef_type</span><span class="plain">, </span><span class="string">", satisfying "</span><span class="plain">, </span><span class="identifier">threshold</span><span class="plain">, </span><span class="string">" requirements:^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">PREFER_HELD</span><span class="plain">;</span>
<span class="identifier">a_s</span><span class="plain"> = </span><span class="identifier">SCORE__BESTLOC</span><span class="plain">; </span><span class="identifier">l_s</span><span class="plain"> = </span><span class="identifier">SCORE__NEXTBESTLOC</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">action_to_be</span><span class="plain"> == ##</span><span class="identifier">Take</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> ##</span><span class="identifier">Remove</span><span class="plain">) {</span>
<span class="identifier">a_s</span><span class="plain"> = </span><span class="identifier">SCORE__NEXTBESTLOC</span><span class="plain">; </span><span class="identifier">l_s</span><span class="plain"> = </span><span class="identifier">SCORE__BESTLOC</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">context</span><span class="plain"> = </span><span class="identifier">context</span><span class="plain">; </span><span class="comment">silence warning</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">ifnot</span><span class="plain">;</span>
<span class="identifier">a_s</span><span class="plain"> = </span><span class="identifier">SCORE__NEXTBESTLOC</span><span class="plain">; </span><span class="identifier">l_s</span><span class="plain"> = </span><span class="identifier">SCORE__BESTLOC</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">context</span><span class="plain"> == </span><span class="identifier">HELD_TOKEN</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">MULTIHELD_TOKEN</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">MULTIEXCEPT_TOKEN</span><span class="plain">) {</span>
<span class="identifier">a_s</span><span class="plain"> = </span><span class="identifier">SCORE__BESTLOC</span><span class="plain">; </span><span class="identifier">l_s</span><span class="plain"> = </span><span class="identifier">SCORE__NEXTBESTLOC</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">endif</span><span class="plain">; </span><span class="comment">PREFER_HELD</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">number_matched</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">obj</span><span class="plain"> = </span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">; </span><span class="identifier">its_owner</span><span class="plain"> = </span><span class="reserved">parent</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">); </span><span class="identifier">its_score</span><span class="plain">=0; </span><span class="identifier">met</span><span class="plain">=0;</span>
2020-04-14 19:56:54 +03:00
<span class="comment"> if (indef_type &amp; OTHER_BIT ~= 0</span>
<span class="comment"> &amp;&amp; obj ~= itobj or himobj or herobj) met++;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">MY_BIT</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain"> &amp;&amp; </span><span class="identifier">its_owner</span><span class="plain"> == </span><span class="identifier">actor</span><span class="plain">) </span><span class="identifier">met</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">THAT_BIT</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain"> &amp;&amp; </span><span class="identifier">its_owner</span><span class="plain"> == </span><span class="identifier">actors_location</span><span class="plain">) </span><span class="identifier">met</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">LIT_BIT</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain"> &amp;&amp; </span><span class="identifier">obj</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">light</span><span class="plain">) </span><span class="identifier">met</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_type</span><span class="plain"> &amp; </span><span class="identifier">UNLIT_BIT</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain"> &amp;&amp; </span><span class="identifier">obj</span><span class="plain"> </span><span class="reserved">hasnt</span><span class="plain"> </span><span class="identifier">light</span><span class="plain">) </span><span class="identifier">met</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_owner</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain"> &amp;&amp; </span><span class="identifier">its_owner</span><span class="plain"> == </span><span class="identifier">indef_owner</span><span class="plain">) </span><span class="identifier">met</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">met</span><span class="plain"> &lt; </span><span class="identifier">threshold</span><span class="plain">) {</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">4</span><span class="plain">)</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">" "</span><span class="plain">, (</span><span class="identifier">The</span><span class="plain">) </span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">, </span><span class="string">" ("</span><span class="plain">, </span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">, </span><span class="string">") in "</span><span class="plain">,</span>
<span class="plain">(</span><span class="identifier">the</span><span class="plain">) </span><span class="identifier">its_owner</span><span class="plain">, </span><span class="string">" is rejected (doesn't match descriptors)^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
<span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> = -1;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">its_score</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain"> </span><span class="reserved">hasnt</span><span class="plain"> </span><span class="identifier">concealed</span><span class="plain">) </span><span class="identifier">its_score</span><span class="plain"> = </span><span class="identifier">SCORE__UNCONCEALED</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">its_owner</span><span class="plain"> == </span><span class="identifier">actor</span><span class="plain">) </span><span class="identifier">its_score</span><span class="plain"> = </span><span class="identifier">its_score</span><span class="plain"> + </span><span class="identifier">a_s</span><span class="plain">;</span>
<span class="reserved">else</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">its_owner</span><span class="plain"> == </span><span class="identifier">actors_location</span><span class="plain">) </span><span class="identifier">its_score</span><span class="plain"> = </span><span class="identifier">its_score</span><span class="plain"> + </span><span class="identifier">l_s</span><span class="plain">;</span>
<span class="reserved">else</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">its_owner</span><span class="plain"> ~= </span><span class="identifier">Compass</span><span class="plain">) </span><span class="identifier">its_score</span><span class="plain"> = </span><span class="identifier">its_score</span><span class="plain"> + </span><span class="identifier">SCORE__NOTCOMPASS</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">its_score</span><span class="plain"> = </span><span class="identifier">its_score</span><span class="plain"> + </span><span class="identifier">SCORE__CHOOSEOBJ</span><span class="plain"> * </span><span class="identifier">ChooseObjects</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">, </span><span class="constant">2</span><span class="plain">);</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain"> </span><span class="reserved">hasnt</span><span class="plain"> </span><span class="identifier">scenery</span><span class="plain">) </span><span class="identifier">its_score</span><span class="plain"> = </span><span class="identifier">its_score</span><span class="plain"> + </span><span class="identifier">SCORE__NOTSCENERY</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain"> ~= </span><span class="identifier">actor</span><span class="plain">) </span><span class="identifier">its_score</span><span class="plain"> = </span><span class="identifier">its_score</span><span class="plain"> + </span><span class="identifier">SCORE__NOTACTOR</span><span class="plain">;</span>
2020-04-14 19:56:54 +03:00
<span class="comment"> A small bonus for having the correct GNA,</span>
<span class="comment"> for sorting out ambiguous articles and the like.</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_cases</span><span class="plain"> &amp; (</span><span class="identifier">PowersOfTwo_TB</span><span class="plain">--&gt;(</span><span class="identifier">GetGNAOfObject</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">))))</span>
<span class="identifier">its_score</span><span class="plain"> = </span><span class="identifier">its_score</span><span class="plain"> + </span><span class="identifier">SCORE__GNA</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">match_scores</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">match_scores</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> + </span><span class="identifier">its_score</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">4</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" "</span><span class="plain">, (</span><span class="identifier">The</span><span class="plain">) </span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">, </span><span class="string">" ("</span><span class="plain">, </span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">,</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="string">") in "</span><span class="plain">, (</span><span class="identifier">the</span><span class="plain">) </span><span class="identifier">its_owner</span><span class="plain">, </span><span class="string">" : "</span><span class="plain">, </span><span class="identifier">match_scores</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">, </span><span class="string">" points^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
<span class="plain">}</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> }</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">number_matched</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> == -1) {</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="identifier">number_matched</span><span class="plain">-1) { </span><span class="identifier">number_matched</span><span class="plain">--; </span><span class="reserved">break</span><span class="plain">; }</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=</span><span class="identifier">i</span><span class="plain"> : </span><span class="identifier">j</span><span class="plain">&lt;</span><span class="identifier">number_matched</span><span class="plain">-1 : </span><span class="identifier">j</span><span class="plain">++) {</span>
<span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain"> = </span><span class="identifier">match_list</span><span class="plain">--&gt;(</span><span class="identifier">j</span><span class="plain">+1);</span>
<span class="identifier">match_scores</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain"> = </span><span class="identifier">match_scores</span><span class="plain">--&gt;(</span><span class="identifier">j</span><span class="plain">+1);</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">number_matched</span><span class="plain">--;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP39"></a><b>&#167;39. BestGuess. </b><code class="display"><span class="extract">BestGuess</span></code> makes the best guess it can out of the match list, assuming that
everything in the match list is textually as good as everything else;
2020-04-14 19:56:54 +03:00
however it ignores items marked as \(-1\), and so marks anything it chooses.
It returns \(-1\) if there are no possible choices.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">BestGuess</span><span class="plain"> </span><span class="identifier">earliest</span><span class="plain"> </span><span class="identifier">its_score</span><span class="plain"> </span><span class="identifier">best</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">earliest</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">best</span><span class="plain"> = -1;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">number_matched</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">its_score</span><span class="plain"> = </span><span class="identifier">match_scores</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">its_score</span><span class="plain"> &gt; </span><span class="identifier">best</span><span class="plain">) { </span><span class="identifier">best</span><span class="plain"> = </span><span class="identifier">its_score</span><span class="plain">; </span><span class="identifier">earliest</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">; }</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">4</span><span class="plain">)</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">best</span><span class="plain"> &lt; </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" Best guess ran out of choices^"</span><span class="plain">;</span>
<span class="plain"> </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" Best guess "</span><span class="plain">, (</span><span class="identifier">the</span><span class="plain">) </span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">earliest</span><span class="plain">,</span>
2020-01-13 13:02:57 +02:00
<span class="string">" ("</span><span class="plain">, </span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">earliest</span><span class="plain">, </span><span class="string">")^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">best</span><span class="plain"> &lt; </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> -1;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">earliest</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">earliest</span><span class="plain"> = -1;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP40"></a><b>&#167;40. SingleBestGuess. </b><code class="display"><span class="extract">SingleBestGuess</span></code> returns the highest-scoring object in the match list
2020-04-14 19:56:54 +03:00
if it is the clear winner, or returns \(-1\) if there is no clear winner.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">SingleBestGuess</span><span class="plain"> </span><span class="identifier">earliest</span><span class="plain"> </span><span class="identifier">its_score</span><span class="plain"> </span><span class="identifier">best</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">earliest</span><span class="plain"> = -1; </span><span class="identifier">best</span><span class="plain"> = -1000;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">number_matched</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">its_score</span><span class="plain"> = </span><span class="identifier">match_scores</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">its_score</span><span class="plain"> == </span><span class="identifier">best</span><span class="plain">) </span><span class="identifier">earliest</span><span class="plain"> = -1;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">its_score</span><span class="plain"> &gt; </span><span class="identifier">best</span><span class="plain">) { </span><span class="identifier">best</span><span class="plain"> = </span><span class="identifier">its_score</span><span class="plain">; </span><span class="identifier">earliest</span><span class="plain"> = </span><span class="identifier">match_list</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">; }</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">earliest</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP41"></a><b>&#167;41. Identical. </b><code class="display"><span class="extract">Identical</span></code> decides whether or not two objects can be distinguished from each
other by anything the player can type. If not, it returns <code class="display"><span class="extract">true</span></code>. (This
routine is critical to the handling of plurals, and the list-writer
requires it to be an equivalence relation between objects: but it is,
2020-04-14 19:56:54 +03:00
because it is equivalent to \(O_1\sim O_2\) if and only if \(f(O_1) = f(O_2)\)
for some function \(f\).)
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">Identical</span><span class="plain"> </span><span class="identifier">o1</span><span class="plain"> </span><span class="identifier">o2</span><span class="plain"> </span><span class="identifier">p1</span><span class="plain"> </span><span class="identifier">p2</span><span class="plain"> </span><span class="identifier">n1</span><span class="plain"> </span><span class="identifier">n2</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">j</span><span class="plain"> </span><span class="identifier">flag</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">o1</span><span class="plain"> == </span><span class="identifier">o2</span><span class="plain">) </span><span class="reserved">rtrue</span><span class="plain">; </span><span class="comment">This should never happen, but to be on the safe side</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">o1</span><span class="plain"> == </span><span class="constant">0</span><span class="plain"> || </span><span class="identifier">o2</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">rfalse</span><span class="plain">; </span><span class="comment">Similarly</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">o1</span><span class="plain"> </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">K3_direction</span><span class="plain"> || </span><span class="identifier">o2</span><span class="plain"> </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">K3_direction</span><span class="plain">) </span><span class="reserved">rfalse</span><span class="plain">; </span><span class="comment">Saves time</span>
2020-04-14 19:56:54 +03:00
<span class="comment"> What complicates things is that o1 or o2 might have a parsing routine,</span>
<span class="comment"> so the parser can't know from here whether they are or aren't the same.</span>
<span class="comment"> If they have different parsing routines, we simply assume they're</span>
<span class="comment"> different. If they have the same routine (which they probably got from</span>
<span class="comment"> a class definition) then the decision process is as follows:</span>
2020-04-07 03:06:09 +03:00
2020-04-14 19:56:54 +03:00
<span class="comment"> the routine is called (with self being o1, not that it matters)</span>
<span class="comment"> with noun and second being set to o1 and o2, and action being set</span>
<span class="comment"> to the fake action TheSame. If it returns -1, they are found</span>
<span class="comment"> identical; if -2, different; and if &gt;=0, then the usual method</span>
<span class="comment"> is used instead.</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">o1</span><span class="plain">.</span><span class="identifier">parse_name</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain"> || </span><span class="identifier">o2</span><span class="plain">.</span><span class="identifier">parse_name</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) {</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">o1</span><span class="plain">.</span><span class="identifier">parse_name</span><span class="plain"> ~= </span><span class="identifier">o2</span><span class="plain">.</span><span class="identifier">parse_name</span><span class="plain">) </span><span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain"> </span><span class="identifier">parser_action</span><span class="plain"> = ##</span><span class="identifier">TheSame</span><span class="plain">; </span><span class="identifier">parser_one</span><span class="plain"> = </span><span class="identifier">o1</span><span class="plain">; </span><span class="identifier">parser_two</span><span class="plain"> = </span><span class="identifier">o2</span><span class="plain">;</span>
<span class="plain"> </span><span class="identifier">j</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">; </span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">RunRoutines</span><span class="plain">(</span><span class="identifier">o1</span><span class="plain">,</span><span class="identifier">parse_name</span><span class="plain">); </span><span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">j</span><span class="plain">;</span>
<span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == -1) </span><span class="reserved">rtrue</span><span class="plain">;</span>
<span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == -2) </span><span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-14 19:56:54 +03:00
<span class="comment"> This is the default algorithm: do they have the same words in their</span>
<span class="comment"> "name" (i.e. property no. 1) properties. (Note that the following allows</span>
<span class="comment"> for repeated words and words in different orders.)</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">p1</span><span class="plain"> = </span><span class="identifier">o1</span><span class="plain">.&amp;1; </span><span class="identifier">n1</span><span class="plain"> = (</span><span class="identifier">o1</span><span class="plain">.#1)/</span><span class="identifier">WORDSIZE</span><span class="plain">;</span>
<span class="identifier">p2</span><span class="plain"> = </span><span class="identifier">o2</span><span class="plain">.&amp;1; </span><span class="identifier">n2</span><span class="plain"> = (</span><span class="identifier">o2</span><span class="plain">.#1)/</span><span class="identifier">WORDSIZE</span><span class="plain">;</span>
2020-04-14 19:56:54 +03:00
<span class="comment"> for (i=0 : i&lt;n1 : i++) { print (address) p1--&gt;i, " "; } new_line;</span>
<span class="comment"> for (i=0 : i&lt;n2 : i++) { print (address) p2--&gt;i, " "; } new_line;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">n1</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">flag</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0 : </span><span class="identifier">j</span><span class="plain">&lt;</span><span class="identifier">n2</span><span class="plain"> : </span><span class="identifier">j</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">p1</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> == </span><span class="identifier">p2</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain">) </span><span class="identifier">flag</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">flag</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0 : </span><span class="identifier">j</span><span class="plain">&lt;</span><span class="identifier">n2</span><span class="plain"> : </span><span class="identifier">j</span><span class="plain">++) {</span>
<span class="identifier">flag</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">n1</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">p1</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> == </span><span class="identifier">p2</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain">) </span><span class="identifier">flag</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">flag</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-14 19:56:54 +03:00
<span class="comment"> print "Which are identical!^";</span>
<span class="reserved">rtrue</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP42"></a><b>&#167;42. Print Command. </b><code class="display"><span class="extract">PrintCommand</span></code> reconstructs the command as it presently reads, from the
pattern which has been built up.
</p>
<p class="inwebparagraph">If <code class="display"><span class="extract">from</span></code> is 0, it starts with the verb: then it goes through the pattern.
</p>
<p class="inwebparagraph">The other parameter is <code class="display"><span class="extract">emptyf</span></code> &mdash; a flag: if 0, it goes up to <code class="display"><span class="extract">pcount</span></code>:
if 1, it goes up to <code class="display"><span class="extract">pcount</span></code>-1.
</p>
<p class="inwebparagraph">Note that verbs and prepositions are printed out of the dictionary:
and that since the dictionary may only preserve the first six characters
of a word (in a V3 game), we have to hand-code the longer words needed.
At present, I7 doesn't do this, but it probably should.
</p>
<p class="inwebparagraph">(Recall that pattern entries are 0 for "multiple object", 1 for "special
word", 2 to <code class="display"><span class="extract">REPARSE_CODE-1</span></code> are object numbers and <code class="display"><span class="extract">REPARSE_CODE+n</span></code> means
the preposition <code class="display"><span class="extract">n</span></code>.)
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">PrintInferredCommand</span><span class="plain"> </span><span class="identifier">from</span><span class="plain"> </span><span class="identifier">singleton_noun</span><span class="plain">;</span>
<span class="identifier">singleton_noun</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">from</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">from</span><span class="plain"> == </span><span class="identifier">pcount</span><span class="plain">-1) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">pattern</span><span class="plain">--&gt;</span><span class="identifier">from</span><span class="plain"> &gt; </span><span class="constant">1</span><span class="plain">) &amp;&amp; (</span><span class="identifier">pattern</span><span class="plain">--&gt;</span><span class="identifier">from</span><span class="plain"> &lt; </span><span class="identifier">REPARSE_CODE</span><span class="plain">))</span>
<span class="identifier">singleton_noun</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">singleton_noun</span><span class="plain">) {</span>
<span class="identifier">BeginActivity</span><span class="plain">(</span><span class="identifier">CLARIFYING_PARSERS_CHOICE_ACT</span><span class="plain">, </span><span class="identifier">pattern</span><span class="plain">--&gt;</span><span class="identifier">from</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ForActivity</span><span class="plain">(</span><span class="identifier">CLARIFYING_PARSERS_CHOICE_ACT</span><span class="plain">, </span><span class="identifier">pattern</span><span class="plain">--&gt;</span><span class="identifier">from</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"("</span><span class="plain">; </span><span class="identifier">PrintCommand</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">); </span><span class="reserved">print</span><span class="plain"> </span><span class="string">")^"</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">EndActivity</span><span class="plain">(</span><span class="identifier">CLARIFYING_PARSERS_CHOICE_ACT</span><span class="plain">, </span><span class="identifier">pattern</span><span class="plain">--&gt;</span><span class="identifier">from</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"("</span><span class="plain">; </span><span class="identifier">PrintCommand</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">); </span><span class="reserved">print</span><span class="plain"> </span><span class="string">")^"</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">PrintCommand</span><span class="plain"> </span><span class="identifier">from</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">k</span><span class="plain"> </span><span class="identifier">spacing_flag</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">verb_word</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">LanguageVerb</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PrintVerb</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> (</span><span class="identifier">address</span><span class="plain">) </span><span class="identifier">i</span><span class="plain">;</span>
<span class="identifier">from</span><span class="plain">++; </span><span class="identifier">spacing_flag</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">k</span><span class="plain">=</span><span class="identifier">from</span><span class="plain"> : </span><span class="identifier">k</span><span class="plain">&lt;</span><span class="identifier">pcount</span><span class="plain"> : </span><span class="identifier">k</span><span class="plain">++) {</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">pattern</span><span class="plain">--&gt;</span><span class="identifier">k</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="identifier">PATTERN_NULL</span><span class="plain">) </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">spacing_flag</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> (</span><span class="identifier">char</span><span class="plain">) </span><span class="character">' '</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) { </span><span class="identifier">PARSER_CLARIF_INTERNAL_RM</span><span class="plain">(</span><span class="character">'F'</span><span class="plain">); </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">TokenPrinted</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) { </span><span class="identifier">PARSER_CLARIF_INTERNAL_RM</span><span class="plain">(</span><span class="character">'G'</span><span class="plain">); </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">TokenPrinted</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> &gt;= </span><span class="identifier">REPARSE_CODE</span><span class="plain">)</span>
<span class="reserved">print</span><span class="plain"> (</span><span class="identifier">address</span><span class="plain">) </span><span class="identifier">VM_NumberToDictionaryAddress</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">-</span><span class="identifier">REPARSE_CODE</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">K3_direction</span><span class="plain">)</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">print</span><span class="plain"> (</span><span class="identifier">LanguageDirection</span><span class="plain">) </span><span class="identifier">i</span><span class="plain">; </span><span class="comment">the direction name as adverb</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">else</span>
<span class="reserved">print</span><span class="plain"> (</span><span class="identifier">the</span><span class="plain">) </span><span class="identifier">i</span><span class="plain">;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> .</span><span class="identifier">TokenPrinted</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">spacing_flag</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP43"></a><b>&#167;43. CantSee. </b>The <code class="display"><span class="extract">CantSee</span></code> routine returns a good error number for the situation where
the last word looked at didn't seem to refer to any object in context.
</p>
<p class="inwebparagraph">The idea is that: if the actor is in a location (but not inside something
like, for instance, a tank which is in that location) then an attempt to
refer to one of the words listed as meaningful-but-irrelevant there
will cause "you don't need to refer to that in this game" rather than
"no such thing" or "what's `it'?".
</p>
<p class="inwebparagraph">(The advantage of not having looked at "irrelevant" local nouns until
now is that it stops them from clogging up the ambiguity-resolving process.
Thus game objects always triumph over scenery.)
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">CantSee</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">w</span><span class="plain"> </span><span class="identifier">e</span><span class="plain">;</span>
<span class="identifier">saved_oops</span><span class="plain">=</span><span class="identifier">oops_from</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">scope_token</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">scope_error</span><span class="plain"> = </span><span class="identifier">scope_token</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">ASKSCOPE_PE</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">wn</span><span class="plain">--; </span><span class="identifier">w</span><span class="plain"> = </span><span class="identifier">NextWord</span><span class="plain">();</span>
<span class="identifier">e</span><span class="plain"> = </span><span class="identifier">CANTSEE_PE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">w</span><span class="plain"> == </span><span class="identifier">pronoun_word</span><span class="plain">) {</span>
<span class="identifier">w</span><span class="plain"> = </span><span class="identifier">NextWordStopped</span><span class="plain">(); </span><span class="identifier">wn</span><span class="plain">--;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">w</span><span class="plain"> == -1) || (</span><span class="identifier">line_token</span><span class="plain">--&gt;(</span><span class="identifier">pcount</span><span class="plain">) ~= </span><span class="identifier">ENDIT_TOKEN</span><span class="plain">)) {</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pcount</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">AnalyseToken</span><span class="plain">(</span><span class="identifier">line_token</span><span class="plain">--&gt;(</span><span class="identifier">pcount</span><span class="plain">-1));</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">pcount</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">found_ttype</span><span class="plain"> == </span><span class="identifier">ROUTINE_FILTER_TT</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">ATTR_FILTER_TT</span><span class="plain">))</span>
<span class="identifier">e</span><span class="plain"> = </span><span class="identifier">NOTINCONTEXT_PE</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">pronoun__word</span><span class="plain"> = </span><span class="identifier">pronoun_word</span><span class="plain">; </span><span class="identifier">pronoun__obj</span><span class="plain"> = </span><span class="identifier">pronoun_obj</span><span class="plain">;</span>
<span class="identifier">e</span><span class="plain"> = </span><span class="identifier">ITGONE_PE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">etype</span><span class="plain"> &gt; </span><span class="identifier">e</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">etype</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">e</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP44"></a><b>&#167;44. Multiple Object List. </b>The <code class="display"><span class="extract">MultiAdd</span></code> routine adds object <code class="display"><span class="extract">o</span></code> to the multiple-object-list. This is
only allowed to hold <code class="display"><span class="extract">MATCH_LIST_WORDS</span></code> minus one objects at most, at which
point it ignores any new entries (and sets a global flag so that a warning
may later be printed if need be).
</p>
<p class="inwebparagraph">The <code class="display"><span class="extract">MultiSub</span></code> routine deletes object <code class="display"><span class="extract">o</span></code> from the multiple-object-list.
It returns 0 if the object was there in the first place, and 9 (because
this is the appropriate error number in <code class="display"><span class="extract">Parser()</span></code>) if it wasn't.
</p>
<p class="inwebparagraph">The <code class="display"><span class="extract">MultiFilter</span></code> routine goes through the multiple-object-list and throws
out anything without the given attribute <code class="display"><span class="extract">attr</span></code> set.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">MultiAdd</span><span class="plain"> </span><span class="identifier">o</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">;</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">multiple_object</span><span class="plain">--&gt;0;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="identifier">MATCH_LIST_WORDS</span><span class="plain">-1) { </span><span class="identifier">toomany_flag</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="reserved">rtrue</span><span class="plain">; }</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=1 : </span><span class="identifier">j</span><span class="plain">&lt;=</span><span class="identifier">i</span><span class="plain"> : </span><span class="identifier">j</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">o</span><span class="plain"> == </span><span class="identifier">multiple_object</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain">) </span><span class="reserved">rtrue</span><span class="plain">;</span>
<span class="identifier">i</span><span class="plain">++;</span>
<span class="identifier">multiple_object</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">o</span><span class="plain">;</span>
<span class="identifier">multiple_object</span><span class="plain">--&gt;0 = </span><span class="identifier">i</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">MultiSub</span><span class="plain"> </span><span class="identifier">o</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">j</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">multiple_object</span><span class="plain">--&gt;0;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=1 : </span><span class="identifier">j</span><span class="plain">&lt;=</span><span class="identifier">i</span><span class="plain"> : </span><span class="identifier">j</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">o</span><span class="plain"> == </span><span class="identifier">multiple_object</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain">) {</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">k</span><span class="plain">=</span><span class="identifier">j</span><span class="plain"> : </span><span class="identifier">k</span><span class="plain">&lt;=</span><span class="identifier">i</span><span class="plain"> : </span><span class="identifier">k</span><span class="plain">++) </span><span class="identifier">multiple_object</span><span class="plain">--&gt;</span><span class="identifier">k</span><span class="plain"> = </span><span class="identifier">multiple_object</span><span class="plain">--&gt;(</span><span class="identifier">k</span><span class="plain">+1);</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">multiple_object</span><span class="plain">--&gt;0 = --</span><span class="identifier">i</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">VAGUE_PE</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">MultiFilter</span><span class="plain"> </span><span class="identifier">attr</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">j</span><span class="plain"> </span><span class="identifier">o</span><span class="plain">;</span>
<span class="plain">.</span><span class="identifier">MFiltl</span><span class="plain">;</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">multiple_object</span><span class="plain">--&gt;0;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=1 : </span><span class="identifier">j</span><span class="plain">&lt;=</span><span class="identifier">i</span><span class="plain"> : </span><span class="identifier">j</span><span class="plain">++) {</span>
<span class="identifier">o</span><span class="plain"> = </span><span class="identifier">multiple_object</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">o</span><span class="plain"> </span><span class="reserved">hasnt</span><span class="plain"> </span><span class="identifier">attr</span><span class="plain">) { </span><span class="identifier">MultiSub</span><span class="plain">(</span><span class="identifier">o</span><span class="plain">); </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">MFiltl</span><span class="plain">; }</span>
<span class="plain">}</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP45"></a><b>&#167;45. Scope. </b>The scope of an actor is the set of objects which he can refer to in typed
commands, which is normally the same as the set of visible objects; but this
can be modified. This is how I7 handles tokens like "[any room]".
</p>
<p class="inwebparagraph">Scope determination is done by calling <code class="display"><span class="extract">SearchScope</span></code> to iterate through the
objects in scope, and "visit" each one: which means, carry out some task
for each as we get there. The task depends on the current value of
<code class="display"><span class="extract">scope_reason</span></code>, which is <code class="display"><span class="extract">PARSING_REASON</span></code> when the parser is matching
command text against object names.
</p>
<p class="inwebparagraph">The scope machinery is built on a number of levels, each making use only
of lower levels:
</p>
<ul class="items"><li>(0) Either <code class="display"><span class="extract">NounDomain</span></code>, <code class="display"><span class="extract">TestScope</span></code> or <code class="display"><span class="extract">LoopOverScope</span></code> makes one or more
calls to <code class="display"><span class="extract">SearchScope</span></code> (on level 1). The point of making multiple calls
is to influence the order in which items in scope are visited, which improves
the quality of "take all"-style multiple object lists, for instance.
</li><li>(1) <code class="display"><span class="extract">SearchScope</span></code> searches for the objects in scope which are within first
one domain, and then another: for instance, first within the current room
but not within the current actor, and then within the current actor. It can
be called either from level 0, or externally from the choose-objects
machinery, but is not recursive. It works within the context of a given
token in the parser (when called for <code class="display"><span class="extract">PARSING_REASON</span></code>) and in particular
the <code class="display"><span class="extract">multiinside</span></code> token, and also handles testing commands, scope tokens,
scope in darkness, and intervention by the I7 "deciding the scope of"
activity. Most of its actual searches are delegated to <code class="display"><span class="extract">ScopeWithin</span></code> (level
2), but it also uses <code class="display"><span class="extract">DoScopeActionAndRecurse</span></code> (level 3) and
<code class="display"><span class="extract">DoScopeAction</span></code> (level 4) as necessary.
</li><li>(2) <code class="display"><span class="extract">ScopeWithin</span></code> iterates through the objects in scope which are within
one supplied domain, but not within another. It can be called either
from level 1, or independently from rules in the "deciding the scope of"
activity via the I7 "place the contents of X in scope" phrase. It calls
<code class="display"><span class="extract">DoScopeActionAndRecurse</span></code> (level 3) on any unconcealed objects it finds.
</li><li>(3) <code class="display"><span class="extract">DoScopeActionAndRecurse</span></code> visits a given object by calling down to
<code class="display"><span class="extract">DoScopeAction</span></code> (level 4), and recurses to all unconcealed object-tree
contents and component parts of the object. The I7 phrase "place X in
scope" uses this routine.
</li><li>(4) <code class="display"><span class="extract">DoScopeAction</span></code> simply visits a single object, taking whatever action
is needed there &mdash; which will depend on the <code class="display"><span class="extract">scope_reason</span></code>. The only use
made by the parser of <code class="display"><span class="extract">TryGivenObject</span></code>, which tries to match command text
against the name of a given object, is from here. The I7 phrase "place X
in scope, but not its contents" uses this routine.
</li></ul>
<p class="inwebparagraph">Two routines are provided for code external to the parser to modify the
scope. They should be called only during scope deliberations &mdash; i.e.,
in <code class="display"><span class="extract">scope=...</span></code> tokens or in rules for the "deciding the scope of"
activity. (At present, <code class="display"><span class="extract">AddToScope</span></code> is not used in I7 at all.) Note
that this I7 form of <code class="display"><span class="extract">PlaceInScope</span></code> has a slightly different specification
to its I6 library counterpart of the same name: it can place a room in
scope. (In I6, room names were not normally parsed.)
</p>
<pre class="display">
2020-04-07 03:06:09 +03:00
<span class="plain">[ </span><span class="identifier">PlaceInScope</span><span class="plain"> </span><span class="identifier">O</span><span class="plain"> </span><span class="identifier">opts</span><span class="plain"> </span><span class="identifier">ws</span><span class="plain">; </span><span class="comment">If opts is set, do not place contents in scope</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">ws</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">; </span><span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">match_from</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">opts</span><span class="plain"> == </span><span class="reserved">false</span><span class="plain">) </span><span class="identifier">DoScopeActionAndRecurse</span><span class="plain">(</span><span class="identifier">O</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">DoScopeAction</span><span class="plain">(</span><span class="identifier">O</span><span class="plain">);</span>
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">ws</span><span class="plain">; </span><span class="reserved">return</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">AddToScope</span><span class="plain"> </span><span class="identifier">obj</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ats_flag</span><span class="plain"> &gt;= </span><span class="constant">2</span><span class="plain">) </span><span class="identifier">DoScopeActionAndRecurse</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">, </span><span class="constant">0</span><span class="plain">, </span><span class="identifier">ats_flag</span><span class="plain">-2);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ats_flag</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) { </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">HasLightSource</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">)==1) </span><span class="identifier">ats_hls</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; }</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP46"></a><b>&#167;46. Scope Level 0. </b>The two ways of starting up the scope machinery other than via the parser
code above.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">TestScope</span><span class="plain"> </span><span class="identifier">obj</span><span class="plain"> </span><span class="identifier">act</span><span class="plain"> </span><span class="identifier">a</span><span class="plain"> </span><span class="identifier">al</span><span class="plain"> </span><span class="identifier">sr</span><span class="plain"> </span><span class="identifier">x</span><span class="plain"> </span><span class="identifier">y</span><span class="plain">;</span>
<span class="identifier">x</span><span class="plain"> = </span><span class="identifier">parser_one</span><span class="plain">; </span><span class="identifier">y</span><span class="plain"> = </span><span class="identifier">parser_two</span><span class="plain">;</span>
<span class="identifier">parser_one</span><span class="plain"> = </span><span class="identifier">obj</span><span class="plain">; </span><span class="identifier">parser_two</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">a</span><span class="plain"> = </span><span class="identifier">actor</span><span class="plain">; </span><span class="identifier">al</span><span class="plain"> = </span><span class="identifier">actors_location</span><span class="plain">;</span>
<span class="identifier">sr</span><span class="plain"> = </span><span class="identifier">scope_reason</span><span class="plain">; </span><span class="identifier">scope_reason</span><span class="plain"> = </span><span class="identifier">TESTSCOPE_REASON</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">act</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">actor</span><span class="plain"> = </span><span class="identifier">player</span><span class="plain">; </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">actor</span><span class="plain"> = </span><span class="identifier">act</span><span class="plain">;</span>
<span class="identifier">actors_location</span><span class="plain"> = </span><span class="identifier">ScopeCeiling</span><span class="plain">(</span><span class="identifier">actor</span><span class="plain">);</span>
<span class="identifier">SearchScope</span><span class="plain">(</span><span class="identifier">actors_location</span><span class="plain">, </span><span class="identifier">actor</span><span class="plain">, </span><span class="constant">0</span><span class="plain">); </span><span class="identifier">scope_reason</span><span class="plain"> = </span><span class="identifier">sr</span><span class="plain">; </span><span class="identifier">actor</span><span class="plain"> = </span><span class="identifier">a</span><span class="plain">;</span>
<span class="identifier">actors_location</span><span class="plain"> = </span><span class="identifier">al</span><span class="plain">; </span><span class="identifier">parser_one</span><span class="plain"> = </span><span class="identifier">x</span><span class="plain">; </span><span class="identifier">x</span><span class="plain"> = </span><span class="identifier">parser_two</span><span class="plain">; </span><span class="identifier">parser_two</span><span class="plain"> = </span><span class="identifier">y</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">x</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">LoopOverScope</span><span class="plain"> </span><span class="identifier">routine</span><span class="plain"> </span><span class="identifier">act</span><span class="plain"> </span><span class="identifier">x</span><span class="plain"> </span><span class="identifier">y</span><span class="plain"> </span><span class="identifier">a</span><span class="plain"> </span><span class="identifier">al</span><span class="plain">;</span>
<span class="identifier">x</span><span class="plain"> = </span><span class="identifier">parser_one</span><span class="plain">; </span><span class="identifier">y</span><span class="plain"> = </span><span class="identifier">scope_reason</span><span class="plain">; </span><span class="identifier">a</span><span class="plain"> = </span><span class="identifier">actor</span><span class="plain">; </span><span class="identifier">al</span><span class="plain"> = </span><span class="identifier">actors_location</span><span class="plain">;</span>
<span class="identifier">parser_one</span><span class="plain"> = </span><span class="identifier">routine</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">act</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">actor</span><span class="plain"> = </span><span class="identifier">player</span><span class="plain">; </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">actor</span><span class="plain"> = </span><span class="identifier">act</span><span class="plain">;</span>
<span class="identifier">actors_location</span><span class="plain"> = </span><span class="identifier">ScopeCeiling</span><span class="plain">(</span><span class="identifier">actor</span><span class="plain">);</span>
<span class="identifier">scope_reason</span><span class="plain"> = </span><span class="identifier">LOOPOVERSCOPE_REASON</span><span class="plain">;</span>
<span class="identifier">SearchScope</span><span class="plain">(</span><span class="identifier">actors_location</span><span class="plain">, </span><span class="identifier">actor</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="identifier">parser_one</span><span class="plain"> = </span><span class="identifier">x</span><span class="plain">; </span><span class="identifier">scope_reason</span><span class="plain"> = </span><span class="identifier">y</span><span class="plain">; </span><span class="identifier">actor</span><span class="plain"> = </span><span class="identifier">a</span><span class="plain">; </span><span class="identifier">actors_location</span><span class="plain"> = </span><span class="identifier">al</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP47"></a><b>&#167;47. SearchScope. </b>Level 1. The method is:
</p>
<ul class="items"><li>(a) If the context is a <code class="display"><span class="extract">scope=...</span></code> token, then the search is delegated
to "stage 2" of the scope routine. This was the old I6 way to override
the searching behaviour: while users probably won't be using it any more,
the template does, in order to give testing commands universal scope which
is exempt from the activity below; and the NI compiler creates <code class="display"><span class="extract">scope=...</span></code>
tokens to handle Understand grammar such as "[any room]". So the feature
remains very much still in use.
</li><li>(b) The "deciding the scope of" activity is given the chance to intervene.
This is the I7 way to override the searching behaviour, and is the one taken
by users.
</li><li>(c) And otherwise:
<ul class="items"><li>(1) The I6 <code class="display"><span class="extract">multiinside</span></code> token, used as the first noun of its grammar line,
has as its scope all of the objects which are inside or on top of the
2020-04-14 19:56:54 +03:00
{\it second} noun of the grammar line. This provides a neat scope for the
ALL in a command like GET ALL FROM CUPBOARD, where the player clearly
does not intend ALL to refer to the cupboard itself, for instance. The
difficulty is that we don't yet know what the second object is, if we are
parsing left to right. But the parser code above has taken care of all of
that, and the <code class="display"><span class="extract">advance_warning</span></code> global is set to the object number of the
2020-04-14 19:56:54 +03:00
second noun, or to \(-1\) if that is not yet known. Note that we check that
the contents are visible before adding them to scope, because otherwise
an unscrupulous player could use such a command to detect the contents of
an opaque locked box. If this rule applies, we skip (c.2), (c.3) and (c.4).
</li><li>(2) For all other tokens except <code class="display"><span class="extract">creature</span></code>, searching scope for the room
holding the current actor always catches the compass directions unless a
definite article has already been typed. (Thus OPEN THE EAST would match
an object called "east door", but not the compass direction "east".)
</li><li>(3) The contents of <code class="display"><span class="extract">domain1</span></code> which are not contents of <code class="display"><span class="extract">domain2</span></code> are
placed in scope, and so are any component parts of <code class="display"><span class="extract">domain1</span></code>. If <code class="display"><span class="extract">domain1</span></code>
is a container or supporter, it is placed in scope itself.
</li><li>(4) The contents and component parts of <code class="display"><span class="extract">domain2</span></code> are placed in scope.
If <code class="display"><span class="extract">domain2</span></code> is a container or supporter, it is placed in scope itself.
</li><li>(5) In darkness, the actor and his component parts are in scope. If the
actor is inside or on top of something, then that thing is also in scope.
(This avoids a situation where the player gets into an opaque box, then
pulls it closed from the inside, plunging himself into darkness, then types
OPEN BOX only to be told that he can't see any such thing.)
</li></ul>
</li></ul>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">SearchScope</span><span class="plain"> </span><span class="identifier">domain1</span><span class="plain"> </span><span class="identifier">domain2</span><span class="plain"> </span><span class="identifier">context</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">domain1</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">(a)</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">scope_token</span><span class="plain">) {</span>
<span class="identifier">scope_stage</span><span class="plain"> = </span><span class="constant">2</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">3</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" [Scope routine called at stage 2]^"</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="reserved">indirect</span><span class="plain">(</span><span class="identifier">scope_token</span><span class="plain">) ~= </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">rtrue</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">(b)</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">BeginActivity</span><span class="plain">(</span><span class="identifier">DECIDING_SCOPE_ACT</span><span class="plain">, </span><span class="identifier">actor</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ForActivity</span><span class="plain">(</span><span class="identifier">DECIDING_SCOPE_ACT</span><span class="plain">, </span><span class="identifier">actor</span><span class="plain">) == </span><span class="reserved">false</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="comment">(c.1)</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">scope_reason</span><span class="plain"> == </span><span class="identifier">PARSING_REASON</span><span class="plain">) &amp;&amp; (</span><span class="identifier">context</span><span class="plain"> == </span><span class="identifier">MULTIINSIDE_TOKEN</span><span class="plain">) &amp;&amp;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">(</span><span class="identifier">advance_warning</span><span class="plain"> ~= -1)) {</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">IsSeeThrough</span><span class="plain">(</span><span class="identifier">advance_warning</span><span class="plain">) == </span><span class="constant">1</span><span class="plain">)</span>
<span class="identifier">ScopeWithin</span><span class="plain">(</span><span class="identifier">advance_warning</span><span class="plain">, </span><span class="constant">0</span><span class="plain">, </span><span class="identifier">context</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
2020-04-07 03:06:09 +03:00
<span class="comment">(c.2)</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">scope_reason</span><span class="plain"> == </span><span class="identifier">PARSING_REASON</span><span class="plain">) &amp;&amp; (</span><span class="identifier">context</span><span class="plain"> ~= </span><span class="identifier">CREATURE_TOKEN</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">indef_mode</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">domain1</span><span class="plain"> == </span><span class="identifier">actors_location</span><span class="plain">))</span>
<span class="identifier">ScopeWithin</span><span class="plain">(</span><span class="identifier">Compass</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="comment">(c.3)</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">domain1</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">supporter</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">container</span><span class="plain">) </span><span class="identifier">DoScopeAction</span><span class="plain">(</span><span class="identifier">domain1</span><span class="plain">);</span>
<span class="identifier">ScopeWithin</span><span class="plain">(</span><span class="identifier">domain1</span><span class="plain">, </span><span class="identifier">domain2</span><span class="plain">, </span><span class="identifier">context</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="comment">(c.4)</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">domain2</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">domain2</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">supporter</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">container</span><span class="plain">) </span><span class="identifier">DoScopeAction</span><span class="plain">(</span><span class="identifier">domain2</span><span class="plain">);</span>
<span class="identifier">ScopeWithin</span><span class="plain">(</span><span class="identifier">domain2</span><span class="plain">, </span><span class="constant">0</span><span class="plain">, </span><span class="identifier">context</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">(c.5)</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">thedark</span><span class="plain"> == </span><span class="identifier">domain1</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">domain2</span><span class="plain">) {</span>
<span class="identifier">DoScopeActionAndRecurse</span><span class="plain">(</span><span class="identifier">actor</span><span class="plain">, </span><span class="identifier">actor</span><span class="plain">, </span><span class="identifier">context</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="reserved">parent</span><span class="plain">(</span><span class="identifier">actor</span><span class="plain">) </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">supporter</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">container</span><span class="plain">)</span>
<span class="identifier">DoScopeActionAndRecurse</span><span class="plain">(</span><span class="reserved">parent</span><span class="plain">(</span><span class="identifier">actor</span><span class="plain">), </span><span class="reserved">parent</span><span class="plain">(</span><span class="identifier">actor</span><span class="plain">), </span><span class="identifier">context</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">EndActivity</span><span class="plain">(</span><span class="identifier">DECIDING_SCOPE_ACT</span><span class="plain">, </span><span class="identifier">actor</span><span class="plain">);</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP48"></a><b>&#167;48. ScopeWithin. </b>Level 2. <code class="display"><span class="extract">ScopeWithin</span></code> puts objects visible from within the <code class="display"><span class="extract">domain</span></code> into scope.
An item belonging to the <code class="display"><span class="extract">domain</span></code> is placed in scope unless it is being
concealed by the <code class="display"><span class="extract">domain</span></code>: and even then, if the <code class="display"><span class="extract">domain</span></code> is the current
actor. Suppose Zorro conceals a book beneath his cloak: then the book is
not in scope to his lady friend The Black Whip, but it is in scope to Zorro
himself. (Thus an actor is not allowed to conceal anything from himself.)
</p>
<p class="inwebparagraph">Note that the <code class="display"><span class="extract">domain</span></code> object itself, and its component parts if any, are
not placed in scope by this routine, though nothing prevents some other
code doing so.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">ScopeWithin</span><span class="plain"> </span><span class="identifier">domain</span><span class="plain"> </span><span class="identifier">nosearch</span><span class="plain"> </span><span class="identifier">context</span><span class="plain"> </span><span class="identifier">obj</span><span class="plain"> </span><span class="identifier">next_obj</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">domain</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">rtrue</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Look through the objects in the domain, avoiding "objectloop" in case</span>
<span class="comment">movements occur.</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">obj</span><span class="plain"> = </span><span class="reserved">child</span><span class="plain">(</span><span class="identifier">domain</span><span class="plain">);</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain">) {</span>
<span class="identifier">next_obj</span><span class="plain"> = </span><span class="reserved">sibling</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">domain</span><span class="plain"> == </span><span class="identifier">actor</span><span class="plain">) || (</span><span class="identifier">TestConcealment</span><span class="plain">(</span><span class="identifier">domain</span><span class="plain">, </span><span class="identifier">obj</span><span class="plain">) == </span><span class="reserved">false</span><span class="plain">))</span>
<span class="identifier">DoScopeActionAndRecurse</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">, </span><span class="identifier">nosearch</span><span class="plain">, </span><span class="identifier">context</span><span class="plain">);</span>
<span class="identifier">obj</span><span class="plain"> = </span><span class="identifier">next_obj</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP49"></a><b>&#167;49. DoScopeActionAndRecurse. </b>Level 3.
In all cases, the <code class="display"><span class="extract">domain</span></code> itself is visited. There are then three possible
forms of recursion:
</p>
<ul class="items"><li>(a) To unconcealed objects which are inside, on top of, carried or worn by
the <code class="display"><span class="extract">domain</span></code>: this is called "searching" in traditional I6 language and
is suppressed if <code class="display"><span class="extract">domain</span></code> is the special value <code class="display"><span class="extract">nosearch</span></code>.
</li><li>(b) To unconcealed component parts of the <code class="display"><span class="extract">domain</span></code>.
</li><li>(c) To any other objects listed in the <code class="display"><span class="extract">add_to_scope</span></code> property array, or
supplied by the <code class="display"><span class="extract">add_to_scope</span></code> property routine, if it has one. (I7 does
not usually use <code class="display"><span class="extract">add_to_scope</span></code>, but it remains a useful hook in the parser,
so it retains its old I6 library interpretation.)
</li></ul>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">DoScopeActionAndRecurse</span><span class="plain"> </span><span class="identifier">domain</span><span class="plain"> </span><span class="identifier">nosearch</span><span class="plain"> </span><span class="identifier">context</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">ad</span><span class="plain"> </span><span class="identifier">n</span><span class="plain"> </span><span class="identifier">obj</span><span class="plain"> </span><span class="identifier">next_obj</span><span class="plain">;</span>
<span class="identifier">DoScopeAction</span><span class="plain">(</span><span class="identifier">domain</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="comment">(a)</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">domain</span><span class="plain"> ~= </span><span class="identifier">nosearch</span><span class="plain">) &amp;&amp;</span>
<span class="plain">((</span><span class="identifier">domain</span><span class="plain"> </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">K1_room</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">K8_person</span><span class="plain">) || (</span><span class="identifier">IsSeeThrough</span><span class="plain">(</span><span class="identifier">domain</span><span class="plain">) == </span><span class="constant">1</span><span class="plain">))) {</span>
<span class="identifier">obj</span><span class="plain"> = </span><span class="reserved">child</span><span class="plain">(</span><span class="identifier">domain</span><span class="plain">);</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain">) {</span>
<span class="identifier">next_obj</span><span class="plain"> = </span><span class="reserved">sibling</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">domain</span><span class="plain"> == </span><span class="identifier">actor</span><span class="plain">) || (</span><span class="identifier">TestConcealment</span><span class="plain">(</span><span class="identifier">domain</span><span class="plain">, </span><span class="identifier">obj</span><span class="plain">) == </span><span class="reserved">false</span><span class="plain">))</span>
<span class="identifier">DoScopeActionAndRecurse</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">, </span><span class="identifier">nosearch</span><span class="plain">, </span><span class="identifier">context</span><span class="plain">);</span>
<span class="identifier">obj</span><span class="plain"> = </span><span class="identifier">next_obj</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">(b)</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">domain</span><span class="plain"> </span><span class="reserved">provides</span><span class="plain"> </span><span class="identifier">component_child</span><span class="plain">) {</span>
<span class="identifier">obj</span><span class="plain"> = </span><span class="identifier">domain</span><span class="plain">.</span><span class="identifier">component_child</span><span class="plain">;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain">) {</span>
<span class="identifier">next_obj</span><span class="plain"> = </span><span class="identifier">obj</span><span class="plain">.</span><span class="identifier">component_sibling</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">domain</span><span class="plain"> == </span><span class="identifier">actor</span><span class="plain">) || (</span><span class="identifier">TestConcealment</span><span class="plain">(</span><span class="identifier">domain</span><span class="plain">, </span><span class="identifier">obj</span><span class="plain">) == </span><span class="reserved">false</span><span class="plain">))</span>
<span class="identifier">DoScopeActionAndRecurse</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">, </span><span class="constant">0</span><span class="plain">, </span><span class="identifier">context</span><span class="plain">);</span>
<span class="identifier">obj</span><span class="plain"> = </span><span class="identifier">next_obj</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">(c)</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">ad</span><span class="plain"> = </span><span class="identifier">domain</span><span class="plain">.&amp;</span><span class="identifier">add_to_scope</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ad</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Test if the property value is not an object.</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="identifier">i</span><span class="plain"> = (</span><span class="identifier">UnsignedCompare</span><span class="plain">(</span><span class="identifier">ad</span><span class="plain">--&gt;0, </span><span class="identifier">top_object</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Ifnot</span><span class="plain">; </span><span class="comment">TARGET_GLULX</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">i</span><span class="plain"> = (((</span><span class="identifier">ad</span><span class="plain">--&gt;0)-&gt;0) ~= </span><span class="constant">$70</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">TARGET_</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">) {</span>
<span class="identifier">ats_flag</span><span class="plain"> = </span><span class="constant">2</span><span class="plain">+</span><span class="identifier">context</span><span class="plain">;</span>
<span class="identifier">RunRoutines</span><span class="plain">(</span><span class="identifier">domain</span><span class="plain">, </span><span class="identifier">add_to_scope</span><span class="plain">);</span>
<span class="identifier">ats_flag</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">n</span><span class="plain"> = </span><span class="identifier">domain</span><span class="plain">.#</span><span class="identifier">add_to_scope</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0 : (</span><span class="identifier">WORDSIZE</span><span class="plain">*</span><span class="identifier">i</span><span class="plain">)&lt;</span><span class="identifier">n</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ad</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">)</span>
<span class="identifier">DoScopeActionAndRecurse</span><span class="plain">(</span><span class="identifier">ad</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">, </span><span class="constant">0</span><span class="plain">, </span><span class="identifier">context</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP50"></a><b>&#167;50. DoScopeAction. </b>Level 4. This is where we take whatever action is to be performed as the
"visit" to each scoped object, and it's the bottom at last of the scope
mechanism.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">DoScopeAction</span><span class="plain"> </span><span class="identifier">item</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">6</span><span class="plain">)</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"[DSA on "</span><span class="plain">, (</span><span class="identifier">the</span><span class="plain">) </span><span class="identifier">item</span><span class="plain">, </span><span class="string">" with reason = "</span><span class="plain">, </span><span class="identifier">scope_reason</span><span class="plain">,</span>
<span class="string">" p1 = "</span><span class="plain">, </span><span class="identifier">parser_one</span><span class="plain">, </span><span class="string">" p2 = "</span><span class="plain">, </span><span class="identifier">parser_two</span><span class="plain">, </span><span class="string">"]^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="plain">@</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">parser_one</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">scope_reason</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">scope_reason</span><span class="plain">) {</span>
<span class="identifier">TESTSCOPE_REASON</span><span class="plain">: </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">item</span><span class="plain"> == </span><span class="identifier">parser_one</span><span class="plain">) </span><span class="identifier">parser_two</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="identifier">LOOPOVERSCOPE_REASON</span><span class="plain">: </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_one</span><span class="plain"> </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">Routine</span><span class="plain">) </span><span class="reserved">indirect</span><span class="plain">(</span><span class="identifier">parser_one</span><span class="plain">, </span><span class="identifier">item</span><span class="plain">);</span>
<span class="identifier">PARSING_REASON</span><span class="plain">, </span><span class="identifier">TALKING_REASON</span><span class="plain">: </span><span class="identifier">MatchTextAgainstObject</span><span class="plain">(</span><span class="identifier">item</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="plain">@</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">scope_reason</span><span class="plain">; @</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">parser_one</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP51"></a><b>&#167;51. Parsing Object Names. </b>We now reach the final major block of code in the parser: the part which tries
to match a given object's name(s) against the text at word position <code class="display"><span class="extract">match_from</span></code>
in the player's command, and calls <code class="display"><span class="extract">MakeMatch</span></code> if it succeeds. There are
basically four possibilities: ME, a pronoun such as IT, a name which doesn't
begin misleadingly with a number, and a name which does. In the latter two
cases, we pass the job down to <code class="display"><span class="extract">TryGivenObject</span></code>.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">MatchTextAgainstObject</span><span class="plain"> </span><span class="identifier">item</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">token_filter</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain"> &amp;&amp; </span><span class="identifier">ConsultNounFilterToken</span><span class="plain">(</span><span class="identifier">item</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">match_from</span><span class="plain"> &lt;= </span><span class="identifier">num_words</span><span class="plain">) { </span><span class="comment">If there's any text to match, that is</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">match_from</span><span class="plain">;</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">NounWord</span><span class="plain">();</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">i</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) &amp;&amp; (</span><span class="identifier">player</span><span class="plain"> == </span><span class="identifier">item</span><span class="plain">)) </span><span class="identifier">MakeMatch</span><span class="plain">(</span><span class="identifier">item</span><span class="plain">, </span><span class="constant">1</span><span class="plain">); </span><span class="comment">"me"</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">i</span><span class="plain"> &gt;= </span><span class="constant">2</span><span class="plain">) &amp;&amp; (</span><span class="identifier">i</span><span class="plain"> &lt; </span><span class="constant">128</span><span class="plain">) &amp;&amp; (</span><span class="identifier">LanguagePronouns</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> == </span><span class="identifier">item</span><span class="plain">)) </span><span class="identifier">MakeMatch</span><span class="plain">(</span><span class="identifier">item</span><span class="plain">, </span><span class="constant">1</span><span class="plain">);</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">Construing the current word as the start of a noun, can it refer to the</span>
<span class="comment">object?</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">match_from</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TryGivenObject</span><span class="plain">(</span><span class="identifier">item</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_nspec_at</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain"> &amp;&amp; </span><span class="identifier">match_from</span><span class="plain"> ~= </span><span class="identifier">indef_nspec_at</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="comment">This case arises if the player has typed a number in</span>
<span class="comment">which is hypothetically an indefinite descriptor:</span>
<span class="comment">e.g. "take two clubs". We have just checked the object</span>
<span class="comment">against the word "clubs", in the hope of eventually finding</span>
<span class="comment">two such objects. But we also backtrack and check it</span>
<span class="comment">against the words "two clubs", in case it turns out to</span>
<span class="comment">be the 2 of Clubs from a pack of cards, say. If it does</span>
<span class="comment">match against "two clubs", we tear up our original</span>
<span class="comment">assumption about the meaning of "two" and lapse back into</span>
<span class="comment">definite mode.</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">indef_nspec_at</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TryGivenObject</span><span class="plain">(</span><span class="identifier">item</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">match_from</span><span class="plain"> = </span><span class="identifier">indef_nspec_at</span><span class="plain">;</span>
<span class="identifier">ResetDescriptors</span><span class="plain">();</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">match_from</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP52"></a><b>&#167;52. TryGivenObject. </b><code class="display"><span class="extract">TryGivenObject</span></code> tries to match as many words as possible in what has been
typed to the given object, <code class="display"><span class="extract">obj</span></code>. If it manages any words matched at all,
it calls <code class="display"><span class="extract">MakeMatch</span></code> to say so, then returns the number of words (or 1
if it was a match because of inadequate input).
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">TryGivenObject</span><span class="plain"> </span><span class="identifier">obj</span><span class="plain"> </span><span class="identifier">nomatch</span><span class="plain"> </span><span class="identifier">threshold</span><span class="plain"> </span><span class="identifier">k</span><span class="plain"> </span><span class="identifier">w</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">5</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" Trying "</span><span class="plain">, (</span><span class="identifier">the</span><span class="plain">) </span><span class="identifier">obj</span><span class="plain">, </span><span class="string">" ("</span><span class="plain">, </span><span class="identifier">obj</span><span class="plain">, </span><span class="string">") at word "</span><span class="plain">, </span><span class="identifier">wn</span><span class="plain">, </span><span class="string">"^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nomatch</span><span class="plain"> &amp;&amp; </span><span class="identifier">obj</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">if (nomatch) print "*** TryGivenObject *** on ", (the) obj, " at wn = ", wn, "^";</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">dict_flags_of_noun</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
2020-04-14 19:56:54 +03:00
<span class="comment"> If input has run out then always match, with only quality 0 (this saves</span>
<span class="comment"> time).</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wn</span><span class="plain"> &gt; </span><span class="identifier">num_words</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nomatch</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_mode</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">)</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">dict_flags_of_noun</span><span class="plain"> = </span><span class="constant">$$01110000</span><span class="plain">; </span><span class="comment">Reject "plural" bit</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">MakeMatch</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">,0);</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">5</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" Matched (0)^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="constant">1</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-14 19:56:54 +03:00
<span class="comment"> Ask the object to parse itself if necessary, sitting up and taking notice</span>
<span class="comment"> if it says the plural was used:</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain">.</span><span class="identifier">parse_name</span><span class="plain">~=0) {</span>
<span class="identifier">parser_action</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">j</span><span class="plain">=</span><span class="identifier">wn</span><span class="plain">;</span>
<span class="identifier">k</span><span class="plain"> = </span><span class="identifier">RunRoutines</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">,</span><span class="identifier">parse_name</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">k</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">wn</span><span class="plain">=</span><span class="identifier">j</span><span class="plain">+</span><span class="identifier">k</span><span class="plain">;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> .</span><span class="identifier">MMbyPN</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_action</span><span class="plain"> == ##</span><span class="identifier">PluralFound</span><span class="plain">)</span>
<span class="identifier">dict_flags_of_noun</span><span class="plain"> = </span><span class="identifier">dict_flags_of_noun</span><span class="plain"> | </span><span class="constant">4</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dict_flags_of_noun</span><span class="plain"> &amp; </span><span class="constant">4</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (~~</span><span class="identifier">allow_plurals</span><span class="plain">) </span><span class="identifier">k</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_mode</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">indef_mode</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="identifier">indef_type</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">indef_wanted</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">indef_type</span><span class="plain"> = </span><span class="identifier">indef_type</span><span class="plain"> | </span><span class="identifier">PLURAL_BIT</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_wanted</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">indef_wanted</span><span class="plain"> = </span><span class="identifier">INDEF_ALL_WANTED</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">DEBUG</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_trace</span><span class="plain"> &gt;= </span><span class="constant">5</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" Matched ("</span><span class="plain">, </span><span class="identifier">k</span><span class="plain">, </span><span class="string">")^"</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">DEBUG</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nomatch</span><span class="plain"> == </span><span class="reserved">false</span><span class="plain">) </span><span class="identifier">MakeMatch</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">,</span><span class="identifier">k</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">k</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">NoWordsMatch</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="comment">The default algorithm is simply to count up how many words pass the</span>
<span class="comment">Refers test:</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">parser_action</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">w</span><span class="plain"> = </span><span class="identifier">NounWord</span><span class="plain">();</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">w</span><span class="plain"> == </span><span class="constant">1</span><span class="plain"> &amp;&amp; </span><span class="identifier">player</span><span class="plain"> == </span><span class="identifier">obj</span><span class="plain">) { </span><span class="identifier">k</span><span class="plain">=1; </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">MMbyPN</span><span class="plain">; }</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">w</span><span class="plain"> &gt;= </span><span class="constant">2</span><span class="plain"> &amp;&amp; </span><span class="identifier">w</span><span class="plain"> &lt; </span><span class="constant">128</span><span class="plain"> &amp;&amp; (</span><span class="identifier">LanguagePronouns</span><span class="plain">--&gt;</span><span class="identifier">w</span><span class="plain"> == </span><span class="identifier">obj</span><span class="plain">)) { </span><span class="identifier">k</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">MMbyPN</span><span class="plain">; }</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Refers</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">, </span><span class="identifier">wn</span><span class="plain">-1) == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="plain">.</span><span class="identifier">NoWordsMatch</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indef_mode</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain">) { </span><span class="identifier">k</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">parser_action</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">MMbyPN</span><span class="plain">; }</span>
<span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">threshold</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="identifier">dict_flags_of_noun</span><span class="plain"> = (</span><span class="identifier">w</span><span class="plain">-&gt;#</span><span class="identifier">dict_par1</span><span class="plain">) &amp; </span><span class="constant">$$01110100</span><span class="plain">;</span>
<span class="identifier">w</span><span class="plain"> = </span><span class="identifier">NextWord</span><span class="plain">();</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Refers</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">, </span><span class="identifier">wn</span><span class="plain">-1)) {</span>
<span class="identifier">threshold</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">w</span><span class="plain">)</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> </span><span class="identifier">dict_flags_of_noun</span><span class="plain"> = </span><span class="identifier">dict_flags_of_noun</span><span class="plain"> | ((</span><span class="identifier">w</span><span class="plain">-&gt;#</span><span class="identifier">dict_par1</span><span class="plain">) &amp; </span><span class="constant">$$01110100</span><span class="plain">);</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">w</span><span class="plain"> = </span><span class="identifier">NextWord</span><span class="plain">();</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">k</span><span class="plain"> = </span><span class="identifier">threshold</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">MMbyPN</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP53"></a><b>&#167;53. Refers. </b><code class="display"><span class="extract">Refers</span></code> works out whether the word at number wnum can refer to the object
<code class="display"><span class="extract">obj</span></code>, returning true or false. The standard method is to see if the word
is listed under the <code class="display"><span class="extract">name</span></code> property for the object, but this is more
complex in languages other than English.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">Refers</span><span class="plain"> </span><span class="identifier">obj</span><span class="plain"> </span><span class="identifier">wnum</span><span class="plain"> </span><span class="identifier">wd</span><span class="plain"> </span><span class="identifier">k</span><span class="plain"> </span><span class="identifier">l</span><span class="plain"> </span><span class="identifier">m</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">rfalse</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">LanguageRefers</span><span class="plain">;</span>
<span class="identifier">k</span><span class="plain"> = </span><span class="identifier">LanguageRefers</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">,</span><span class="identifier">wnum</span><span class="plain">); </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">k</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">LanguageRefers</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">k</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">; </span><span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">wnum</span><span class="plain">; </span><span class="identifier">wd</span><span class="plain"> = </span><span class="identifier">NextWordStopped</span><span class="plain">(); </span><span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">k</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parser_inflection</span><span class="plain"> &gt;= </span><span class="constant">256</span><span class="plain">) {</span>
<span class="identifier">k</span><span class="plain"> = </span><span class="reserved">indirect</span><span class="plain">(</span><span class="identifier">parser_inflection</span><span class="plain">, </span><span class="identifier">obj</span><span class="plain">, </span><span class="identifier">wd</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">k</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">m</span><span class="plain"> = -</span><span class="identifier">k</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">else</span>
<span class="identifier">m</span><span class="plain"> = </span><span class="identifier">parser_inflection</span><span class="plain">;</span>
<span class="identifier">k</span><span class="plain"> = </span><span class="identifier">obj</span><span class="plain">.&amp;</span><span class="identifier">m</span><span class="plain">; </span><span class="identifier">l</span><span class="plain"> = (</span><span class="identifier">obj</span><span class="plain">.#</span><span class="identifier">m</span><span class="plain">)/</span><span class="identifier">WORDSIZE</span><span class="plain">-1;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">m</span><span class="plain">=0 : </span><span class="identifier">m</span><span class="plain">&lt;=</span><span class="identifier">l</span><span class="plain"> : </span><span class="identifier">m</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wd</span><span class="plain"> == </span><span class="identifier">k</span><span class="plain">--&gt;</span><span class="identifier">m</span><span class="plain">) </span><span class="reserved">rtrue</span><span class="plain">;</span>
<span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">WordInProperty</span><span class="plain"> </span><span class="identifier">wd</span><span class="plain"> </span><span class="identifier">obj</span><span class="plain"> </span><span class="identifier">prop</span><span class="plain"> </span><span class="identifier">k</span><span class="plain"> </span><span class="identifier">l</span><span class="plain"> </span><span class="identifier">m</span><span class="plain">;</span>
<span class="identifier">k</span><span class="plain"> = </span><span class="identifier">obj</span><span class="plain">.&amp;</span><span class="identifier">prop</span><span class="plain">; </span><span class="identifier">l</span><span class="plain"> = (</span><span class="identifier">obj</span><span class="plain">.#</span><span class="identifier">prop</span><span class="plain">)/</span><span class="identifier">WORDSIZE</span><span class="plain">-1;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">m</span><span class="plain">=0 : </span><span class="identifier">m</span><span class="plain">&lt;=</span><span class="identifier">l</span><span class="plain"> : </span><span class="identifier">m</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wd</span><span class="plain"> == </span><span class="identifier">k</span><span class="plain">--&gt;</span><span class="identifier">m</span><span class="plain">) </span><span class="reserved">rtrue</span><span class="plain">;</span>
<span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP54"></a><b>&#167;54. NounWord. </b><code class="display"><span class="extract">NounWord</span></code> (which takes no arguments) returns:
</p>
<ul class="items"><li>(a) 0 if the next word is not in the dictionary or is but does not carry the
"noun" bit in its dictionary entry,
</li><li>(b) 1 if it is a word meaning "me",
</li><li>(c) the index in the pronoun table (plus 2) of the value field of a pronoun,
if it is a pronoun,
</li><li>(d) the address in the dictionary if it is a recognised noun.
</li></ul>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">NounWord</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">j</span><span class="plain"> </span><span class="identifier">s</span><span class="plain">;</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">NextWord</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">rfalse</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="identifier">ME1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">ME2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">ME3__WD</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">1</span><span class="plain">;</span>
<span class="identifier">s</span><span class="plain"> = </span><span class="identifier">LanguagePronouns</span><span class="plain">--&gt;0;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=1 : </span><span class="identifier">j</span><span class="plain">&lt;=</span><span class="identifier">s</span><span class="plain"> : </span><span class="identifier">j</span><span class="plain">=</span><span class="identifier">j</span><span class="plain">+3)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="identifier">LanguagePronouns</span><span class="plain">--&gt;</span><span class="identifier">j</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">+2;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">i</span><span class="plain">-&gt;#</span><span class="identifier">dict_par1</span><span class="plain">)&amp;128 == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">rfalse</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP55"></a><b>&#167;55. TryNumber. </b><code class="display"><span class="extract">TryNumber</span></code> takes word number <code class="display"><span class="extract">wordnum</span></code> and tries to parse it as an (unsigned)
decimal number or the name of a small number, returning
</p>
<p class="inwebparagraph"></p>
2020-04-14 19:56:54 +03:00
<ul class="items"><li>(a) \(-1000\) if it is not a number
</li><li>(b) the number, if it has between 1 and 4 digits
</li><li>(c) 10000 if it has 5 or more digits.
</li></ul>
<p class="inwebparagraph">(The danger of allowing 5 digits is that Z-machine integers are only 16 bits
long, and anyway this routine isn't meant to be perfect: it only really needs
to be good enough to handle numeric descriptors such as those in TAKE 31 COINS
or DROP FOUR DAGGERS. In particular, it is not the way I7 "[number]" tokens
are parsed.)
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">TryNumber</span><span class="plain"> </span><span class="identifier">wordnum</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">j</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> </span><span class="identifier">num</span><span class="plain"> </span><span class="identifier">len</span><span class="plain"> </span><span class="identifier">mul</span><span class="plain"> </span><span class="identifier">tot</span><span class="plain"> </span><span class="identifier">d</span><span class="plain"> </span><span class="identifier">digit</span><span class="plain">;</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">; </span><span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">wordnum</span><span class="plain">; </span><span class="identifier">j</span><span class="plain"> = </span><span class="identifier">NextWord</span><span class="plain">(); </span><span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">j</span><span class="plain"> = </span><span class="identifier">NumberWord</span><span class="plain">(</span><span class="identifier">j</span><span class="plain">); </span><span class="comment">Test for verbal forms ONE to THIRTY</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain"> &gt;= </span><span class="constant">1</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">wordnum</span><span class="plain">*4+1; </span><span class="identifier">j</span><span class="plain"> = </span><span class="identifier">parse</span><span class="plain">-&gt;</span><span class="identifier">i</span><span class="plain">; </span><span class="identifier">num</span><span class="plain"> = </span><span class="identifier">j</span><span class="plain">+</span><span class="identifier">buffer</span><span class="plain">; </span><span class="identifier">len</span><span class="plain"> = </span><span class="identifier">parse</span><span class="plain">-&gt;(</span><span class="identifier">i</span><span class="plain">-1);</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Ifnot</span><span class="plain">; </span><span class="comment">TARGET_GLULX</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">wordnum</span><span class="plain">*3; </span><span class="identifier">j</span><span class="plain"> = </span><span class="identifier">parse</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">; </span><span class="identifier">num</span><span class="plain"> = </span><span class="identifier">j</span><span class="plain">+</span><span class="identifier">buffer</span><span class="plain">; </span><span class="identifier">len</span><span class="plain"> = </span><span class="identifier">parse</span><span class="plain">--&gt;(</span><span class="identifier">i</span><span class="plain">-1);</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">TARGET_</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">len</span><span class="plain"> &gt;= </span><span class="constant">4</span><span class="plain">) </span><span class="identifier">mul</span><span class="plain">=1000;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">len</span><span class="plain"> == </span><span class="constant">3</span><span class="plain">) </span><span class="identifier">mul</span><span class="plain">=100;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">len</span><span class="plain"> == </span><span class="constant">2</span><span class="plain">) </span><span class="identifier">mul</span><span class="plain">=10;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">len</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) </span><span class="identifier">mul</span><span class="plain">=1;</span>
<span class="identifier">tot</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">c</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">len</span><span class="plain"> = </span><span class="identifier">len</span><span class="plain">-1;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain">=0 : </span><span class="identifier">c</span><span class="plain">&lt;=</span><span class="identifier">len</span><span class="plain"> : </span><span class="identifier">c</span><span class="plain">++) {</span>
<span class="identifier">digit</span><span class="plain">=</span><span class="identifier">num</span><span class="plain">-&gt;</span><span class="identifier">c</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">digit</span><span class="plain"> == </span><span class="character">'0'</span><span class="plain">) { </span><span class="identifier">d</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">digok</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">digit</span><span class="plain"> == </span><span class="character">'1'</span><span class="plain">) { </span><span class="identifier">d</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">digok</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">digit</span><span class="plain"> == </span><span class="character">'2'</span><span class="plain">) { </span><span class="identifier">d</span><span class="plain"> = </span><span class="constant">2</span><span class="plain">; </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">digok</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">digit</span><span class="plain"> == </span><span class="character">'3'</span><span class="plain">) { </span><span class="identifier">d</span><span class="plain"> = </span><span class="constant">3</span><span class="plain">; </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">digok</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">digit</span><span class="plain"> == </span><span class="character">'4'</span><span class="plain">) { </span><span class="identifier">d</span><span class="plain"> = </span><span class="constant">4</span><span class="plain">; </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">digok</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">digit</span><span class="plain"> == </span><span class="character">'5'</span><span class="plain">) { </span><span class="identifier">d</span><span class="plain"> = </span><span class="constant">5</span><span class="plain">; </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">digok</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">digit</span><span class="plain"> == </span><span class="character">'6'</span><span class="plain">) { </span><span class="identifier">d</span><span class="plain"> = </span><span class="constant">6</span><span class="plain">; </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">digok</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">digit</span><span class="plain"> == </span><span class="character">'7'</span><span class="plain">) { </span><span class="identifier">d</span><span class="plain"> = </span><span class="constant">7</span><span class="plain">; </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">digok</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">digit</span><span class="plain"> == </span><span class="character">'8'</span><span class="plain">) { </span><span class="identifier">d</span><span class="plain"> = </span><span class="constant">8</span><span class="plain">; </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">digok</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">digit</span><span class="plain"> == </span><span class="character">'9'</span><span class="plain">) { </span><span class="identifier">d</span><span class="plain"> = </span><span class="constant">9</span><span class="plain">; </span><span class="reserved">jump</span><span class="plain"> </span><span class="identifier">digok</span><span class="plain">; }</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">return</span><span class="plain"> -1000;</span>
2020-04-08 01:02:44 +03:00
<span class="plain"> .</span><span class="identifier">digok</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">tot</span><span class="plain"> = </span><span class="identifier">tot</span><span class="plain">+</span><span class="identifier">mul</span><span class="plain">*</span><span class="identifier">d</span><span class="plain">; </span><span class="identifier">mul</span><span class="plain"> = </span><span class="identifier">mul</span><span class="plain">/10;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">len</span><span class="plain"> &gt; </span><span class="constant">3</span><span class="plain">) </span><span class="identifier">tot</span><span class="plain">=10000;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">tot</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP56"></a><b>&#167;56. Gender. </b><code class="display"><span class="extract">GetGender</span></code> returns 0 if the given animate object is female, and 1 if male,
and is abstracted as a routine in case something more elaborate is ever
needed.
</p>
2020-04-14 19:56:54 +03:00
<p class="inwebparagraph">For GNAs &mdash; gender/noun/animation combinations &mdash; see the {\it Inform Designer's
Manual}, 4th edition.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">GetGender</span><span class="plain"> </span><span class="identifier">person</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">person</span><span class="plain"> </span><span class="reserved">hasnt</span><span class="plain"> </span><span class="identifier">female</span><span class="plain">) </span><span class="reserved">rtrue</span><span class="plain">;</span>
<span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">GetGNAOfObject</span><span class="plain"> </span><span class="identifier">obj</span><span class="plain"> </span><span class="identifier">case</span><span class="plain"> </span><span class="identifier">gender</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain"> </span><span class="reserved">hasnt</span><span class="plain"> </span><span class="identifier">animate</span><span class="plain">) </span><span class="identifier">case</span><span class="plain"> = </span><span class="constant">6</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">male</span><span class="plain">) </span><span class="identifier">gender</span><span class="plain"> = </span><span class="identifier">male</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">female</span><span class="plain">) </span><span class="identifier">gender</span><span class="plain"> = </span><span class="identifier">female</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">neuter</span><span class="plain">) </span><span class="identifier">gender</span><span class="plain"> = </span><span class="identifier">neuter</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gender</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">case</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">gender</span><span class="plain"> = </span><span class="identifier">LanguageAnimateGender</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">gender</span><span class="plain"> = </span><span class="identifier">LanguageInanimateGender</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gender</span><span class="plain"> == </span><span class="identifier">female</span><span class="plain">) </span><span class="identifier">case</span><span class="plain"> = </span><span class="identifier">case</span><span class="plain"> + </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gender</span><span class="plain"> == </span><span class="identifier">neuter</span><span class="plain">) </span><span class="identifier">case</span><span class="plain"> = </span><span class="identifier">case</span><span class="plain"> + </span><span class="constant">2</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">pluralname</span><span class="plain">) </span><span class="identifier">case</span><span class="plain"> = </span><span class="identifier">case</span><span class="plain"> + </span><span class="constant">3</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">case</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP57"></a><b>&#167;57. Noticing Plurals. </b></p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">DetectPluralWord</span><span class="plain"> </span><span class="identifier">at</span><span class="plain"> </span><span class="identifier">n</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">w</span><span class="plain"> </span><span class="identifier">swn</span><span class="plain"> </span><span class="identifier">outcome</span><span class="plain">;</span>
<span class="identifier">swn</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">; </span><span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">at</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0:</span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">n</span><span class="plain">:</span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">w</span><span class="plain"> = </span><span class="identifier">NextWordStopped</span><span class="plain">();</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">w</span><span class="plain"> == </span><span class="constant">0</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">THEN1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">COMMA_WORD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> -1) </span><span class="reserved">break</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">w</span><span class="plain">-&gt;#</span><span class="identifier">dict_par1</span><span class="plain">) &amp; </span><span class="constant">$$00000100</span><span class="plain">) {</span>
<span class="identifier">parser_action</span><span class="plain"> = ##</span><span class="identifier">PluralFound</span><span class="plain">;</span>
<span class="identifier">outcome</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">swn</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">outcome</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP58"></a><b>&#167;58. Pronoun Handling. </b></p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">SetPronoun</span><span class="plain"> </span><span class="identifier">dword</span><span class="plain"> </span><span class="identifier">value</span><span class="plain"> </span><span class="identifier">x</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">x</span><span class="plain">=1 : </span><span class="identifier">x</span><span class="plain">&lt;=</span><span class="identifier">LanguagePronouns</span><span class="plain">--&gt;0 : </span><span class="identifier">x</span><span class="plain">=</span><span class="identifier">x</span><span class="plain">+3)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">LanguagePronouns</span><span class="plain">--&gt;</span><span class="identifier">x</span><span class="plain"> == </span><span class="identifier">dword</span><span class="plain">) {</span>
<span class="identifier">LanguagePronouns</span><span class="plain">--&gt;(</span><span class="identifier">x</span><span class="plain">+2) = </span><span class="identifier">value</span><span class="plain">; </span><span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">RunTimeError</span><span class="plain">(14);</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">PronounValue</span><span class="plain"> </span><span class="identifier">dword</span><span class="plain"> </span><span class="identifier">x</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">x</span><span class="plain">=1 : </span><span class="identifier">x</span><span class="plain">&lt;=</span><span class="identifier">LanguagePronouns</span><span class="plain">--&gt;0 : </span><span class="identifier">x</span><span class="plain">=</span><span class="identifier">x</span><span class="plain">+3)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">LanguagePronouns</span><span class="plain">--&gt;</span><span class="identifier">x</span><span class="plain"> == </span><span class="identifier">dword</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">LanguagePronouns</span><span class="plain">--&gt;(</span><span class="identifier">x</span><span class="plain">+2);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">ResetVagueWords</span><span class="plain"> </span><span class="identifier">obj</span><span class="plain">; </span><span class="identifier">PronounNotice</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">); ];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">PronounNotice</span><span class="plain"> </span><span class="identifier">obj</span><span class="plain"> </span><span class="identifier">x</span><span class="plain"> </span><span class="identifier">bm</span><span class="plain"> </span><span class="identifier">g</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain"> == </span><span class="identifier">player</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">g</span><span class="plain"> = (</span><span class="identifier">GetGNAOfObject</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">));</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">bm</span><span class="plain"> = </span><span class="identifier">PowersOfTwo_TB</span><span class="plain">--&gt;</span><span class="identifier">g</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">x</span><span class="plain">=1 : </span><span class="identifier">x</span><span class="plain">&lt;=</span><span class="identifier">LanguagePronouns</span><span class="plain">--&gt;0 : </span><span class="identifier">x</span><span class="plain">=</span><span class="identifier">x</span><span class="plain">+3)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bm</span><span class="plain"> &amp; (</span><span class="identifier">LanguagePronouns</span><span class="plain">--&gt;(</span><span class="identifier">x</span><span class="plain">+1)) ~= </span><span class="constant">0</span><span class="plain">)</span>
<span class="identifier">LanguagePronouns</span><span class="plain">--&gt;(</span><span class="identifier">x</span><span class="plain">+2) = </span><span class="identifier">obj</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (((</span><span class="identifier">g</span><span class="plain"> % </span><span class="constant">6</span><span class="plain">) &lt; </span><span class="constant">3</span><span class="plain">) &amp;&amp; (</span><span class="identifier">obj</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">ambigpluralname</span><span class="plain">)) {</span>
<span class="identifier">g</span><span class="plain"> = </span><span class="identifier">g</span><span class="plain"> + </span><span class="constant">3</span><span class="plain">;</span>
<span class="identifier">bm</span><span class="plain"> = </span><span class="identifier">PowersOfTwo_TB</span><span class="plain">--&gt;</span><span class="identifier">g</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">x</span><span class="plain">=1 : </span><span class="identifier">x</span><span class="plain">&lt;=</span><span class="identifier">LanguagePronouns</span><span class="plain">--&gt;0 : </span><span class="identifier">x</span><span class="plain">=</span><span class="identifier">x</span><span class="plain">+3)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bm</span><span class="plain"> &amp; (</span><span class="identifier">LanguagePronouns</span><span class="plain">--&gt;(</span><span class="identifier">x</span><span class="plain">+1)) ~= </span><span class="constant">0</span><span class="plain">)</span>
<span class="identifier">LanguagePronouns</span><span class="plain">--&gt;(</span><span class="identifier">x</span><span class="plain">+2) = </span><span class="identifier">obj</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">PronounNoticeHeldObjects</span><span class="plain"> </span><span class="identifier">x</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">IFNDEF</span><span class="plain"> </span><span class="identifier">MANUAL_PRONOUNS</span><span class="plain">;</span>
<span class="reserved">objectloop</span><span class="plain">(</span><span class="identifier">x</span><span class="plain"> </span><span class="reserved">in</span><span class="plain"> </span><span class="identifier">player</span><span class="plain">) </span><span class="identifier">PronounNotice</span><span class="plain">(</span><span class="identifier">x</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">ENDIF</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">x</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="comment">To prevent a "not used" error</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP59"></a><b>&#167;59. Yes/No Questions. </b></p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">YesOrNo</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (::) {</span>
<span class="plain">#</span><span class="identifier">Ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">location</span><span class="plain"> == </span><span class="reserved">nothing</span><span class="plain"> || </span><span class="reserved">parent</span><span class="plain">(</span><span class="identifier">player</span><span class="plain">) == </span><span class="reserved">nothing</span><span class="plain">) </span><span class="reserved">read</span><span class="plain"> </span><span class="identifier">buffer2</span><span class="plain"> </span><span class="identifier">parse2</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">read</span><span class="plain"> </span><span class="identifier">buffer2</span><span class="plain"> </span><span class="identifier">parse2</span><span class="plain"> </span><span class="identifier">DrawStatusLine</span><span class="plain">;</span>
<span class="identifier">j</span><span class="plain"> = </span><span class="identifier">parse2</span><span class="plain">-&gt;1;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Ifnot</span><span class="plain">; </span><span class="comment">TARGET_GLULX;</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">location</span><span class="plain"> ~= </span><span class="reserved">nothing</span><span class="plain"> &amp;&amp; </span><span class="reserved">parent</span><span class="plain">(</span><span class="identifier">player</span><span class="plain">) ~= </span><span class="reserved">nothing</span><span class="plain">) </span><span class="identifier">DrawStatusLine</span><span class="plain">();</span>
<span class="identifier">KeyboardPrimitive</span><span class="plain">(</span><span class="identifier">buffer2</span><span class="plain">, </span><span class="identifier">parse2</span><span class="plain">);</span>
<span class="identifier">j</span><span class="plain"> = </span><span class="identifier">parse2</span><span class="plain">--&gt;0;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">#</span><span class="identifier">Endif</span><span class="plain">; </span><span class="comment">TARGET_</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">) { </span><span class="comment">at least one word entered</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">parse2</span><span class="plain">--&gt;1;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="identifier">YES1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">YES2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">YES3__WD</span><span class="plain">) </span><span class="reserved">rtrue</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="identifier">NO1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">NO2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">NO3__WD</span><span class="plain">) </span><span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">YES_OR_NO_QUESTION_INTERNAL_RM</span><span class="plain">(</span><span class="character">'A'</span><span class="plain">); </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"&gt; "</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">YES_OR_NO_QUESTION_INTERNAL_R</span><span class="plain">; ];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP60"></a><b>&#167;60. Number Words. </b>Not much of a parsing routine: we look through an array of pairs of number
words (single words) and their numeric equivalents.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">NumberWord</span><span class="plain"> </span><span class="identifier">o</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">n</span><span class="plain">;</span>
<span class="identifier">n</span><span class="plain"> = </span><span class="identifier">LanguageNumbers</span><span class="plain">--&gt;0;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=1 : </span><span class="identifier">i</span><span class="plain">&lt;=</span><span class="identifier">n</span><span class="plain"> : </span><span class="identifier">i</span><span class="plain">=</span><span class="identifier">i</span><span class="plain">+2)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">o</span><span class="plain"> == </span><span class="identifier">LanguageNumbers</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">LanguageNumbers</span><span class="plain">--&gt;(</span><span class="identifier">i</span><span class="plain">+1);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP61"></a><b>&#167;61. Choose Objects. </b>This material, the final body of code in the parser, is an I7 addition.
The I6 parser leaves it to the user to provide a <code class="display"><span class="extract">ChooseObjects</span></code> routine
to decide between possibilities when the situation is ambiguous. For I7
use, we provide a <code class="display"><span class="extract">ChooseObjects</span></code> which essentially runs the "does the
player mean" rulebook to decide, though this is not obvious from the
code below because it is hidden in the <code class="display"><span class="extract">CheckDPMR</span></code> routine &mdash; which
is defined in the Standard Rules, not here.
</p>
<pre class="display">
2020-04-07 03:06:09 +03:00
<span class="comment">onstant COBJ_DEBUG;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">the highest value returned by CheckDPMR (see the Standard Rules)</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">HIGHEST_DPMR_SCORE</span><span class="plain"> = </span><span class="constant">4</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">alt_match_list</span><span class="plain"> --&gt; (</span><span class="identifier">MATCH_LIST_WORDS</span><span class="plain">+1);</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">TARGET_GLULX</span><span class="plain">;</span>
<span class="plain">[ </span><span class="identifier">COBJ__Copy</span><span class="plain"> </span><span class="identifier">words</span><span class="plain"> </span><span class="identifier">from</span><span class="plain"> </span><span class="reserved">to</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0: </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">words</span><span class="plain">: </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">to</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">from</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">ifnot</span><span class="plain">;</span>
<span class="plain">[ </span><span class="identifier">COBJ__Copy</span><span class="plain"> </span><span class="identifier">words</span><span class="plain"> </span><span class="identifier">from</span><span class="plain"> </span><span class="reserved">to</span><span class="plain"> </span><span class="identifier">bytes</span><span class="plain">;</span>
<span class="identifier">bytes</span><span class="plain"> = </span><span class="identifier">words</span><span class="plain"> * </span><span class="constant">2</span><span class="plain">;</span>
<span class="plain">@</span><span class="identifier">copy_table</span><span class="plain"> </span><span class="identifier">from</span><span class="plain"> </span><span class="reserved">to</span><span class="plain"> </span><span class="identifier">bytes</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">endif</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">swap alt_match_list with match_list/number_matched</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">COBJ__SwapMatches</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">x</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">swap the counts</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">x</span><span class="plain"> = </span><span class="identifier">number_matched</span><span class="plain">;</span>
<span class="identifier">number_matched</span><span class="plain"> = </span><span class="identifier">alt_match_list</span><span class="plain">--&gt;0;</span>
<span class="identifier">alt_match_list</span><span class="plain">--&gt;0 = </span><span class="identifier">x</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">swap the values</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">x</span><span class="plain"> &lt; </span><span class="identifier">number_matched</span><span class="plain">) </span><span class="identifier">x</span><span class="plain"> = </span><span class="identifier">number_matched</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=</span><span class="identifier">x</span><span class="plain">: </span><span class="identifier">i</span><span class="plain">&gt;0: </span><span class="identifier">i</span><span class="plain">--) {</span>
<span class="identifier">x</span><span class="plain"> = </span><span class="identifier">match_list</span><span class="plain">--&gt;(</span><span class="identifier">i</span><span class="plain">-1);</span>
<span class="identifier">match_list</span><span class="plain">--&gt;(</span><span class="identifier">i</span><span class="plain">-1) = </span><span class="identifier">alt_match_list</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">;</span>
<span class="identifier">alt_match_list</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">x</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">ChooseObjects</span><span class="plain"> </span><span class="identifier">obj</span><span class="plain"> </span><span class="identifier">code</span><span class="plain"> </span><span class="identifier">l</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">swn</span><span class="plain"> </span><span class="identifier">spcount</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">code</span><span class="plain">&lt;2) </span><span class="reserved">rfalse</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cobj_flag</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) {</span>
<span class="plain">.</span><span class="identifier">CodeOne</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parameters</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) {</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">COBJ_DEBUG</span><span class="plain">;</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"[scoring "</span><span class="plain">, (</span><span class="identifier">the</span><span class="plain">) </span><span class="identifier">obj</span><span class="plain">, </span><span class="string">" (second)]^"</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ScoreDabCombo</span><span class="plain">(</span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP1_PRES</span><span class="plain">, </span><span class="identifier">obj</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">COBJ_DEBUG</span><span class="plain">;</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"[scoring "</span><span class="plain">, (</span><span class="identifier">the</span><span class="plain">) </span><span class="identifier">obj</span><span class="plain">, </span><span class="string">" (first) in "</span><span class="plain">,</span>
<span class="identifier">alt_match_list</span><span class="plain">--&gt;0, </span><span class="string">" combinations]^"</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span><span class="plain">;</span>
<span class="identifier">l</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=1: </span><span class="identifier">i</span><span class="plain">&lt;=</span><span class="identifier">alt_match_list</span><span class="plain">--&gt;0: </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">spcount</span><span class="plain"> = </span><span class="identifier">ScoreDabCombo</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">, </span><span class="identifier">alt_match_list</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">spcount</span><span class="plain"> == </span><span class="identifier">HIGHEST_DPMR_SCORE</span><span class="plain">) {</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">COBJ_DEBUG</span><span class="plain">;</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"[scored "</span><span class="plain">, </span><span class="identifier">spcount</span><span class="plain">, </span><span class="string">" - best possible]^"</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">spcount</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">spcount</span><span class="plain">&gt;</span><span class="identifier">l</span><span class="plain">) </span><span class="identifier">l</span><span class="plain"> = </span><span class="identifier">spcount</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">l</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cobj_flag</span><span class="plain"> == </span><span class="constant">2</span><span class="plain">) {</span>
<span class="plain">.</span><span class="identifier">CodeTwo</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">COBJ_DEBUG</span><span class="plain">;</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"[scoring "</span><span class="plain">, (</span><span class="identifier">the</span><span class="plain">) </span><span class="identifier">obj</span><span class="plain">, </span><span class="string">" (simple); parameters = "</span><span class="plain">, </span><span class="identifier">parameters</span><span class="plain">,</span>
<span class="string">" aw = "</span><span class="plain">, </span><span class="identifier">advance_warning</span><span class="plain">, </span><span class="string">"]^"</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span><span class="plain">;</span>
<span class="plain">@</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">action_to_be</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parameters</span><span class="plain">==0) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">advance_warning</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">)</span>
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">ScoreDabCombo</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">, </span><span class="identifier">advance_warning</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">ScoreDabCombo</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">ScoreDabCombo</span><span class="plain">(</span><span class="identifier">parser_results</span><span class="plain">--&gt;</span><span class="identifier">INP1_PRES</span><span class="plain">, </span><span class="identifier">obj</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="plain">@</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">action_to_be</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">l</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">COBJ_DEBUG</span><span class="plain">;</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"[choosing a cobj strategy: "</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span><span class="plain">;</span>
<span class="identifier">swn</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">;</span>
<span class="identifier">spcount</span><span class="plain"> = </span><span class="identifier">pcount</span><span class="plain">;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">line_ttype</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain"> == </span><span class="identifier">PREPOSITION_TT</span><span class="plain">) </span><span class="identifier">pcount</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">line_ttype</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain"> == </span><span class="identifier">ELEMENTARY_TT</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">line_tdata</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain"> == </span><span class="identifier">TOPIC_TOKEN</span><span class="plain">) {</span>
<span class="identifier">pcount</span><span class="plain"> = </span><span class="identifier">spcount</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">CodeTwo</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">wn</span><span class="plain"> &lt;= </span><span class="identifier">num_words</span><span class="plain">) {</span>
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">NextWordStopped</span><span class="plain">(); </span><span class="identifier">wn</span><span class="plain">--;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="identifier">THEN1__WD</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> ( (</span><span class="identifier">l</span><span class="plain"> ~= -1 </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">l</span><span class="plain">-&gt;#</span><span class="identifier">dict_par1</span><span class="plain">) &amp;8 ) { </span><span class="identifier">wn</span><span class="plain">++; </span><span class="reserved">continue</span><span class="plain">; } </span><span class="comment">if preposition</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain"> == </span><span class="identifier">ALL1__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">ALL2__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">ALL3__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">ALL4__WD</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">ALL5__WD</span><span class="plain">) { </span><span class="identifier">wn</span><span class="plain">++; </span><span class="reserved">continue</span><span class="plain">; }</span>
<span class="identifier">SafeSkipDescriptors</span><span class="plain">();</span>
2020-04-07 03:06:09 +03:00
<span class="comment">save the current match state</span>
2020-01-13 13:02:57 +02:00
<span class="plain">@</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">match_length</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">token_filter</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">match_from</span><span class="plain">;</span>
<span class="identifier">alt_match_list</span><span class="plain">--&gt;0 = </span><span class="identifier">number_matched</span><span class="plain">;</span>
<span class="identifier">COBJ__Copy</span><span class="plain">(</span><span class="identifier">number_matched</span><span class="plain">, </span><span class="identifier">match_list</span><span class="plain">, </span><span class="identifier">alt_match_list</span><span class="plain">+</span><span class="identifier">WORDSIZE</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="comment">now get all the matches for the second noun</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">match_length</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">number_matched</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">match_from</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">;</span>
<span class="identifier">token_filter</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">SearchScope</span><span class="plain">(</span><span class="identifier">actor</span><span class="plain">, </span><span class="identifier">actors_location</span><span class="plain">, </span><span class="identifier">line_tdata</span><span class="plain">--&gt;</span><span class="identifier">pcount</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">COBJ_DEBUG</span><span class="plain">;</span>
<span class="reserved">print</span><span class="plain"> </span><span class="identifier">number_matched</span><span class="plain">, </span><span class="string">" possible second nouns]^"</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span><span class="plain">;</span>
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">swn</span><span class="plain">;</span>
<span class="identifier">cobj_flag</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="comment">restore match variables</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">COBJ__SwapMatches</span><span class="plain">();</span>
<span class="plain">@</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">match_from</span><span class="plain">; @</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">token_filter</span><span class="plain">; @</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">match_length</span><span class="plain">;</span>
<span class="identifier">pcount</span><span class="plain"> = </span><span class="identifier">spcount</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">CodeOne</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">pcount</span><span class="plain"> = </span><span class="identifier">spcount</span><span class="plain">;</span>
<span class="identifier">wn</span><span class="plain"> = </span><span class="identifier">swn</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">COBJ_DEBUG</span><span class="plain">;</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"nothing interesting]^"</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span><span class="plain">;</span>
<span class="identifier">cobj_flag</span><span class="plain"> = </span><span class="constant">2</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">CodeTwo</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">ScoreDabCombo</span><span class="plain"> </span><span class="identifier">a</span><span class="plain"> </span><span class="identifier">b</span><span class="plain"> </span><span class="identifier">result</span><span class="plain">;</span>
<span class="plain">@</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">action</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">act_requester</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">noun</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">second</span><span class="plain">;</span>
<span class="identifier">action</span><span class="plain"> = </span><span class="identifier">action_to_be</span><span class="plain">;</span>
<span class="identifier">act_requester</span><span class="plain"> = </span><span class="identifier">player</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">action_reversed</span><span class="plain">) { </span><span class="identifier">noun</span><span class="plain"> = </span><span class="identifier">b</span><span class="plain">; </span><span class="identifier">second</span><span class="plain"> = </span><span class="identifier">a</span><span class="plain">; }</span>
<span class="reserved">else</span><span class="plain"> { </span><span class="identifier">noun</span><span class="plain"> = </span><span class="identifier">a</span><span class="plain">; </span><span class="identifier">second</span><span class="plain"> = </span><span class="identifier">b</span><span class="plain">; }</span>
<span class="identifier">result</span><span class="plain"> = </span><span class="identifier">CheckDPMR</span><span class="plain">();</span>
<span class="plain">@</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">second</span><span class="plain">; @</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">noun</span><span class="plain">; @</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">act_requester</span><span class="plain">; @</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">action</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">COBJ_DEBUG</span><span class="plain">;</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"["</span><span class="plain">, (</span><span class="identifier">the</span><span class="plain">) </span><span class="identifier">a</span><span class="plain">, </span><span class="string">" / "</span><span class="plain">, (</span><span class="identifier">the</span><span class="plain">) </span><span class="identifier">b</span><span class="plain">, </span><span class="string">" =&gt; "</span><span class="plain">, </span><span class="identifier">result</span><span class="plain">, </span><span class="string">"]^"</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">result</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-26 01:42:42 +02:00
<span class="plain">[ </span><span class="identifier">CheckDPMR</span><span class="plain"> </span><span class="identifier">result</span><span class="plain"> </span><span class="identifier">sinp1</span><span class="plain"> </span><span class="identifier">sinp2</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="identifier">sinp1</span><span class="plain"> = </span><span class="identifier">inp1</span><span class="plain">; </span><span class="identifier">sinp2</span><span class="plain"> = </span><span class="identifier">inp2</span><span class="plain">; </span><span class="identifier">inp1</span><span class="plain"> = </span><span class="identifier">noun</span><span class="plain">; </span><span class="identifier">inp2</span><span class="plain"> = </span><span class="identifier">second</span><span class="plain">;</span>
<span class="identifier">rv</span><span class="plain"> = </span><span class="identifier">FollowRulebook</span><span class="plain">(</span><span class="identifier">DOES_THE_PLAYER_MEAN_RB</span><span class="plain">);</span>
<span class="identifier">inp1</span><span class="plain"> = </span><span class="identifier">sinp1</span><span class="plain">; </span><span class="identifier">inp2</span><span class="plain"> = </span><span class="identifier">sinp2</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">rv</span><span class="plain">) &amp;&amp; </span><span class="identifier">RulebookSucceeded</span><span class="plain">()) {</span>
<span class="identifier">result</span><span class="plain"> = </span><span class="identifier">ResultOfRule</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">result</span><span class="plain"> == </span><span class="identifier">RBNO4_OUTCOME</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">4</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">result</span><span class="plain"> == </span><span class="identifier">RBNO3_OUTCOME</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">3</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">result</span><span class="plain"> == </span><span class="identifier">RBNO2_OUTCOME</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">2</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">result</span><span class="plain"> == </span><span class="identifier">RBNO1_OUTCOME</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">result</span><span class="plain"> == </span><span class="identifier">RBNO0_OUTCOME</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">2</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP62"></a><b>&#167;62. Default Topic. </b>A default value for the I7 sort-of-kind "topic", which never matches.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">DefaultTopic</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">GPR_FAIL</span><span class="plain">; ];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP63"></a><b>&#167;63. Recognition-only-GPR. </b>An I6 general parsing routine to look at words from the position marker
<code class="display"><span class="extract">wn</span></code> in the player's command to see if they match the contents of the
text <code class="display"><span class="extract">txt</span></code>, returning either <code class="display"><span class="extract">GPR_PREPOSITION</span></code> or <code class="display"><span class="extract">GPR_FAIL</span></code>
according to whether a match could be made. This is used when the an
object's name is set to include one of its properties, and the property in
question is a text: "A flowerpot is a kind of thing. A flowerpot
has a text called pattern. Understand the pattern property as
describing a flowerpot." When the player types EXAMINE STRIPED FLOWERPOT,
and there is a flowerpot in scope, the following routine is called to
test whether its pattern property &mdash; a text &mdash; matches any words
at the position STRIPED FLOWERPOT. Assuming a pot does indeed have the
pattern "striped", the routine advances <code class="display"><span class="extract">wn</span></code> by 1 and returns
<code class="display"><span class="extract">GPR_PREPOSITION</span></code> to indicate a match.
</p>
<p class="inwebparagraph">This kind of GPR is called a "recognition-only-GPR", because it only
recognises an existing value: it doesn't parse a new one.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_ROGPR</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain"> </span><span class="identifier">p</span><span class="plain"> </span><span class="identifier">cp</span><span class="plain"> </span><span class="identifier">r</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">txt</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">GPR_FAIL</span><span class="plain">;</span>
<span class="identifier">cp</span><span class="plain"> = </span><span class="identifier">txt</span><span class="plain">--&gt;0; </span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">TEXT_TY_Temporarily_Transmute</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="identifier">r</span><span class="plain"> = </span><span class="identifier">TEXT_TY_ROGPRI</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_Untransmute</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">cp</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">r</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_ROGPRI</span><span class="plain"> </span><span class="identifier">txt</span>
<span class="identifier">pos</span><span class="plain"> </span><span class="identifier">len</span><span class="plain"> </span><span class="identifier">wa</span><span class="plain"> </span><span class="identifier">wl</span><span class="plain"> </span><span class="identifier">wpos</span><span class="plain"> </span><span class="identifier">bdm</span><span class="plain"> </span><span class="identifier">ch</span><span class="plain"> </span><span class="identifier">own</span><span class="plain">;</span>
<span class="identifier">bdm</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">; </span><span class="identifier">own</span><span class="plain"> = </span><span class="identifier">wn</span><span class="plain">;</span>
<span class="identifier">len</span><span class="plain"> = </span><span class="identifier">BlkValueLBCapacity</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">pos</span><span class="plain">=0: </span><span class="identifier">pos</span><span class="plain">&lt;=</span><span class="identifier">len</span><span class="plain">: </span><span class="identifier">pos</span><span class="plain">++) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pos</span><span class="plain"> == </span><span class="identifier">len</span><span class="plain">) </span><span class="identifier">ch</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">ch</span><span class="plain"> = </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">pos</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ch</span><span class="plain"> == </span><span class="constant">32</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">9</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">10</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">0</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bdm</span><span class="plain">) </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="identifier">bdm</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wpos</span><span class="plain"> ~= </span><span class="identifier">wl</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">GPR_FAIL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ch</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bdm</span><span class="plain">) {</span>
<span class="identifier">bdm</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">NextWordStopped</span><span class="plain">() == -1) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">GPR_FAIL</span><span class="plain">;</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">wa</span><span class="plain"> = </span><span class="identifier">WordAddress</span><span class="plain">(</span><span class="identifier">wn</span><span class="plain">-1);</span>
<span class="identifier">wl</span><span class="plain"> = </span><span class="identifier">WordLength</span><span class="plain">(</span><span class="identifier">wn</span><span class="plain">-1);</span>
<span class="identifier">wpos</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wa</span><span class="plain">-&gt;</span><span class="identifier">wpos</span><span class="plain"> ~= </span><span class="identifier">ch</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">TEXT_TY_RevCase</span><span class="plain">(</span><span class="identifier">ch</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">GPR_FAIL</span><span class="plain">;</span>
<span class="identifier">wpos</span><span class="plain">++;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wn</span><span class="plain"> == </span><span class="identifier">own</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">GPR_FAIL</span><span class="plain">; </span><span class="comment">Progress must be made to avoid looping</span>
2020-01-13 13:02:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">GPR_PREPOSITION</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP64"></a><b>&#167;64. RunRoutines. </b>This function may not be very well-named, but the idea is to take a property
of a given object and either to print it (and return <code class="display"><span class="extract">true</span></code>) if it's a string,
and call it (and pass along its return value) if it's a routine. If the
object does not provide the property, we act on the default value for the
property if it has one, and otherwise do nothing (and return <code class="display"><span class="extract">false</span></code>).
</p>
<p class="inwebparagraph">The I6 pseudo-object <code class="display"><span class="extract">thedark</span></code> is used to give the impression that Darkness
is a room in its own right, which is not really true. Note that it is not
permitted to have properties other than the three named here: all other
properties are redirected to the current location's object.
</p>
<p class="inwebparagraph">Properties with numbers under <code class="display"><span class="extract">INDIV_PROP_START</span></code> are "common properties".
These come along with a table of default values, so that it is meaningful
(in I6, anyway) to read them even when they are not provided (so that the
address, returned by the <code class="display"><span class="extract">.&amp;</span></code> operator, is zero).
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">RunRoutines</span><span class="plain"> </span><span class="identifier">obj</span><span class="plain"> </span><span class="identifier">prop</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain"> == </span><span class="identifier">thedark</span><span class="plain">) </span><span class="identifier">obj</span><span class="plain"> = </span><span class="identifier">real_location</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">obj</span><span class="plain">.&amp;</span><span class="identifier">prop</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">prop</span><span class="plain"> &gt;= </span><span class="identifier">INDIV_PROP_START</span><span class="plain">)) </span><span class="reserved">rfalse</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">obj</span><span class="plain">.</span><span class="identifier">prop</span><span class="plain">();</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP65"></a><b>&#167;65. Setting the Player's Command. </b>In effect, the text typed most recently by the player is a sort of
text already, though it isn't in text format, and doesn't live on
the heap.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">SetPlayersCommand</span><span class="plain"> </span><span class="identifier">from_txt</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">len</span><span class="plain"> </span><span class="identifier">at</span><span class="plain"> </span><span class="identifier">p</span><span class="plain"> </span><span class="identifier">cp</span><span class="plain">;</span>
<span class="identifier">cp</span><span class="plain"> = </span><span class="identifier">from_txt</span><span class="plain">--&gt;0; </span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">TEXT_TY_Temporarily_Transmute</span><span class="plain">(</span><span class="identifier">from_txt</span><span class="plain">);</span>
<span class="identifier">len</span><span class="plain"> = </span><span class="identifier">TEXT_TY_CharacterLength</span><span class="plain">(</span><span class="identifier">from_txt</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">len</span><span class="plain"> &gt; </span><span class="constant">118</span><span class="plain">) </span><span class="identifier">len</span><span class="plain"> = </span><span class="constant">118</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="identifier">buffer</span><span class="plain">-&gt;1 = </span><span class="identifier">len</span><span class="plain">; </span><span class="identifier">at</span><span class="plain"> = </span><span class="constant">2</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">ifnot</span><span class="plain">;</span>
<span class="identifier">buffer</span><span class="plain">--&gt;0 = </span><span class="identifier">len</span><span class="plain">; </span><span class="identifier">at</span><span class="plain"> = </span><span class="constant">4</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0:</span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">len</span><span class="plain">:</span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">buffer</span><span class="plain">-&gt;(</span><span class="identifier">i</span><span class="plain">+</span><span class="identifier">at</span><span class="plain">) = </span><span class="identifier">CharToCase</span><span class="plain">(</span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">from_txt</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">), </span><span class="constant">0</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (:</span><span class="identifier">at</span><span class="plain">+</span><span class="identifier">i</span><span class="plain">&lt;120:</span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">buffer</span><span class="plain">-&gt;(</span><span class="identifier">at</span><span class="plain">+</span><span class="identifier">i</span><span class="plain">) = </span><span class="character">' '</span><span class="plain">;</span>
<span class="identifier">VM_Tokenise</span><span class="plain">(</span><span class="identifier">buffer</span><span class="plain">, </span><span class="identifier">parse</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">players_command</span><span class="plain"> = </span><span class="constant">100</span><span class="plain"> + </span><span class="identifier">WordCount</span><span class="plain">(); </span><span class="comment">The snippet variable "player's command"</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">TEXT_TY_Untransmute</span><span class="plain">(</span><span class="identifier">from_txt</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">cp</span><span class="plain">);</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP66"></a><b>&#167;66. Multiple Object List. </b>The parser uses one data structure which is really a list: but which can't
be represented as such because the heap might not exist. This is the multiple
object list, which is used to handle commands like TAKE ALL by firing off a
sequence of actions with one of the objects taken from entries in turn of
the list. The following converts it to a list structure.
</p>
<pre class="display">
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">LIST_OF_TY_Mol</span><span class="plain"> </span><span class="identifier">list</span><span class="plain"> </span><span class="identifier">len</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">list</span><span class="plain">==0) || (</span><span class="identifier">BlkValueWeakKind</span><span class="plain">(</span><span class="identifier">list</span><span class="plain">) ~= </span><span class="identifier">LIST_OF_TY</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">len</span><span class="plain"> = </span><span class="identifier">multiple_object</span><span class="plain">--&gt;0;</span>
<span class="identifier">LIST_OF_TY_SetLength</span><span class="plain">(</span><span class="identifier">list</span><span class="plain">, </span><span class="identifier">len</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=1: </span><span class="identifier">i</span><span class="plain">&lt;=</span><span class="identifier">len</span><span class="plain">: </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="identifier">LIST_OF_TY_PutItem</span><span class="plain">(</span><span class="identifier">list</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">multiple_object</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">list</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-13 13:02:57 +02:00
<span class="plain">[ </span><span class="identifier">LIST_OF_TY_Set_Mol</span><span class="plain"> </span><span class="identifier">list</span><span class="plain"> </span><span class="identifier">len</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">list</span><span class="plain">==0) || (</span><span class="identifier">BlkValueWeakKind</span><span class="plain">(</span><span class="identifier">list</span><span class="plain">) ~= </span><span class="identifier">LIST_OF_TY</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">len</span><span class="plain"> = </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">list</span><span class="plain">, </span><span class="identifier">LIST_LENGTH_F</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">len</span><span class="plain"> &gt; </span><span class="constant">63</span><span class="plain">) </span><span class="identifier">len</span><span class="plain"> = </span><span class="constant">63</span><span class="plain">;</span>
<span class="identifier">multiple_object</span><span class="plain">--&gt;0 = </span><span class="identifier">len</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=1: </span><span class="identifier">i</span><span class="plain">&lt;=</span><span class="identifier">len</span><span class="plain">: </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="identifier">multiple_object</span><span class="plain">--&gt;</span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">list</span><span class="plain">, </span><span class="identifier">LIST_ITEM_BASE</span><span class="plain">+</span><span class="identifier">i</span><span class="plain">-1);</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<hr class="tocbar">
2020-04-14 19:56:54 +03:00
<ul class="toc"><li><i>(This section begins Sections.)</i></li><li><a href="S-tkn.html">Continue with 'Number Template'</a></li></ul><hr class="tocbar">
<!--End of weave-->
2020-04-14 19:56:54 +03:00
<script>
MathJax = {
tex: {
inlineMath: '$', '$'], ['\\(', '\\)'
},
svg: {
fontCache: 'global'
}
};
</script>
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>
2020-03-19 02:11:25 +02:00
</main>
</body>
</html>