<pclass="purpose">The possible command text following a command verb, or referring to a single concept or object, is gathered into a "command grammar".</p>
<ulclass="toc"><li><ahref="5-cg.html#SP5">§5. The CG_IS_COMMAND form</a></li><li><ahref="5-cg.html#SP11">§11. The CG_IS_TOKEN form</a></li><li><ahref="5-cg.html#SP13">§13. The CG_IS_SUBJECT form</a></li><li><ahref="5-cg.html#SP15">§15. The CG_IS_VALUE form</a></li><li><ahref="5-cg.html#SP16">§16. The CG_IS_CONSULT form</a></li><li><ahref="5-cg.html#SP17">§17. The CG_IS_PROPERTY_NAME form</a></li><li><ahref="5-cg.html#SP18">§18. The list of grammar lines</a></li><li><ahref="5-cg.html#SP20">§20. Slashing and determining</a></li><li><ahref="5-cg.html#SP22">§22. Sorting</a></li></ul><hrclass="tocbar">
<pclass="commentary firstcommentary"><aid="SP1"class="paragraph-anchor"></a><b>§1. </b>Command grammars, or CGs, are used in six excitingly different ways:
<preclass="definitions code-font"><spanclass="definition-keyword">define</span><spanclass="constant-syntax">CG_IS_COMMAND</span><spanclass="plain-syntax"></span><spanclass="constant-syntax">1</span><spanclass="plain-syntax"></span><spanclass="comment-syntax"> for player-typed commands starting with a given verb</span>
<spanclass="definition-keyword">define</span><spanclass="constant-syntax">CG_IS_TOKEN</span><spanclass="plain-syntax"></span><spanclass="constant-syntax">2</span><spanclass="plain-syntax"></span><spanclass="comment-syntax"> for defining a square-bracketed token used in commands</span>
<spanclass="definition-keyword">define</span><spanclass="constant-syntax">CG_IS_SUBJECT</span><spanclass="plain-syntax"></span><spanclass="constant-syntax">3</span><spanclass="plain-syntax"></span><spanclass="comment-syntax"> for ways the player can refer to an object or kind</span>
<spanclass="definition-keyword">define</span><spanclass="constant-syntax">CG_IS_VALUE</span><spanclass="plain-syntax"></span><spanclass="constant-syntax">4</span><spanclass="plain-syntax"></span><spanclass="comment-syntax"> for ways the player can refer to a non-object value</span>
<spanclass="definition-keyword">define</span><spanclass="constant-syntax">CG_IS_CONSULT</span><spanclass="plain-syntax"></span><spanclass="constant-syntax">5</span><spanclass="plain-syntax"></span><spanclass="comment-syntax"> for topics of conversation, as used in commands like ASK or CONSULT</span>
<spanclass="definition-keyword">define</span><spanclass="constant-syntax">CG_IS_PROPERTY_NAME</span><spanclass="plain-syntax"></span><spanclass="constant-syntax">6</span><spanclass="plain-syntax"></span><spanclass="comment-syntax"> for ways to refer to property values used adjectivally</span>
<pclass="commentary firstcommentary"><aid="SP2"class="paragraph-anchor"></a><b>§2. </b>Fixed maxima are generally a bad idea in a compiler (what seems excessive in
one decade becomes limiting in the next), but in this plugin we have to
make data tables in formats which can be handled by the Inform 6 compiler.
And that does have two maxima which cannot easily be avoided, so we need to
respect those here as well.
</p>
<pclass="commentary"><spanclass="extract"><spanclass="extract-syntax">MAX_ALIASED_COMMANDS</span></span> is harmless enough: it's the maximum number of command
verbs which can be synonymous with a single other one, as for example if CONSUME
were synonymous with EAT. Few command verbs need more than four or five, and
many need none at all.
</p>
<pclass="commentary"><spanclass="extract"><spanclass="extract-syntax">MAX_LINES_PER_GRAMMAR</span></span> is potentially more biting, since it puts a limit on
the number of different command syntaxes which any one command verb can have.
(It applies only to <spanclass="extract"><spanclass="extract-syntax">CG_IS_COMMAND</span></span> grammars: the rest are unlimited.) Skilled
Inform 7 writers can get around this with named tokens, but still, in an ideal
<pclass="commentary firstcommentary"><aid="SP3"class="paragraph-anchor"></a><b>§3. </b>Many of the fields here are relevant only when the CG takes a given <spanclass="extract"><spanclass="extract-syntax">cg_is</span></span>
form, so this is not as bloated a structure as it looks.
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">cg_is</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> one of the </span><spanclass="extract"><spanclass="extract-syntax">CG_IS_*</span></span><spanclass="comment-syntax"> values above</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">struct</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">parse_node</span><spanclass="plain-syntax"> *</span><spanclass="identifier-syntax">where_cg_created</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> for problem message reports</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">struct</span><spanclass="plain-syntax"></span><spanclass="reserved-syntax">cg_line</span><spanclass="plain-syntax"> *</span><spanclass="identifier-syntax">first_line</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> linked list in creation order</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">struct</span><spanclass="plain-syntax"></span><spanclass="reserved-syntax">cg_line</span><spanclass="plain-syntax"> *</span><spanclass="identifier-syntax">sorted_first_line</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> and in logical applicability order</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">slashed</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> slashing has been done</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">determined</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> determination has been done</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">struct</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">wording</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">command</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"></span><spanclass="extract"><spanclass="extract-syntax">CG_IS_COMMAND</span></span><spanclass="comment-syntax">: what command verb this belongs to</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">struct</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">wording</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">aliased_command</span><spanclass="plain-syntax">[</span><spanclass="constant-syntax">MAX_ALIASED_COMMANDS</span><spanclass="plain-syntax">]; </span><spanclass="comment-syntax"> ...and other commands synonymous</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">no_aliased_commands</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> ...and how many of them there are</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">struct</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">wording</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">token_name</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"></span><spanclass="extract"><spanclass="extract-syntax">CG_IS_TOKEN</span></span><spanclass="comment-syntax">: name of this token</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">struct</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">inference_subject</span><spanclass="plain-syntax"> *</span><spanclass="identifier-syntax">subj_understood</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"></span><spanclass="extract"><spanclass="extract-syntax">CG_IS_SUBJECT</span></span><spanclass="comment-syntax">: what this provides names for</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">struct</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">kind</span><spanclass="plain-syntax"> *</span><spanclass="identifier-syntax">kind_understood</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"></span><spanclass="extract"><spanclass="extract-syntax">CG_IS_VALUE</span></span><spanclass="comment-syntax">: for which type it names an instance of</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">struct</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">property</span><spanclass="plain-syntax"> *</span><spanclass="identifier-syntax">prn_understood</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"></span><spanclass="extract"><spanclass="extract-syntax">CG_IS_PROPERTY_NAME</span></span><spanclass="comment-syntax">: which prn this names</span>
<pclass="commentary firstcommentary"><aid="SP4"class="paragraph-anchor"></a><b>§4. </b>We begin as usual with a constructor and some debug log tracing.
<pclass="commentary firstcommentary"><aid="SP5"class="paragraph-anchor"></a><b>§5. The CG_IS_COMMAND form. </b>These are the CGs for which CGs were invented, really. Each different
imperative verb a player can type has a CG of the possible syntaxes the
player's command can take after that start.
</p>
<pclass="commentary">However, such a CG can also handle a number of "aliases", which are verbs
synonymous to the main one. For instance, the Standard Rules create a CG for
the command PULL but also give it one alias, DRAG.
</p>
<pclass="commentary">Command verbs are of course recognised by their wording, or rather, spelling.
(We cannot have two different CGs for the verb MARK as understood in two
different senses, say for marking work and for daubing on a wall.) A special
case is the empty command verb, the one with no letters at all, which is
traditionally called the "no verb verb".<supid="fnref:1"><ahref="#fn:1"rel="footnote">1</a></sup> All other verbs are "genuinely
<ulclass="footnotetexts"><liclass="footnote"id="fn:1"><pclass="inwebfootnote"><supid="fnref:1"><ahref="#fn:1"rel="footnote">1</a></sup> The Standard Rules do not use the no verb verb, but Inform designers
sometimes do, to allow players to type commands which are meaningful even
when they do not start with a verb. We treat those as being commands which
do in fact start with the invisible "no verb verb".
<ahref="#fnref:1"title="return to text">↩</a></p></li></ul>
<pclass="commentary firstcommentary"><aid="SP6"class="paragraph-anchor"></a><b>§6. </b>Here we find the CG associated with command <spanclass="extract"><spanclass="extract-syntax">W</span></span>, or return null if none
exists (i.e. because no grammar has been created for it). Note that if <spanclass="extract"><spanclass="extract-syntax">W</span></span> is
the <spanclass="extract"><spanclass="extract-syntax">EMPTY_WORDING</span></span>, then this function returns the "no verb verb".
<pclass="commentary firstcommentary"><aid="SP7"class="paragraph-anchor"></a><b>§7. </b>This does the same, but creating the CG if it does not already exist, so
that it is guaranteed to return a non-<spanclass="extract"><spanclass="extract-syntax">NULL</span></span> pointer:
<spanclass="plain-syntax"></span><spanclass="identifier-syntax">LOGIF</span><spanclass="plain-syntax">(</span><spanclass="identifier-syntax">GRAMMAR</span><spanclass="plain-syntax">, </span><spanclass="string-syntax">"CG%d is the no verb verb\n"</span><spanclass="plain-syntax">, </span><spanclass="identifier-syntax">cg</span><spanclass="plain-syntax">-></span><spanclass="identifier-syntax">allocation_id</span><spanclass="plain-syntax">);</span>
<spanclass="plain-syntax"></span><spanclass="identifier-syntax">LOGIF</span><spanclass="plain-syntax">(</span><spanclass="identifier-syntax">GRAMMAR</span><spanclass="plain-syntax">, </span><spanclass="string-syntax">"CG%d is the command verb %W\n"</span><spanclass="plain-syntax">, </span><spanclass="identifier-syntax">cg</span><spanclass="plain-syntax">-></span><spanclass="identifier-syntax">allocation_id</span><spanclass="plain-syntax">, </span><spanclass="identifier-syntax">W</span><spanclass="plain-syntax">);</span>
<pclass="commentary firstcommentary"><aid="SP8"class="paragraph-anchor"></a><b>§8. </b>We now have functions to add or remove command verbs from a given CG as aliases.
Note that these cannot be called on the no verb verb.
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (</span><spanclass="identifier-syntax">cg</span><spanclass="plain-syntax"> == </span><spanclass="identifier-syntax">NULL</span><spanclass="plain-syntax">) </span><spanclass="identifier-syntax">internal_error</span><spanclass="plain-syntax">(</span><spanclass="string-syntax">"add alias to null CG"</span><spanclass="plain-syntax">);</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (</span><spanclass="identifier-syntax">cg</span><spanclass="plain-syntax">-></span><spanclass="element-syntax">cg_is</span><spanclass="plain-syntax"> != </span><spanclass="constant-syntax">CG_IS_COMMAND</span><spanclass="plain-syntax">) </span><spanclass="identifier-syntax">internal_error</span><spanclass="plain-syntax">(</span><spanclass="string-syntax">"add alias to non-command CG"</span><spanclass="plain-syntax">);</span>
<spanclass="plain-syntax"></span><spanclass="identifier-syntax">LOGIF</span><spanclass="plain-syntax">(</span><spanclass="identifier-syntax">GRAMMAR</span><spanclass="plain-syntax">, </span><spanclass="string-syntax">"Adding alias '%W' to CG%d '%W'\n"</span><spanclass="plain-syntax">, </span><spanclass="identifier-syntax">W</span><spanclass="plain-syntax">,</span>
<pclass="commentary firstcommentary"><aid="SP9"class="paragraph-anchor"></a><b>§9. </b>Removing is trickier, since we might be detaching the main command verb, and
that means that one of the aliases must become the new main verb; or, in the
worst case, there might be no commands left, and in that case we need to empty
the CG of grammar lines so that it can either be ignored or re-used.
<spanclass="plain-syntax"></span><spanclass="identifier-syntax">internal_error</span><spanclass="plain-syntax">(</span><spanclass="string-syntax">"tried to detach alias command from null CG"</span><spanclass="plain-syntax">);</span>
<spanclass="plain-syntax"></span><spanclass="identifier-syntax">internal_error</span><spanclass="plain-syntax">(</span><spanclass="string-syntax">"tried to detach alias command from non-command CG"</span><spanclass="plain-syntax">);</span>
<spanclass="plain-syntax"></span><spanclass="identifier-syntax">LOGIF</span><spanclass="plain-syntax">(</span><spanclass="identifier-syntax">GRAMMAR</span><spanclass="plain-syntax">, </span><spanclass="string-syntax">"Detached verb is the head-verb\n"</span><spanclass="plain-syntax">);</span>
<spanclass="plain-syntax"></span><spanclass="identifier-syntax">LOGIF</span><spanclass="plain-syntax">(</span><spanclass="identifier-syntax">GRAMMAR</span><spanclass="plain-syntax">, </span><spanclass="string-syntax">"Which had no aliases: clearing grammar to NULL\n"</span><spanclass="plain-syntax">);</span>
<spanclass="plain-syntax"></span><spanclass="identifier-syntax">LOGIF</span><spanclass="plain-syntax">(</span><spanclass="identifier-syntax">GRAMMAR</span><spanclass="plain-syntax">, </span><spanclass="string-syntax">"Which had aliases: making new head-verb '%W'\n"</span><spanclass="plain-syntax">,</span>
<spanclass="plain-syntax"></span><spanclass="identifier-syntax">LOGIF</span><spanclass="plain-syntax">(</span><spanclass="identifier-syntax">GRAMMAR</span><spanclass="plain-syntax">, </span><spanclass="string-syntax">"Detached verb is one of the aliases\n"</span><spanclass="plain-syntax">);</span>
<pclass="commentary firstcommentary"><aid="SP10"class="paragraph-anchor"></a><b>§10. </b>This is needed when the designer asks to make actions inaccessible to
commands from the player, with a line like "Understand nothing as the
<pclass="commentary firstcommentary"><aid="SP11"class="paragraph-anchor"></a><b>§11. The CG_IS_TOKEN form. </b>These are like text substitutions in reverse. For instance, we could define
a token "[suitable colour]", which matches any colour name typed by the player.
</p>
<pclass="commentary">Tokens are identified solely by their textual names. There is one and only one
<pclass="commentary firstcommentary"><aid="SP12"class="paragraph-anchor"></a><b>§12. </b>A slight variation is provided by those which are defined by Inter functions.
<pclass="commentary firstcommentary"><aid="SP13"class="paragraph-anchor"></a><b>§13. The CG_IS_SUBJECT form. </b>Any inference subject can in theory be given a CG, used to parse unusual forms
<ulclass="footnotetexts"><liclass="footnote"id="fn:2"><pclass="inwebfootnote"><supid="fnref:2"><ahref="#fn:2"rel="footnote">2</a></sup> Because in our run-time representation, objects and kinds of objects have
data which makes it convenient for them to provide their own "general parsing
routines", whereas enumeration values do not. So to give exotic names to instances
of non-object kinds we use <spanclass="extract"><spanclass="extract-syntax">CG_IS_VALUE</span></span> instead. And in any case numbers or
times of day are not inference subjects anyway, so we would need <spanclass="extract"><spanclass="extract-syntax">CG_IS_VALUE</span></span>
in any case for those.
<ahref="#fnref:2"title="return to text">↩</a></p></li></ul>
<pclass="commentary firstcommentary"><aid="SP14"class="paragraph-anchor"></a><b>§14. </b>This is an optimisation to store grammar more efficiently if it turns out
that the names given to the subject are all single words. It saves a few bytes
at run-time, and is just a little faster for the command parser then.
<spanclass="plain-syntax"></span><spanclass="identifier-syntax">internal_error</span><spanclass="plain-syntax">(</span><spanclass="string-syntax">"One-word optimisation applies only to objects"</span><spanclass="plain-syntax">);</span>
<pclass="commentary firstcommentary"><aid="SP15"class="paragraph-anchor"></a><b>§15. The CG_IS_VALUE form. </b>This is used to store names for, say, particular numbers, or enumeration
values. The following examples both involve <spanclass="extract"><spanclass="extract-syntax">CG_IS_VALUE</span></span> grammars:
<pclass="commentary">Note however that a <spanclass="extract"><spanclass="extract-syntax">CG_IS_VALUE</span></span> grammar is associated with a kind: unlike
the case of <spanclass="extract"><spanclass="extract-syntax">CG_IS_SUBJECT</span></span>, there isn't a different one for each individual
value. There is just one grammar holding all possible fancy names for
different numbers, for example; the <spanclass="extract"><spanclass="extract-syntax">CG_IS_VALUE</span></span> grammar for <spanclass="extract"><spanclass="extract-syntax">K_number</span></span>.
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (</span><spanclass="identifier-syntax">K</span><spanclass="plain-syntax"> == </span><spanclass="identifier-syntax">NULL</span><spanclass="plain-syntax">) </span><spanclass="identifier-syntax">internal_error</span><spanclass="plain-syntax">(</span><spanclass="string-syntax">"cannot get CG for null kind"</span><spanclass="plain-syntax">);</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (</span><spanclass="identifier-syntax">Kinds::Behaviour::is_object</span><spanclass="plain-syntax">(</span><spanclass="identifier-syntax">K</span><spanclass="plain-syntax">)) </span><spanclass="identifier-syntax">internal_error</span><spanclass="plain-syntax">(</span><spanclass="string-syntax">"cannot set CG for K_object"</span><spanclass="plain-syntax">);</span>
<spanclass="plain-syntax"></span><spanclass="identifier-syntax">internal_error</span><spanclass="plain-syntax">(</span><spanclass="string-syntax">"object kinds should not have a CG_IS_VALUE grammar"</span><spanclass="plain-syntax">);</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (</span><spanclass="identifier-syntax">Kinds::Behaviour::is_object</span><spanclass="plain-syntax">(</span><spanclass="identifier-syntax">K</span><spanclass="plain-syntax">)) </span><spanclass="identifier-syntax">internal_error</span><spanclass="plain-syntax">(</span><spanclass="string-syntax">"cannot get CG for K_object"</span><spanclass="plain-syntax">);</span>
<pclass="commentary firstcommentary"><aid="SP16"class="paragraph-anchor"></a><b>§16. The CG_IS_CONSULT form. </b>Consultation grammars<supid="fnref:3"><ahref="#fn:3"rel="footnote">3</a></sup> are used to handle topics of conversation and other
free-form textual parts of commands typed by the player: the player can legally
type ASK JETHRO ABOUT ... and put almost anything after ABOUT, and we need ways
to parse that material.
</p>
<pclass="commentary">The model here is rather different. Because the topic being discussed could be
almost anything — maybe Jethro knows about WHEAT PRICES, the HARVEST and
QUANTUM CHROMODYNAMICS (he has hidden depths) — there is no obvious data
structure in Inform to attach such a grammar to. Instead, code wishing to
create a new consultation should first call <ahref="5-cg.html#SP16"class="internal">CommandGrammars::prepare_consultation_cg</a>,
then access the current one being made using <ahref="5-cg.html#SP16"class="internal">CommandGrammars::get_consultation_cg</a>.
Note that exactly one consultation can be made at a time.
</p>
<ulclass="footnotetexts"><liclass="footnote"id="fn:3"><pclass="inwebfootnote"><supid="fnref:3"><ahref="#fn:3"rel="footnote">3</a></sup> The term "consultation" goes back to the origins of this feature in the
CONSULT command, which in turn goes right back to a game called "Curses" (1993),
in which players consulted a biographical dictionary of the Meldrew family.
<ahref="#fnref:3"title="return to text">↩</a></p></li></ul>
<pclass="commentary firstcommentary"><aid="SP17"class="paragraph-anchor"></a><b>§17. The CG_IS_PROPERTY_NAME form. </b>A few properties can be recognised by adjectives in the player's commands.
For example, we might allow OPEN or CLOSED in connection with doors. If so,
we may want to allow synonyms or other ways to express this, and so a
property value used adjectivally like this can be given a CG.
<pclass="commentary firstcommentary"><aid="SP18"class="paragraph-anchor"></a><b>§18. The list of grammar lines. </b>Every CG has a list of CGLs: indeed, this list is the point of the grammar. Here
we test this for emptiness, and provide for adding to it. In general removals
are not possible, but see <ahref="5-cg.html#SP10"class="internal">CommandGrammars::remove_action</a> above.
<spanclass="plain-syntax"></span><spanclass="string-syntax">"this command verb now has too many Understand possibilities"</span><spanclass="plain-syntax">,</span>
<spanclass="plain-syntax"></span><spanclass="string-syntax">"that is, there are too many 'Understand \"whatever ...\" as ...' "</span>
<spanclass="plain-syntax"></span><spanclass="string-syntax">"which share the same initial word 'whatever'. The best way to "</span>
<spanclass="plain-syntax"></span><spanclass="string-syntax">"get around this is to try to consolidate some of those lines "</span>
<spanclass="plain-syntax"></span><spanclass="string-syntax">"together, perhaps by using slashes to combine alternative "</span>
<spanclass="plain-syntax"></span><spanclass="string-syntax">"wordings, or by defining new grammar tokens [in square brackets]."</span><spanclass="plain-syntax">);</span>
<pclass="commentary firstcommentary"><aid="SP19"class="paragraph-anchor"></a><b>§19. </b>As noted above, some CGs are used to refer to objects or values: others not.
This returns the kind if so, or <spanclass="extract"><spanclass="extract-syntax">NULL</span></span> if not.
<pclass="commentary firstcommentary"><aid="SP20"class="paragraph-anchor"></a><b>§20. Slashing and determining. </b>CGs are created and then gradually accumulate grammar lines in response to the
stream of "Understand... as..." sentences. Once all of that is done, we have to
make sense of it all, which we do in two phases: "slashing" and "determining".
<pclass="commentary firstcommentary"><aid="SP21"class="paragraph-anchor"></a><b>§21. </b>Determining is more involved, and is also recursive. What we are doing is
trying to work values a CG can produce, in terms of what value it refers to —
if any. For <spanclass="extract"><spanclass="extract-syntax">CG_IS_COMMAND</span></span> grammars, for example, it will be <spanclass="extract"><spanclass="extract-syntax">NULL</span></span>, but
for <spanclass="extract"><spanclass="extract-syntax">CG_IS_VALUE</span></span>, it might for example be a description meaning "any value
with kind <spanclass="extract"><spanclass="extract-syntax">K_number</span></span>.
<spanclass="plain-syntax"></span><spanclass="named-paragraph-container code-font"><ahref="5-cg.html#SP21_1"class="named-paragraph-link"><spanclass="named-paragraph">If this CG produces a value we have determined already, return that</span><spanclass="named-paragraph-number">21.1</span></a></span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="named-paragraph-container code-font"><ahref="5-cg.html#SP21_2"class="named-paragraph-link"><spanclass="named-paragraph">If recursion went impossibly deep, the CG grammar must be ill-founded</span><spanclass="named-paragraph-number">21.2</span></a></span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="named-paragraph-container code-font"><ahref="5-cg.html#SP21_3"class="named-paragraph-link"><spanclass="named-paragraph">Take the union of the single-term results of each line</span><spanclass="named-paragraph-number">21.3</span></a></span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="named-paragraph-container code-font"><ahref="5-cg.html#SP21_4"class="named-paragraph-link"><spanclass="named-paragraph">Cache the answer so that we need not determine it again</span><spanclass="named-paragraph-number">21.4</span></a></span><spanclass="plain-syntax">;</span>
<pclass="commentary firstcommentary"><aid="SP21_1"class="paragraph-anchor"></a><b>§21.1. </b><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">If this CG produces a value we have determined already, return that</span><spanclass="named-paragraph-number">21.1</span></span><spanclass="comment-syntax"> =</span>
<ulclass="endnotetexts"><li>This code is used in <ahref="5-cg.html#SP21">§21</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP21_2"class="paragraph-anchor"></a><b>§21.2. </b><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">If recursion went impossibly deep, the CG grammar must be ill-founded</span><spanclass="named-paragraph-number">21.2</span></span><spanclass="comment-syntax"> =</span>
<spanclass="plain-syntax"></span><spanclass="string-syntax">"grammar tokens are not allowed to be defined in terms of themselves"</span><spanclass="plain-syntax">,</span>
<spanclass="plain-syntax"></span><spanclass="string-syntax">"either directly or indirectly."</span><spanclass="plain-syntax">);</span>
<pclass="commentary firstcommentary"><aid="SP21_3"class="paragraph-anchor"></a><b>§21.3. </b>The "union" referred to below is the widest possible description which
matches the single term of the determination type of each CGL in the list.
</p>
<pclass="commentary"><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">Take the union of the single-term results of each line</span><spanclass="named-paragraph-number">21.3</span></span><spanclass="comment-syntax"> =</span>
<spanclass="plain-syntax"></span><spanclass="identifier-syntax">LOGIF</span><spanclass="plain-syntax">(</span><spanclass="identifier-syntax">GRAMMAR_CONSTRUCTION</span><spanclass="plain-syntax">, </span><spanclass="string-syntax">"Taking union on $G\n"</span><spanclass="plain-syntax">, </span><spanclass="identifier-syntax">cg</span><spanclass="plain-syntax">);</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (</span><spanclass="identifier-syntax">first_flag</span><spanclass="plain-syntax">) { </span><spanclass="comment-syntax"> initially no expectations: </span><spanclass="extract"><spanclass="extract-syntax">spec_union</span></span><spanclass="comment-syntax"> is meaningless</span>
<spanclass="plain-syntax"></span><spanclass="identifier-syntax">spec_union</span><spanclass="plain-syntax"> = </span><spanclass="identifier-syntax">spec_of_line</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> so we set it to the first result</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">continue</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> we expected to find no result, and did: so no problem</span>
<spanclass="plain-syntax"></span><spanclass="identifier-syntax">spec_union</span><spanclass="plain-syntax"> = </span><spanclass="identifier-syntax">spec_of_line</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> here </span><spanclass="extract"><spanclass="extract-syntax">spec_of_line</span></span><spanclass="comment-syntax"> was a wider type</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">continue</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> here </span><spanclass="extract"><spanclass="extract-syntax">spec_union</span></span><spanclass="comment-syntax"> was already wide enough</span>
<spanclass="plain-syntax"> }</span>
<spanclass="plain-syntax"> }</span>
<spanclass="plain-syntax"></span><spanclass="named-paragraph-container code-font"><ahref="5-cg.html#SP21_3_1"class="named-paragraph-link"><spanclass="named-paragraph">It is now evident that the lines have incompatible determination types</span><spanclass="named-paragraph-number">21.3.1</span></a></span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">break</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> to prevent the problem being repeated for the same grammar</span>
<spanclass="plain-syntax"></span><spanclass="identifier-syntax">LOGIF</span><spanclass="plain-syntax">(</span><spanclass="identifier-syntax">GRAMMAR_CONSTRUCTION</span><spanclass="plain-syntax">, </span><spanclass="string-syntax">"Result is $P\n"</span><spanclass="plain-syntax">, </span><spanclass="identifier-syntax">spec_union</span><spanclass="plain-syntax">);</span>
</pre>
<ulclass="endnotetexts"><li>This code is used in <ahref="5-cg.html#SP21">§21</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP21_3_1"class="paragraph-anchor"></a><b>§21.3.1. </b>In some CGs, it doesn't matter if the lines do different things: for example,
in the CG_IS_COMMAND for the command verb TAKE, "inventory" (void determination
type) and "[things]" (single term determination type) can happily co-exist.
</p>
<pclass="commentary">CG_IS_VALUE and CG_IS_SUBJECT are also exceptions because they include grammars
associated with kinds, in which different CGLs may describe different specific
values of that kind. For example, the one for the kind <spanclass="extract"><spanclass="extract-syntax">K_number</span></span> might have one
CGL describing the number 17, and another describing 22. There's no good way to
take the union of those numbers.
</p>
<pclass="commentary"><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">It is now evident that the lines have incompatible determination types</span><spanclass="named-paragraph-number">21.3.1</span></span><spanclass="comment-syntax"> =</span>
<spanclass="plain-syntax"></span><spanclass="identifier-syntax">LOG</span><spanclass="plain-syntax">(</span><spanclass="string-syntax">"Offending CGL is $g in $G\n"</span><spanclass="plain-syntax">, </span><spanclass="identifier-syntax">cgl</span><spanclass="plain-syntax">, </span><spanclass="identifier-syntax">cg</span><spanclass="plain-syntax">);</span>
<spanclass="plain-syntax"></span><spanclass="string-syntax">"grammar tokens must have the same outcome whatever the way they are reached"</span><spanclass="plain-syntax">,</span>
<spanclass="plain-syntax"></span><spanclass="string-syntax">"so writing a line like 'Understand \"within\" or \"next to [something]\" "</span>
<spanclass="plain-syntax"></span><spanclass="string-syntax">"as \"[my token]\" must be wrong: one way it produces a thing, the other "</span>
<spanclass="plain-syntax"></span><spanclass="string-syntax">"way it doesn't."</span><spanclass="plain-syntax">);</span>
<ulclass="endnotetexts"><li>This code is used in <ahref="5-cg.html#SP21_3">§21.3</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP21_4"class="paragraph-anchor"></a><b>§21.4. </b><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">Cache the answer so that we need not determine it again</span><spanclass="named-paragraph-number">21.4</span></span><spanclass="comment-syntax"> =</span>
<ulclass="endnotetexts"><li>This code is used in <ahref="5-cg.html#SP21">§21</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP22"class="paragraph-anchor"></a><b>§22. Sorting. </b>The list of lines in a CG needs to be sorted into order before compilation,
to ensure that the player's commands are interpreted correctly whatever order
in which the designer wrote the "Understand... as..." sentences setting it up.