1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-03 07:24:58 +03:00
inform7/docs/values-module/3-lp.html
2022-04-28 17:37:28 +01:00

1792 lines
361 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Literal Patterns</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<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">
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<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>
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Preform-Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-assets/Inform.png" height=72">
</a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../indocn.html">indoc</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
<li><a href="../inrtpsn.html">inrtps</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=18> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="../../../inweb/index.html">inweb</a></li>
<li><a href="../../../intest/index.html">intest</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Literal Patterns' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inform7n.html">Inform7</a></li><li><a href="index.html">values</a></li><li><a href="index.html#3">Chapter 3: Literals</a></li><li><b>Literal Patterns</b></li></ul></div>
<p class="purpose">To manage the possible notations with which literal values can be written.</p>
<ul class="toc"><li><a href="3-lp.html#SP7">&#167;7. Creating patterns, tokens and elements</a></li><li><a href="3-lp.html#SP10">&#167;10. Listing LPs</a></li><li><a href="3-lp.html#SP15">&#167;15. Optional break points</a></li><li><a href="3-lp.html#SP16">&#167;16. Matching an LP in the source text</a></li><li><a href="3-lp.html#SP17">&#167;17. Indexing literal patterns for a given kind</a></li><li><a href="3-lp.html#SP20">&#167;20. Printing values in an LP's notation to the index at compile-time</a></li><li><a href="3-lp.html#SP27">&#167;27. I7 phrases to print values in specified ways</a></li><li><a href="3-lp.html#SP28">&#167;28. I7 phrases to pack and unpack the value</a></li><li><a href="3-lp.html#SP29">&#167;29. The kind's list</a></li><li><a href="3-lp.html#SP31">&#167;31. Literal patterns in Preform</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. </b>Literal patterns (LPs) allow an author to create new notations for
quasi-numerical kinds of value. For example,
</p>
<blockquote>
<p>16:9 specifies an aspect ratio.</p>
</blockquote>
<p class="commentary">establishes a new notation for writing literals of the kind "aspect ratios".
</p>
<p class="commentary">Each kind of value has a linked list of literal notations which can specify
it, if any. We sometimes need to iterate through the this list, and can do
so with the following macro:
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">LITERAL_FORMS_LOOP</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax"> = </span><a href="3-lp.html#SP30" class="function-link"><span class="function-syntax">LiteralPatterns::list_of_literal_forms</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">); </span><span class="identifier-syntax">lp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">=</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_for_this_kind</span><span class="plain-syntax">)</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>LPs with just a single numerical part to them (like "20 yards" rather than
"16:9") are of special interest for holding scientific measurements, and
we provide elaborate extra features for this form of LP.
</p>
<p class="commentary">A given kind can have many different LPs to represent it, and this is
especially convenient for physics &mdash; it means we can give ways to describe
mass (a kind of value) in grams, kilograms or tonnes (all literal patterns).
Among these, one LP is special and is called the "benchmark" for the kind &mdash;
it is the default notation, the one considered most natural, and other LPs for
the same kind are scaled relative to this. For instance, the benchmark for
mass might be the notation "1 kg"; the notations "1 g" and "1 tonne" would
then be scaled down by 1000, and up by 1000, respectively.
</p>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>Syntactically, a literal pattern is a series of "tokens", of which more
below. Some tokens are simply fixed lettering or wording, but at least one
must be numerical, and called an "element". For example, "16:9" has three
tokens &mdash; element, fixed <span class="extract"><span class="extract-syntax">:</span></span>, element.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_ELEMENTS_PER_LITERAL</span><span class="plain-syntax"> </span><span class="constant-syntax">8</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">MAX_TOKENS_PER_LITERAL</span><span class="plain-syntax"> </span><span class="constant-syntax">100</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_specified</span><span class="plain-syntax">; </span><span class="comment-syntax"> the kind of the result: i.e., what it specifies</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_for_this_kind</span><span class="plain-syntax">; </span><span class="comment-syntax"> continuing list for this kind</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">prototype_text</span><span class="plain-syntax">; </span><span class="comment-syntax"> where the prototype specification is</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_lp_tokens</span><span class="plain-syntax">; </span><span class="comment-syntax"> number of tokens in parse_node</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_token</span><span class="plain-syntax"> </span><span class="identifier-syntax">lp_tokens</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_TOKENS_PER_LITERAL</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_lp_elements</span><span class="plain-syntax">; </span><span class="comment-syntax"> how many tokens are numbers</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_element</span><span class="plain-syntax"> </span><span class="identifier-syntax">lp_elements</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_ELEMENTS_PER_LITERAL</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">number_signed</span><span class="plain-syntax">; </span><span class="comment-syntax"> for instance -10 cm would be allowed if this is set</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> used when we have a sequence of alternative notations for the same unit</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">primary_alternative</span><span class="plain-syntax">; </span><span class="comment-syntax"> first of a set of alternatives?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_alternative_lp</span><span class="plain-syntax">; </span><span class="comment-syntax"> continuing list of alternatives</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">singular_form_only</span><span class="plain-syntax">; </span><span class="comment-syntax"> print using this notation only for 1 unit</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">plural_form_only</span><span class="plain-syntax">; </span><span class="comment-syntax"> print using this notation for 2 units, 0.5 units, etc.</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> used when printing and calculating values</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="identifier-syntax">scaling</span><span class="plain-syntax">; </span><span class="comment-syntax"> how to convert apparent to actual values</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">equivalent_unit</span><span class="plain-syntax">; </span><span class="comment-syntax"> is this just an equivalent to another LP?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">benchmark</span><span class="plain-syntax">; </span><span class="comment-syntax"> is this the benchmark LP for its kind?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">last_resort</span><span class="plain-syntax">; </span><span class="comment-syntax"> is this the last possible LP to use when printing a value of the kind?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">marked_for_printing</span><span class="plain-syntax">; </span><span class="comment-syntax"> used in compiling printing routines</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">literal_pattern_compilation_data</span><span class="plain-syntax"> </span><span class="identifier-syntax">compilation_data</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure literal_pattern is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>There are three sorts of token: character, word and element. Each token can
be a whole word, or only part of a word. For instance, in
</p>
<blockquote>
<p>28kg net specifies a weight.</p>
</blockquote>
<p class="commentary">we have a sequence of four tokens: an element token, marked as beginning a
word; a character token <span class="extract"><span class="extract-syntax">k</span></span>; a character token <span class="extract"><span class="extract-syntax">g</span></span>; and a word token <span class="extract"><span class="extract-syntax">net</span></span>,
which necessarily begins a word. Word boundaries in the source text must
match those in the specification, so this notation does not match the text
"41 kg net", for instance.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">WORD_LPT</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">CHARACTER_LPT</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">ELEMENT_LPT</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_token</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">new_word_at</span><span class="plain-syntax">; </span><span class="comment-syntax"> does token start a new word?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">lpt_type</span><span class="plain-syntax">; </span><span class="comment-syntax"> one of the three constants defined above</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">token_char</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">CHARACTER_LPT</span></span><span class="comment-syntax"> only; the character to match</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">token_wn</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">WORD_LPT</span></span><span class="comment-syntax"> only; word number in source text of the prototype</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">literal_pattern_token</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure literal_pattern_token is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>A value notated this way is like an old-school Pascal packed integer,
where a small data structure was joined into a single word of data. For
instance, in the "16:9" example, \(e_0:e_1\) would be stored as
\(e_0r_1+e_1\) where \(r_1 = 10\) is one more than the maximum value of \(e_1\).
So "4:3" would be stored as \(4\cdot(9+1) + 3 = 43\).
</p>
<p class="commentary">More formally, we call the numbers in such a literal its "elements". In the
case of "16:9", there are two elements, \(e_0 = 16\) and \(e_1 = 9\). The general
formula is:
$$ N = \sum_{i=0}^{n-1} e_i\cdot \prod_{j&gt;i} r_j $$
where \((e_0, e_1, ..., e_{n-1})\) are the values and \(r_j\), the "range",
is the constraint such that \(0\leq e_j &lt; r_j\).
Note that \(r_0\) is never required, since \(e_0\) is constrained in size only
by the need for \(N\) to fit into a single virtual machine integer. The value
$$ m_i = \prod_{j&gt;i} r_j $$
is called the "multiplier", and note that \(m_{n-1} = 1\). Conversely,
\(e_i = N/m_0\) if \(i=0\), and \(N/m_i {\rm ~mod~} r_i\) otherwise.
The rightmost element \(e_{n-1}\) is the least significant numerically.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_element</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">element_index</span><span class="plain-syntax">; </span><span class="comment-syntax"> the value </span>\(i\)<span class="comment-syntax"> placing this within its LP, where </span>\(0\leq i&lt;n\)
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">element_range</span><span class="plain-syntax">; </span><span class="comment-syntax"> the value </span>\(r_i\)<span class="comment-syntax"> for this LP</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">element_multiplier</span><span class="plain-syntax">; </span><span class="comment-syntax"> the value </span>\(m_i\)<span class="comment-syntax"> for this LP</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">element_name</span><span class="plain-syntax">; </span><span class="comment-syntax"> if we define a name for the element</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">is_real</span><span class="plain-syntax">; </span><span class="comment-syntax"> store as a real number, not an integer?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">without_leading_zeros</span><span class="plain-syntax">; </span><span class="comment-syntax"> normally without?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">element_optional</span><span class="plain-syntax">; </span><span class="comment-syntax"> can we truncate the LP here?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">preamble_optional</span><span class="plain-syntax">; </span><span class="comment-syntax"> if so, can we lose the preamble as well?</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">literal_pattern_element</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure literal_pattern_element is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>For the sake of printing, we can specify which notation is to be used in
printing a value back. For instance,
</p>
<blockquote>
<p>1 tonne (in tonnes, singular) specifies a mass scaled up by 1000.</p>
</blockquote>
<p class="commentary">assigns the name "in tonnes" to this notation for writing a mass. There can
be several notation associated with "in tonnes":
</p>
<blockquote>
<p>2 tonnes (in tonnes, plural) specifies a mass scaled up by 1000.</p>
</blockquote>
<p class="commentary">and hence the linked list of LPs associated with a single "literal pattern
name". Moreover, a given kind of value can support multiple named notations;
mass might also support "in kilograms" and "in grams", for instance.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_name</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">notation_name</span><span class="plain-syntax">; </span><span class="comment-syntax"> name for this notation, if any; e.g. "in centimetres"</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">can_use_this_lp</span><span class="plain-syntax">; </span><span class="comment-syntax"> list of LPs used under this name</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next</span><span class="plain-syntax">; </span><span class="comment-syntax"> other names for the same kind</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_with_rp</span><span class="plain-syntax">; </span><span class="comment-syntax"> used in parsing only: list applied to one notation</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">lpn_compiled_already</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">literal_pattern_name</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure literal_pattern_name is accessed in 2/rvl, 2/lvl, 2/cnd, 2/dsc, 4/teav, 4/cap, 4/inv, 4/pi, 5/dsh and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. Creating patterns, tokens and elements. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="function-syntax">LiteralPatterns::lp_new</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">LiteralPatterns::lp_new</span></span>:<br/><a href="3-lp.html#SP24_7">&#167;24.7</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">plural_form_only</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">singular_form_only</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_specified</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">prototype_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">W</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_for_this_kind</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">primary_alternative</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_alternative_lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_lp_elements</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_lp_tokens</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">number_signed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::Scalings::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="identifier-syntax">LP_SCALED_AT</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">.0, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">.0);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">equivalent_unit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">benchmark</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">compilation_data</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RTLiteralPatterns::new_compilation_data</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">literal_pattern_token</span><span class="plain-syntax"> </span><span class="function-syntax">LiteralPatterns::lpt_new</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">LiteralPatterns::lpt_new</span></span>:<br/><a href="3-lp.html#SP24_8">&#167;24.8</a>, <a href="3-lp.html#SP24_8_1">&#167;24.8.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">nw</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_token</span><span class="plain-syntax"> </span><span class="identifier-syntax">lpt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lpt</span><span class="plain-syntax">.</span><span class="element-syntax">new_word_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nw</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lpt</span><span class="plain-syntax">.</span><span class="element-syntax">lpt_type</span><span class="plain-syntax"> = </span><span class="identifier-syntax">t</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lpt</span><span class="plain-syntax">.</span><span class="element-syntax">token_char</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lpt</span><span class="plain-syntax">.</span><span class="element-syntax">token_wn</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">lpt</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">literal_pattern_element</span><span class="plain-syntax"> </span><span class="function-syntax">LiteralPatterns::lpe_new</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">LiteralPatterns::lpe_new</span></span>:<br/><a href="3-lp.html#SP24_8_1">&#167;24.8.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">r</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">sgn</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_element</span><span class="plain-syntax"> </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">.</span><span class="element-syntax">element_range</span><span class="plain-syntax"> = -1; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">.</span><span class="element-syntax">element_range</span><span class="plain-syntax"> = </span><span class="identifier-syntax">r</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">.</span><span class="element-syntax">element_multiplier</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">.</span><span class="element-syntax">element_index</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">.</span><span class="element-syntax">element_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">.</span><span class="element-syntax">preamble_optional</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">.</span><span class="element-syntax">element_optional</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">.</span><span class="element-syntax">without_leading_zeros</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. Listing LPs. </b>A routine to append a LP to the linked list of LPs for a given kind. But
it's a little more involved because this is where we calculate the scale
factors which relate LPs in the list, and also because we need to keep the
list in a particular order.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">PM_ZMachineOverflow2_issued</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="function-syntax">LiteralPatterns::list_add</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">LiteralPatterns::list_add</span></span>:<br/><a href="3-lp.html#SP29">&#167;29</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">list_head</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">new_lp</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">using_integer_scaling</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">list_head</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP10_1" class="named-paragraph-link"><span class="named-paragraph">Begin a new list with just the new LP in it</span><span class="named-paragraph-number">10.1</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP10_2" class="named-paragraph-link"><span class="named-paragraph">Add the new LP to the existing list</span><span class="named-paragraph-number">10.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP10_3" class="named-paragraph-link"><span class="named-paragraph">Correct the "last resort" flags in the list of LPs</span><span class="named-paragraph-number">10.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP10_4" class="named-paragraph-link"><span class="named-paragraph">Automatically enable signed literals if there are scaled LPs in the list</span><span class="named-paragraph-number">10.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">list_head</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10_1" class="paragraph-anchor"></a><b>&#167;10.1. </b>When the new LP is the first one, it can only be scaled in absolute terms:
"scaled at", which specifies its \(M\) value.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Begin a new list with just the new LP in it</span><span class="named-paragraph-number">10.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::Scalings::determine_M</span><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">new_lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">), </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="identifier-syntax">new_lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">equivalent_unit</span><span class="plain-syntax">, </span><span class="identifier-syntax">new_lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">primary_alternative</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">list_head</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_lp</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_2" class="paragraph-anchor"></a><b>&#167;10.2. </b>But if other LPs already exist, then absolute scalings are forbidden. The
new LP must be scaled up or down relative to existing notations, or pegged
equivalent to an exact value.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Add the new LP to the existing list</span><span class="named-paragraph-number">10.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">scaling_transformation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">benchmark_sc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">list_head</span><span class="plain-syntax">; </span><span class="identifier-syntax">lp</span><span class="plain-syntax">; </span><span class="identifier-syntax">lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_for_this_kind</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">benchmark</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">benchmark_sc</span><span class="plain-syntax"> = &amp;(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">scaling</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rescale_factor</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::Scalings::determine_M</span><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">new_lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">), </span><span class="identifier-syntax">benchmark_sc</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">new_lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">equivalent_unit</span><span class="plain-syntax">, </span><span class="identifier-syntax">new_lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">primary_alternative</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rescale_factor</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">list_head</span><span class="plain-syntax">; </span><span class="identifier-syntax">lp</span><span class="plain-syntax">; </span><span class="identifier-syntax">lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_for_this_kind</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">lp</span><span class="plain-syntax"> != </span><span class="identifier-syntax">new_lp</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">equivalent_unit</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::Scalings::enlarge</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">, </span><span class="identifier-syntax">rescale_factor</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">list_head</span><span class="plain-syntax"> = </span><a href="3-lp.html#SP11" class="function-link"><span class="function-syntax">LiteralPatterns::lp_list_add_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">list_head</span><span class="plain-syntax">, </span><span class="identifier-syntax">new_lp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">TargetVMs::is_16_bit</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::vm</span><span class="plain-syntax">())) &amp;&amp; (</span><span class="identifier-syntax">PM_ZMachineOverflow2_issued</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">list_head</span><span class="plain-syntax">; </span><span class="identifier-syntax">lp</span><span class="plain-syntax">; </span><span class="identifier-syntax">lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_for_this_kind</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Scalings::quantum</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">32767</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_ZMachineOverflow2</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"you've set up literal specifications needing a range of "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"values too broad to be stored at run-time"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"at least with the Settings for this project as they currently are. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"(Change to Glulx to be allowed to use much larger numbers; "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"or for really enormous values, use real arithmetic.)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PM_ZMachineOverflow2_issued</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_3" class="paragraph-anchor"></a><b>&#167;10.3. </b>Within the list, exactly one LP is marked with the <span class="extract"><span class="extract-syntax">last_resort</span></span> flag: the
last one not marked as an equivalent unit. (You can only be equivalent to
something already there, so it's not possible for all the LPs in the list to
be equivalent.)
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Correct the "last resort" flags in the list of LPs</span><span class="named-paragraph-number">10.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lp</span><span class="plain-syntax">, *</span><span class="identifier-syntax">last_resorter</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">list_head</span><span class="plain-syntax">; </span><span class="identifier-syntax">lp</span><span class="plain-syntax">; </span><span class="identifier-syntax">lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_for_this_kind</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_resort</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">equivalent_unit</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="identifier-syntax">last_resorter</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">last_resorter</span><span class="plain-syntax">) </span><span class="identifier-syntax">last_resorter</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_resort</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_4" class="paragraph-anchor"></a><b>&#167;10.4. </b>Inform is ordinarily a bit picky about not allowing negative values within
these notations, unless they have explicitly been defined to allow it. That
makes sense for basically combinatorial notations (room 1 to room 64, say)
but would be a nonsense for scientific measurements where we intend to perform
arithmetic. So:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Automatically enable signed literals if there are scaled LPs in the list</span><span class="named-paragraph-number">10.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">scalings_exist</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">list_head</span><span class="plain-syntax">; </span><span class="identifier-syntax">lp</span><span class="plain-syntax">; </span><span class="identifier-syntax">lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_for_this_kind</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Scalings::involves_scale_change</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">scalings_exist</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">scalings_exist</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">list_head</span><span class="plain-syntax">; </span><span class="identifier-syntax">lp</span><span class="plain-syntax">; </span><span class="identifier-syntax">lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_for_this_kind</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">number_signed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>The actual insertion of the new LP into the list is carried out here, and
is complicated by the fact that we need to keep these in a special order.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="function-syntax">LiteralPatterns::lp_list_add_inner</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">LiteralPatterns::lp_list_add_inner</span></span>:<br/><a href="3-lp.html#SP10_2">&#167;10.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">list_head</span><span class="plain-syntax">, </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">new_lp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lp</span><span class="plain-syntax">, *</span><span class="identifier-syntax">lp_prev</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_for_this_kind</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">list_head</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">new_lp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">list_head</span><span class="plain-syntax">; </span><span class="identifier-syntax">lp_prev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-lp.html#SP12" class="function-link"><span class="function-syntax">LiteralPatterns::lp_precedes</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new_lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_for_this_kind</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp_prev</span><span class="plain-syntax">) </span><span class="identifier-syntax">lp_prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_for_this_kind</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_lp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">list_head</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_lp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">list_head</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp_prev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_for_this_kind</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp_prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_for_this_kind</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_lp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">list_head</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. </b>Highly scaled values come before less scaled ones; otherwise plural forms
come before singular ones; and otherwise an earlier-defined LP comes before
a later one.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">LiteralPatterns::lp_precedes</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">LiteralPatterns::lp_precedes</span></span>:<br/><a href="3-lp.html#SP11">&#167;11</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">A</span><span class="plain-syntax">, </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">B</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::Scalings::compare</span><span class="plain-syntax">(</span><span class="identifier-syntax">A</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">, </span><span class="identifier-syntax">B</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">s</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">s</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">A</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">primary_alternative</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">B</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">primary_alternative</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">A</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">primary_alternative</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">B</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">primary_alternative</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">A</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">plural_form_only</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">B</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">plural_form_only</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">A</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">plural_form_only</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">B</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">plural_form_only</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">A</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">singular_form_only</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">B</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">singular_form_only</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">A</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">singular_form_only</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">B</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">singular_form_only</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">A</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">B</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. </b>One member of the list is the "benchmark", as noted above.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="function-syntax">LiteralPatterns::get_benchmark</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">LiteralPatterns::get_benchmark</span></span>:<br/><a href="3-lp.html#SP14">&#167;14</a>, <a href="3-lp.html#SP17">&#167;17</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LITERAL_FORMS_LOOP</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">benchmark</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. </b>And this returns the multiplier of the benchmark, which is important for
performing multiplications.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">DETERMINE_SCALE_FACTOR_KINDS_CALLBACK</span><span class="plain-syntax"> </span><a href="3-lp.html#SP14" class="function-link"><span class="function-syntax">LiteralPatterns::scale_factor</span></a>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">LiteralPatterns::scale_factor</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax"> = </span><a href="3-lp.html#SP13" class="function-link"><span class="function-syntax">LiteralPatterns::get_benchmark</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::Scalings::get_integer_multiplier</span><span class="plain-syntax">(</span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. Optional break points. </b>Sometimes the pattern allows later numerical elements to be skipped, in which
case they are understood to be 0.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">LiteralPatterns::at_optional_break_point</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">LiteralPatterns::at_optional_break_point</span></span>:<br/><a href="3-lp.html#SP16_1">&#167;16.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ec</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">tc</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">ec</span><span class="function-syntax">&lt;lp-&gt;</span><span class="element-syntax">no_lp_elements</span><span class="plain-syntax">) &amp;&amp; </span><span class="comment-syntax"> i.e., if there are still numerical elements to supply</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_elements</span><span class="plain-syntax">[</span><span class="identifier-syntax">ec</span><span class="plain-syntax">].</span><span class="element-syntax">element_optional</span><span class="plain-syntax">) &amp;&amp; </span><span class="comment-syntax"> but which are optional</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_elements</span><span class="plain-syntax">[</span><span class="identifier-syntax">ec</span><span class="plain-syntax">].</span><span class="element-syntax">preamble_optional</span><span class="plain-syntax">) || </span><span class="comment-syntax"> and either the preamble tokens are also optional</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_tokens</span><span class="plain-syntax">[</span><span class="identifier-syntax">tc</span><span class="plain-syntax">].</span><span class="element-syntax">lpt_type</span><span class="plain-syntax"> == </span><span class="constant-syntax">ELEMENT_LPT</span><span class="plain-syntax">))) </span><span class="comment-syntax"> or we're at the number token</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. Matching an LP in the source text. </b>Given an excerpt <span class="extract"><span class="extract-syntax">(w1, w2)</span></span>, we try to parse it as a constant value written
in the LP notation: if it passes, we return the kind of value, and if not
we return <span class="extract"><span class="extract-syntax">NULL</span></span>.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">waive_lp_overflows</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">last_LP_problem_at</span><span class="plain-syntax"> = -1;</span>
<span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="identifier-syntax">latest_constructed_real</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">.0;</span>
<span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="function-syntax">LiteralPatterns::get_latest_real</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">latest_constructed_real</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="function-syntax">LiteralPatterns::match</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">LiteralPatterns::match</span></span>:<br/><a href="3-lp.html#SP31">&#167;31</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">found</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">matched_number</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">overflow_16_bit_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">overflow_32_bit_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_element</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sign_used_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">element_overflow_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> if the excerpt is longer than the maximum length of such a notation, give up quickly:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::length</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">) &gt; </span><span class="identifier-syntax">Wordings::length</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">prototype_text</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP16_1" class="named-paragraph-link"><span class="named-paragraph">Try to match the excerpt against the whole prototype or up to an optional break</span><span class="named-paragraph-number">16.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sign_used_at</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP16_2" class="named-paragraph-link"><span class="named-paragraph">Check that a negative number can be used in this notation</span><span class="named-paragraph-number">16.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">waive_lp_overflows</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">element_overflow_at</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP16_4" class="named-paragraph-link"><span class="named-paragraph">Report a problem because one element in the notation overflows</span><span class="named-paragraph-number">16.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP16_3" class="named-paragraph-link"><span class="named-paragraph">Check that the value found lies within the range which the VM can hold</span><span class="named-paragraph-number">16.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">found</span><span class="plain-syntax"> = </span><span class="identifier-syntax">matched_number</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_specified</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP16_1" class="paragraph-anchor"></a><b>&#167;16.1. </b>Scanning the tokens one at a time. The scan position is represented as a
word number <span class="extract"><span class="extract-syntax">wn</span></span> together with a character position within the word, <span class="extract"><span class="extract-syntax">wpos</span></span>.
The <span class="extract"><span class="extract-syntax">wpos</span></span> value \(-1\) means that word <span class="extract"><span class="extract-syntax">wn</span></span> has not yet been started.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Try to match the excerpt against the whole prototype or up to an optional break</span><span class="named-paragraph-number">16.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">tc</span><span class="plain-syntax">, </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">), </span><span class="identifier-syntax">wpos</span><span class="plain-syntax"> = -1, </span><span class="identifier-syntax">ec</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">matched_scaledown</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">parsed_as_real</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">wd</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lexer::word_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tc</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">tc</span><span class="function-syntax">&lt;lp-&gt;</span><span class="element-syntax">no_lp_tokens</span><span class="plain-syntax">; </span><span class="identifier-syntax">tc</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wn</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">wpos</span><span class="plain-syntax"> == -1) </span><span class="comment-syntax"> i.e., if we are cleanly at a word boundary</span>
<span class="plain-syntax"> &amp;&amp; (</span><a href="3-lp.html#SP15" class="function-link"><span class="function-syntax">LiteralPatterns::at_optional_break_point</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">ec</span><span class="plain-syntax">, </span><span class="identifier-syntax">tc</span><span class="plain-syntax">))) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_tokens</span><span class="plain-syntax">[</span><span class="identifier-syntax">tc</span><span class="plain-syntax">].</span><span class="element-syntax">lpt_type</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">WORD_LPT:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP16_1_1" class="named-paragraph-link"><span class="named-paragraph">Match a fixed word token within a literal pattern</span><span class="named-paragraph-number">16.1.1</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CHARACTER_LPT:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP16_1_2" class="named-paragraph-link"><span class="named-paragraph">Match a character token within a literal pattern</span><span class="named-paragraph-number">16.1.2</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">ELEMENT_LPT:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP16_1_3" class="named-paragraph-link"><span class="named-paragraph">Match an element token within a literal pattern</span><span class="named-paragraph-number">16.1.3</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"unknown literal pattern token type"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wpos</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> we need to end cleanly, not in mid-word</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wn</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> and we need to have used up all of the excerpt</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parsed_as_real</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">loses_accuracy</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::Scalings::contract</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">, </span><span class="identifier-syntax">matched_scaledown</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">loses_accuracy</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">matched_number</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::Scalings::quanta_to_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">sc</span><span class="plain-syntax">, </span><span class="identifier-syntax">matched_number</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">loses_accuracy</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP16_1_4" class="named-paragraph-link"><span class="named-paragraph">Report a problem because not enough accuracy is available</span><span class="named-paragraph-number">16.1.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">long</span><span class="plain-syntax"> </span><span class="reserved-syntax">long</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">max_16_bit</span><span class="plain-syntax"> = </span><span class="constant-syntax">32767</span><span class="identifier-syntax">LL</span><span class="plain-syntax">, </span><span class="identifier-syntax">max_32_bit</span><span class="plain-syntax"> = </span><span class="constant-syntax">2147483647</span><span class="identifier-syntax">LL</span><span class="plain-syntax">, </span><span class="identifier-syntax">min_32_bit</span><span class="plain-syntax"> = -2147483648</span><span class="identifier-syntax">LL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">matched_number</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">max_16_bit</span><span class="plain-syntax">) </span><span class="identifier-syntax">overflow_16_bit_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">matched_number</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">max_32_bit</span><span class="plain-syntax">) </span><span class="identifier-syntax">overflow_32_bit_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">sign_used_at</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">overflow_32_bit_flag</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">matched_number</span><span class="plain-syntax"> == </span><span class="identifier-syntax">min_32_bit</span><span class="plain-syntax">) </span><span class="identifier-syntax">overflow_32_bit_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">matched_number</span><span class="plain-syntax"> = -</span><span class="identifier-syntax">matched_number</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">pragma</span><span class="plain-syntax"> </span><span class="identifier-syntax">clang</span><span class="plain-syntax"> </span><span class="identifier-syntax">diagnostic</span><span class="plain-syntax"> </span><span class="identifier-syntax">push</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">pragma</span><span class="plain-syntax"> </span><span class="identifier-syntax">clang</span><span class="plain-syntax"> </span><span class="identifier-syntax">diagnostic</span><span class="plain-syntax"> </span><span class="identifier-syntax">ignored</span><span class="plain-syntax"> </span><span class="string-syntax">"-Wsign-conversion"</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sign_used_at</span><span class="plain-syntax">) </span><span class="identifier-syntax">matched_number</span><span class="plain-syntax"> = </span><span class="identifier-syntax">matched_number</span><span class="plain-syntax"> | </span><span class="constant-syntax">0x80000000</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">pragma</span><span class="plain-syntax"> </span><span class="identifier-syntax">clang</span><span class="plain-syntax"> </span><span class="identifier-syntax">diagnostic</span><span class="plain-syntax"> </span><span class="identifier-syntax">pop</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP16">&#167;16</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP16_1_1" class="paragraph-anchor"></a><b>&#167;16.1.1. </b>A word token matches an exact word (but allowing for variation in casing).
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Match a fixed word token within a literal pattern</span><span class="named-paragraph-number">16.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wpos</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> if we're still in the middle of the last word, we must fail</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">compare_words</span><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_tokens</span><span class="plain-syntax">[</span><span class="identifier-syntax">tc</span><span class="plain-syntax">].</span><span class="element-syntax">token_wn</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax">++;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP16_1">&#167;16.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP16_1_2" class="paragraph-anchor"></a><b>&#167;16.1.2. </b>A character token matches only a single character &mdash; note the case insensitivity
here, because of the use of <span class="extract"><span class="extract-syntax">tolower</span></span>.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Match a character token within a literal pattern</span><span class="named-paragraph-number">16.1.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wpos</span><span class="plain-syntax"> == -1) { </span><span class="identifier-syntax">wpos</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">wd</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lexer::word_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">); } </span><span class="comment-syntax"> start parsing the interior of a word</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Characters::tolower</span><span class="plain-syntax">(</span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">++]) != </span><span class="identifier-syntax">Characters::tolower</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_tokens</span><span class="plain-syntax">[</span><span class="identifier-syntax">tc</span><span class="plain-syntax">].</span><span class="element-syntax">token_char</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">] == </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">wn</span><span class="plain-syntax">++; </span><span class="identifier-syntax">wpos</span><span class="plain-syntax"> = -1; } </span><span class="comment-syntax"> and stop parsing the interior of a word</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP16_1">&#167;16.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP16_1_3" class="paragraph-anchor"></a><b>&#167;16.1.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Match an element token within a literal pattern</span><span class="named-paragraph-number">16.1.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_element</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lpe</span><span class="plain-syntax"> = &amp;(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_elements</span><span class="plain-syntax">[</span><span class="identifier-syntax">ec</span><span class="plain-syntax">++]); </span><span class="comment-syntax"> fetch details of next number</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wpos</span><span class="plain-syntax"> == -1) { </span><span class="identifier-syntax">wpos</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">wd</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lexer::word_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">); } </span><span class="comment-syntax"> start parsing the interior of a word</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">] == </span><span class="character-syntax">'-'</span><span class="plain-syntax">) { </span><span class="identifier-syntax">sign_used_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">; </span><span class="identifier-syntax">wpos</span><span class="plain-syntax">++; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::FloatingPoint::uses_floating_point</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_specified</span><span class="plain-syntax">)) </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP16_1_3_2" class="named-paragraph-link"><span class="named-paragraph">Match a real number element token</span><span class="named-paragraph-number">16.1.3.2</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP16_1_3_1" class="named-paragraph-link"><span class="named-paragraph">Match an integer number element token</span><span class="named-paragraph-number">16.1.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">] == </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">wn</span><span class="plain-syntax">++; </span><span class="identifier-syntax">wpos</span><span class="plain-syntax"> = -1; } </span><span class="comment-syntax"> and stop parsing the interior of a word</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP16_1">&#167;16.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP16_1_3_1" class="paragraph-anchor"></a><b>&#167;16.1.3.1. </b>There are three different sorts of overflow:
</p>
<ul class="items"><li>(1) The calculation of the packed value exceeding the range which an integer
can store on a 16-bit virtual machine;
</li><li>(2) Ditto, but on a 32-bit virtual machine; and
</li><li>(3) One of the numerical elements inside the notation being given out of range.
</li></ul>
<p class="commentary">We report none of these as a problem immediately &mdash; only if the pattern would
otherwise match.
</p>
<p class="commentary">The following assumes that <span class="extract"><span class="extract-syntax">long long int</span></span> is at least 64-bit, so that it
can hold any 32-bit integer multiplied by 10, and also any product of two
32-bit numbers. This is true for all modern <span class="extract"><span class="extract-syntax">gcc</span></span> implementations and is
required by PM_, but was not required by C90, so it is just possible that
this could cause trouble on unusual platforms.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Match an integer number element token</span><span class="named-paragraph-number">16.1.3.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">long</span><span class="plain-syntax"> </span><span class="reserved-syntax">long</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">tot</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">max_32_bit</span><span class="plain-syntax">, </span><span class="identifier-syntax">max_16_bit</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">digits_found</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">point_at</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">max_16_bit</span><span class="plain-syntax"> = </span><span class="constant-syntax">32767</span><span class="identifier-syntax">LL</span><span class="plain-syntax">; </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sign_used_at</span><span class="plain-syntax">) </span><span class="identifier-syntax">max_16_bit</span><span class="plain-syntax"> = </span><span class="constant-syntax">32768</span><span class="identifier-syntax">LL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">max_32_bit</span><span class="plain-syntax"> = </span><span class="constant-syntax">2147483647</span><span class="identifier-syntax">LL</span><span class="plain-syntax">; </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sign_used_at</span><span class="plain-syntax">) </span><span class="identifier-syntax">max_32_bit</span><span class="plain-syntax"> = </span><span class="constant-syntax">2147483648</span><span class="identifier-syntax">LL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Characters::isdigit</span><span class="plain-syntax">(</span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">])) ||</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">] == </span><span class="character-syntax">'.'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Kinds::Scalings::get_integer_multiplier</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">point_at</span><span class="plain-syntax"> == -1))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">] == </span><span class="character-syntax">'.'</span><span class="plain-syntax">) { </span><span class="identifier-syntax">point_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">digits_found</span><span class="plain-syntax">; </span><span class="identifier-syntax">wpos</span><span class="plain-syntax">++; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">tot</span><span class="plain-syntax"> = </span><span class="constant-syntax">10</span><span class="plain-syntax">*</span><span class="identifier-syntax">tot</span><span class="plain-syntax"> + (</span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">++] - </span><span class="character-syntax">'0'</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tot</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">max_16_bit</span><span class="plain-syntax">) </span><span class="identifier-syntax">overflow_16_bit_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tot</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">max_32_bit</span><span class="plain-syntax">) </span><span class="identifier-syntax">overflow_32_bit_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">digits_found</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">point_at</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">point_at</span><span class="plain-syntax"> == </span><span class="identifier-syntax">digits_found</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">digits_found</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">point_at</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">point_at</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">digits_found</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">matched_scaledown</span><span class="plain-syntax"> *= </span><span class="constant-syntax">10</span><span class="plain-syntax">; </span><span class="identifier-syntax">point_at</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">tot</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_range</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_index</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)) </span><span class="identifier-syntax">element_overflow_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">tot</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_multiplier</span><span class="plain-syntax">)*</span><span class="identifier-syntax">tot</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tot</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">max_16_bit</span><span class="plain-syntax">) </span><span class="identifier-syntax">overflow_16_bit_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tot</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">max_32_bit</span><span class="plain-syntax">) </span><span class="identifier-syntax">overflow_32_bit_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">tot</span><span class="plain-syntax"> = </span><span class="identifier-syntax">matched_number</span><span class="plain-syntax"> + </span><span class="identifier-syntax">tot</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tot</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">max_16_bit</span><span class="plain-syntax">) </span><span class="identifier-syntax">overflow_16_bit_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tot</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">max_32_bit</span><span class="plain-syntax">) </span><span class="identifier-syntax">overflow_32_bit_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">matched_number</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">tot</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP16_1_3">&#167;16.1.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP16_1_3_2" class="paragraph-anchor"></a><b>&#167;16.1.3.2. </b>In real arithmetic, though, overflow isn't a problem, since we can use the
infinities to represent arbitrarily large numbers.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Match a real number element token</span><span class="named-paragraph-number">16.1.3.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">real_buffer</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">point_at</span><span class="plain-syntax"> = -1, </span><span class="identifier-syntax">mult_at</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Characters::isdigit</span><span class="plain-syntax">(</span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">])) || ((</span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">] == </span><span class="character-syntax">'.'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">point_at</span><span class="plain-syntax"> == -1))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">] == </span><span class="character-syntax">'.'</span><span class="plain-syntax">) </span><span class="identifier-syntax">point_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">real_buffer</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">real_buffer</span><span class="plain-syntax">, </span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">++]);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">real_buffer</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">point_at</span><span class="plain-syntax"> == </span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">real_buffer</span><span class="plain-syntax">)-1)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-lrn.html#SP2" class="function-link"><span class="function-syntax">LiteralReals::ismultiplicationsign</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">])) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mult_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wpos</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">real_buffer</span><span class="plain-syntax">, </span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">++]);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">] == </span><span class="character-syntax">'1'</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">real_buffer</span><span class="plain-syntax">, </span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">++]); </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">] == </span><span class="character-syntax">'0'</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">real_buffer</span><span class="plain-syntax">, </span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">++]); </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">] == </span><span class="character-syntax">'^'</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">real_buffer</span><span class="plain-syntax">, </span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">++]); </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">] == </span><span class="character-syntax">'+'</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">real_buffer</span><span class="plain-syntax">, </span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">++]);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">] == </span><span class="character-syntax">'-'</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">real_buffer</span><span class="plain-syntax">, </span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">++]);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Characters::isdigit</span><span class="plain-syntax">(</span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">])) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">real_buffer</span><span class="plain-syntax">, </span><span class="identifier-syntax">wd</span><span class="plain-syntax">[</span><span class="identifier-syntax">wpos</span><span class="plain-syntax">++]);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Feeds::feed_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">real_buffer</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">real_buffer</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">point_at</span><span class="plain-syntax"> == -1) &amp;&amp; (</span><span class="identifier-syntax">mult_at</span><span class="plain-syntax"> == -1)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;cardinal-number&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">matched_number</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;r&gt;&gt;</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">signbit</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">matched_number</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">signbit</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="identifier-syntax">matched_number</span><span class="plain-syntax"> = -</span><span class="identifier-syntax">matched_number</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">matched_number</span><span class="plain-syntax"> = </span><a href="3-lrn.html#SP3" class="function-link"><span class="function-syntax">LiteralReals::construct_float</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">signbit</span><span class="plain-syntax">, </span><span class="identifier-syntax">matched_number</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;literal-real-in-digits&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">matched_number</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;r&gt;&gt;</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">latest_constructed_real</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::Scalings::real_quanta_to_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">, </span><span class="identifier-syntax">latest_constructed_real</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">signbit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">latest_constructed_real</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">latest_constructed_real</span><span class="plain-syntax"> = -</span><span class="identifier-syntax">latest_constructed_real</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">signbit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">matched_number</span><span class="plain-syntax"> = </span><a href="3-lrn.html#SP3" class="function-link"><span class="function-syntax">LiteralReals::construct_float</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">signbit</span><span class="plain-syntax">, </span><span class="identifier-syntax">latest_constructed_real</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parsed_as_real</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP16_1_3">&#167;16.1.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP16_2" class="paragraph-anchor"></a><b>&#167;16.2. </b>Problem messages here have a tendency to be repeated, in some situations,
which is annoying. So we have a mechanism to suppress duplicates:
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">ISSUING_LP_PROBLEM</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">last_LP_problem_at</span><span class="plain-syntax"> == </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_LP_problem_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Check that a negative number can be used in this notation</span><span class="named-paragraph-number">16.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::FloatingPoint::uses_floating_point</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_specified</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sign_used_at</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_index</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">ISSUING_LP_PROBLEM</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_NegationInternal</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"a negative number can't be used in the middle of a constant"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and the minus sign makes it look as if that's what you are "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"trying here."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">number_signed</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">ISSUING_LP_PROBLEM</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_NegationForbidden</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the minus sign is not allowed here"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"since this is a kind of value which only allows positive "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"values to be written."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP16">&#167;16</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP16_3" class="paragraph-anchor"></a><b>&#167;16.3. </b>The out of range problem messages:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Check that the value found lies within the range which the VM can hold</span><span class="named-paragraph-number">16.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">overflow_32_bit_flag</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">ISSUING_LP_PROBLEM</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EvenOverflow</span><span class="plain-syntax">-</span><span class="identifier-syntax">G</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"you use a literal specification to make a value which is too large"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"even for a story file compiled with the Glulx setting. (You can "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"see the size limits for each way of writing a value on the Kinds "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"page of the Index.)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">overflow_16_bit_flag</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">TargetVMs::is_16_bit</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::vm</span><span class="plain-syntax">()))) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">ISSUING_LP_PROBLEM</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_ZMachineOverflow</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"you use a literal specification to make a value which is too large"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"at least with the Settings for this project as they currently are. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"(Change to Glulx to be allowed to use much larger numbers; "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"meanwhile, you can see the size limits for each way of writing a "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"value on the Kinds page of the Index.)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP16">&#167;16</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP16_4" class="paragraph-anchor"></a><b>&#167;16.4. </b>The more specific problem of an internal overflow:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Report a problem because one element in the notation overflows</span><span class="named-paragraph-number">16.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">max</span><span class="plain-syntax"> = </span><span class="identifier-syntax">element_overflow_at</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_range</span><span class="plain-syntax"> - </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">prototype_text</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_number</span><span class="plain-syntax">(4, &amp;</span><span class="identifier-syntax">max</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">element_overflow_at</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">element_index</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">: </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(5, </span><span class="string-syntax">"first"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">: </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(5, </span><span class="string-syntax">"second"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">: </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(5, </span><span class="string-syntax">"third"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax">: </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(5, </span><span class="string-syntax">"fourth"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax">: </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(5, </span><span class="string-syntax">"fifth"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax">: </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(5, </span><span class="string-syntax">"sixth"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">6</span><span class="plain-syntax">: </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(5, </span><span class="string-syntax">"seventh"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">7</span><span class="plain-syntax">: </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(5, </span><span class="string-syntax">"eighth"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">8</span><span class="plain-syntax">: </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(5, </span><span class="string-syntax">"ninth"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">9</span><span class="plain-syntax">: </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(5, </span><span class="string-syntax">"tenth"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(5, </span><span class="string-syntax">"eventual"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_ElementOverflow</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"In the sentence %1, you use the notation '%2' to write a constant value. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"But the notation was specified as '%3', which means that the %5 numerical "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"part should range between 0 and %4."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP16">&#167;16</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP16_1_4" class="paragraph-anchor"></a><b>&#167;16.1.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Report a problem because not enough accuracy is available</span><span class="named-paragraph-number">16.1.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">prototype_text</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_LPTooLittleAccuracy</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"In the sentence %1, you use the notation '%2' to write a constant value. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"But to store that, I would need greater accuracy than this kind of "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"value has - see the Kinds page of the Index for the range it has."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP16_1">&#167;16.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. Indexing literal patterns for a given kind. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LiteralPatterns::index_all</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lp</span><span class="plain-syntax">, *</span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax"> = </span><a href="3-lp.html#SP13" class="function-link"><span class="function-syntax">LiteralPatterns::get_benchmark</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">B</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">scalings_exist</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax">) </span><span class="identifier-syntax">B</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::Scalings::get_integer_multiplier</span><span class="plain-syntax">(</span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LITERAL_FORMS_LOOP</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Scalings::involves_scale_change</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">scalings_exist</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP17_1" class="named-paragraph-link"><span class="named-paragraph">Index the list of possible LPs for the kind, not counting equivalents</span><span class="named-paragraph-number">17.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP17_2" class="named-paragraph-link"><span class="named-paragraph">Index the list of possible LPs for the kind, only counting equivalents</span><span class="named-paragraph-number">17.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP17_3" class="named-paragraph-link"><span class="named-paragraph">Index the possible names for these notations, as ways of printing them back</span><span class="named-paragraph-number">17.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP17_1" class="paragraph-anchor"></a><b>&#167;17.1. </b>Each entry in this list is, in principle, a list all by itself &mdash; of
alternatives such as "1 tonne" vs "2 tonnes", which aren't different
enough to be listed separately. Of these exactly one is the "primary"
alternative.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Index the list of possible LPs for the kind, not counting equivalents</span><span class="named-paragraph-number">17.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">f</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LITERAL_FORMS_LOOP</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">primary_alternative</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">equivalent_unit</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">f</span><span class="plain-syntax">) </span><span class="identifier-syntax">HTML_TAG</span><span class="plain-syntax">(</span><span class="string-syntax">"br"</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;i&gt;Written as:&lt;/i&gt;"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_TAG</span><span class="plain-syntax">(</span><span class="string-syntax">"br"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">scalings_exist</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><a href="3-lp.html#SP18" class="function-link"><span class="function-syntax">LiteralPatterns::index_lp_possibilities</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%+W"</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">prototype_text</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">f</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP17">&#167;17</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP17_2" class="paragraph-anchor"></a><b>&#167;17.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Index the list of possible LPs for the kind, only counting equivalents</span><span class="named-paragraph-number">17.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">f</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LITERAL_FORMS_LOOP</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">primary_alternative</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">equivalent_unit</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_TAG</span><span class="plain-syntax">(</span><span class="string-syntax">"br"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">f</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;i&gt;With these equivalent units:&lt;/i&gt;"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_TAG</span><span class="plain-syntax">(</span><span class="string-syntax">"br"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="3-lp.html#SP18" class="function-link"><span class="function-syntax">LiteralPatterns::index_lp_possibilities</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">f</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP17">&#167;17</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP17_3" class="paragraph-anchor"></a><b>&#167;17.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Index the possible names for these notations, as ways of printing them back</span><span class="named-paragraph-number">17.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">f</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lpn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">lpn</span><span class="plain-syntax">, </span><span class="reserved-syntax">literal_pattern_name</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">lpn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">notation_name</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LITERAL_FORMS_LOOP</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lpn2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lpn2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lpn</span><span class="plain-syntax">; </span><span class="identifier-syntax">lpn2</span><span class="plain-syntax">; </span><span class="identifier-syntax">lpn2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lpn2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">lpn2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">can_use_this_lp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">f</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"; "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_TAG</span><span class="plain-syntax">(</span><span class="string-syntax">"br"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"\n&lt;i&gt;Can be printed back:&lt;/i&gt;\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_TAG</span><span class="plain-syntax">(</span><span class="string-syntax">"br"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"\n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">f</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%+W"</span><span class="plain-syntax">, </span><span class="identifier-syntax">lpn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">notation_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">NextLPN</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NextLPN:</span><span class="plain-syntax"> ;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP17">&#167;17</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. </b>And here we list of alternatives followed by the relationship this notation
has to the benchmark, e.g., "where 1 tonne \(=\) 1000 kg".
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LiteralPatterns::index_lp_possibilities</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">LiteralPatterns::index_lp_possibilities</span></span>:<br/><a href="3-lp.html#SP17_1">&#167;17.1</a>, <a href="3-lp.html#SP17_2">&#167;17.2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lp.html#SP19" class="function-link"><span class="function-syntax">LiteralPatterns::index_lp_possibility</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">equivalent_unit</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" &lt;i&gt;where&lt;/i&gt; "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lp.html#SP22" class="function-link"><span class="function-syntax">LiteralPatterns::lp_index_quantum_value</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" = "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lp.html#SP22" class="function-link"><span class="function-syntax">LiteralPatterns::lp_index_quantum_value</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Scalings::compare</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">, </span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">) &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" &lt;i&gt;where&lt;/i&gt; "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lp.html#SP22" class="function-link"><span class="function-syntax">LiteralPatterns::lp_index_quantum_value</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" = "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lp.html#SP22" class="function-link"><span class="function-syntax">LiteralPatterns::lp_index_quantum_value</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Scalings::compare</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">, </span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" &lt;i&gt;where&lt;/i&gt; "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lp.html#SP22" class="function-link"><span class="function-syntax">LiteralPatterns::lp_index_quantum_value</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" = "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lp.html#SP22" class="function-link"><span class="function-syntax">LiteralPatterns::lp_index_quantum_value</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>&#167;19. </b>This is where the list of alternatives, "1 tonne" followed by "2 tonnes",
say, is produced:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LiteralPatterns::index_lp_possibility</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">LiteralPatterns::index_lp_possibility</span></span>:<br/><a href="3-lp.html#SP18">&#167;18</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;b&gt;"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">plural_form_only</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="3-lp.html#SP22" class="function-link"><span class="function-syntax">LiteralPatterns::lp_index_quantum_value</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">Kinds::Scalings::enlarge</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><a href="3-lp.html#SP22" class="function-link"><span class="function-syntax">LiteralPatterns::lp_index_quantum_value</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;/b&gt;"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_alternative_lp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" &lt;i&gt;or&lt;/i&gt; "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lp.html#SP19" class="function-link"><span class="function-syntax">LiteralPatterns::index_lp_possibility</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_alternative_lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">benchmark_lp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>&#167;20. Printing values in an LP's notation to the index at compile-time. </b>This front-end routine chooses the most appropriate notation to use when
indexing a given value. For instance, a mass of 1000000 is best expressed
as "1 tonne", not "1000000 grams".
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LiteralPatterns::index_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lp_list</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">v</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lp_possibility</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lp_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">lp</span><span class="plain-syntax">; </span><span class="identifier-syntax">lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_for_this_kind</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">v</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">benchmark</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="3-lp.html#SP22" class="function-link"><span class="function-syntax">LiteralPatterns::lp_index_value_specific</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">v</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">primary_alternative</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">equivalent_unit</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">lp_possibility</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">Kinds::Scalings::quantum</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">) != </span><span class="identifier-syntax">k</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp_possibility</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::Scalings::quantum</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">v</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">Kinds::Scalings::quantum</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><a href="3-lp.html#SP22" class="function-link"><span class="function-syntax">LiteralPatterns::lp_index_value_specific</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">v</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp_possibility</span><span class="plain-syntax">) </span><a href="3-lp.html#SP22" class="function-link"><span class="function-syntax">LiteralPatterns::lp_index_value_specific</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp_possibility</span><span class="plain-syntax">, </span><span class="identifier-syntax">v</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><a href="3-lp.html#SP22" class="function-link"><span class="function-syntax">LiteralPatterns::lp_index_value_specific</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp_list</span><span class="plain-syntax">, </span><span class="identifier-syntax">v</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>&#167;21. </b>Here we index the benchmark value. Pursuing our example of mass, if the
benchmark is 1 kilogram, then the following indexes the value 1000 in
kilograms, resulting in "1 kg". (This will always effectively look like
"1 something", whatever the something is.)
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LiteralPatterns::index_benchmark_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LITERAL_FORMS_LOOP</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">benchmark</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="3-lp.html#SP22" class="function-link"><span class="function-syntax">LiteralPatterns::lp_index_quantum_value</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"1"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP22" class="paragraph-anchor"></a><b>&#167;22. </b>We are rather formal when printing values to the index, so we choose not
to make use of optional truncation.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LiteralPatterns::lp_index_quantum_value</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">LiteralPatterns::lp_index_quantum_value</span></span>:<br/><a href="3-lp.html#SP18">&#167;18</a>, <a href="3-lp.html#SP19">&#167;19</a>, <a href="3-lp.html#SP21">&#167;21</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">scaling_transformation</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">v</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="identifier-syntax">real_v</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">.0;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::FloatingPoint::uses_floating_point</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_specified</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">real_v</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::Scalings::real_quantum</span><span class="plain-syntax">(</span><span class="identifier-syntax">sc</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">v</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::Scalings::quantum</span><span class="plain-syntax">(</span><span class="identifier-syntax">sc</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lp.html#SP22" class="function-link"><span class="function-syntax">LiteralPatterns::lp_index_value_specific_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">v</span><span class="plain-syntax">, </span><span class="identifier-syntax">real_v</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LiteralPatterns::lp_index_value_specific</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">LiteralPatterns::lp_index_value_specific</span></span>:<br/><a href="3-lp.html#SP20">&#167;20</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="identifier-syntax">alt_value</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">v</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">alt_value</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="identifier-syntax">real_v</span><span class="plain-syntax"> = </span><span class="identifier-syntax">alt_value</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="3-lp.html#SP22" class="function-link"><span class="function-syntax">LiteralPatterns::lp_index_value_specific_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">v</span><span class="plain-syntax">, </span><span class="identifier-syntax">real_v</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LiteralPatterns::lp_index_value_specific_inner</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">v</span><span class="plain-syntax">, </span><span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="identifier-syntax">real_v</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"--"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">tc</span><span class="plain-syntax">, </span><span class="identifier-syntax">ec</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tc</span><span class="plain-syntax">=0, </span><span class="identifier-syntax">ec</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">tc</span><span class="function-syntax">&lt;lp-&gt;</span><span class="element-syntax">no_lp_tokens</span><span class="plain-syntax">; </span><span class="identifier-syntax">tc</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">tc</span><span class="plain-syntax">&gt;0) &amp;&amp; (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_tokens</span><span class="plain-syntax">[</span><span class="identifier-syntax">tc</span><span class="plain-syntax">].</span><span class="element-syntax">new_word_at</span><span class="plain-syntax">)) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_tokens</span><span class="plain-syntax">[</span><span class="identifier-syntax">tc</span><span class="plain-syntax">].</span><span class="element-syntax">lpt_type</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">WORD_LPT:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP22_1" class="named-paragraph-link"><span class="named-paragraph">Index a fixed word token within a literal pattern</span><span class="named-paragraph-number">22.1</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CHARACTER_LPT:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP22_2" class="named-paragraph-link"><span class="named-paragraph">Index a character token within a literal pattern</span><span class="named-paragraph-number">22.2</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">ELEMENT_LPT:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP22_3" class="named-paragraph-link"><span class="named-paragraph">Index an element token within a literal pattern</span><span class="named-paragraph-number">22.3</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"unknown literal pattern token type"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP22_1" class="paragraph-anchor"></a><b>&#167;22.1. </b>We parse in a case-insensitive way, but print back case-sensitively &mdash;
note that the following uses the raw text of the word.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Index a fixed word token within a literal pattern</span><span class="named-paragraph-number">22.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tc</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%&lt;N"</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_tokens</span><span class="plain-syntax">[</span><span class="identifier-syntax">tc</span><span class="plain-syntax">].</span><span class="element-syntax">token_wn</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP22">&#167;22</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP22_2" class="paragraph-anchor"></a><b>&#167;22.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Index a character token within a literal pattern</span><span class="named-paragraph-number">22.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::put</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, (</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_tokens</span><span class="plain-syntax">[</span><span class="identifier-syntax">tc</span><span class="plain-syntax">].</span><span class="element-syntax">token_char</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP22">&#167;22</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP22_3" class="paragraph-anchor"></a><b>&#167;22.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Index an element token within a literal pattern</span><span class="named-paragraph-number">22.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::FloatingPoint::uses_floating_point</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_specified</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%g"</span><span class="plain-syntax">, </span><span class="identifier-syntax">Kinds::Scalings::real_value_to_quanta</span><span class="plain-syntax">(</span><span class="identifier-syntax">real_v</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">remainder</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::Scalings::value_to_quanta</span><span class="plain-syntax">(</span><span class="identifier-syntax">v</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">v</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">remainder</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_element</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lpe</span><span class="plain-syntax"> = &amp;(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_elements</span><span class="plain-syntax">[</span><span class="identifier-syntax">ec</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ec</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">v</span><span class="plain-syntax">/(</span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_multiplier</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prototype</span><span class="plain-syntax"> = </span><span class="string-syntax">"%d"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_tokens</span><span class="plain-syntax">[</span><span class="identifier-syntax">tc</span><span class="plain-syntax">].</span><span class="element-syntax">new_word_at</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">without_leading_zeros</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">prototype</span><span class="plain-syntax"> = </span><a href="3-lp.html#SP23" class="function-link"><span class="function-syntax">LiteralPatterns::leading_zero_prototype</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_range</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, (</span><span class="identifier-syntax">v</span><span class="plain-syntax">/(</span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_multiplier</span><span class="plain-syntax">)) % (</span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_range</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ec</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP22_3_1" class="named-paragraph-link"><span class="named-paragraph">Index the fractional part of the value</span><span class="named-paragraph-number">22.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ec</span><span class="plain-syntax">++;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP22">&#167;22</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP22_3_1" class="paragraph-anchor"></a><b>&#167;22.3.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Index the fractional part of the value</span><span class="named-paragraph-number">22.3.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ranger</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">M</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::Scalings::get_integer_multiplier</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">M</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">ranger</span><span class="plain-syntax">) </span><span class="identifier-syntax">ranger</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ranger</span><span class="plain-syntax">*10;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">remainder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">remainder</span><span class="plain-syntax">*(</span><span class="identifier-syntax">ranger</span><span class="plain-syntax">/</span><span class="identifier-syntax">M</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">remainder</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; ((</span><span class="identifier-syntax">remainder</span><span class="plain-syntax"> % </span><span class="constant-syntax">10</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ranger</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ranger</span><span class="plain-syntax">/10; </span><span class="identifier-syntax">remainder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">remainder</span><span class="plain-syntax">/10;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">remainder</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><a href="3-lp.html#SP23" class="function-link"><span class="function-syntax">LiteralPatterns::leading_zero_prototype</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ranger</span><span class="plain-syntax">), </span><span class="identifier-syntax">remainder</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP22_3">&#167;22.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP23" class="paragraph-anchor"></a><b>&#167;23. </b>Please don't mention the words "logarithm" or "shift". It works fine.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="function-syntax">LiteralPatterns::leading_zero_prototype</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">LiteralPatterns::leading_zero_prototype</span></span>:<br/><a href="3-lp.html#SP22_3">&#167;22.3</a>, <a href="3-lp.html#SP22_3_1">&#167;22.3.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">range</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">range</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">1000000000</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"%010d"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">range</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">100000000</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"%09d"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">range</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">10000000</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"%08d"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">range</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">1000000</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"%07d"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">range</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">100000</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"%06d"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">range</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">10000</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"%05d"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">range</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">1000</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"%04d"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">range</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">100</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"%03d"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">range</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">10</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"%02d"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"%d"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP24" class="paragraph-anchor"></a><b>&#167;24. </b>The grammars for the specify sentence are quite complicated, but aren't used
recursively. So it's more convenient to have them set global variables than to
form a big parse subtree and extract the data from that; these are what they
set.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="function-syntax">LiteralPatterns::new_literal_specification_inner</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp_specification</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lps</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">q</span><span class="plain-syntax">, </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">owner</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">offset</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">integer_scaling</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_specified</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> what we will create, if all goes well</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::FloatingPoint::uses_floating_point</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">)) </span><span class="identifier-syntax">integer_scaling</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">uses_real_arithmetic</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">integer_scaling</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP24_5" class="named-paragraph-link"><span class="named-paragraph">Issue problem message warning that real arithmetic is needed</span><span class="named-paragraph-number">24.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP24_4" class="named-paragraph-link"><span class="named-paragraph">Check that the new notation does not overlap with that of any existing LP</span><span class="named-paragraph-number">24.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP24_6" class="named-paragraph-link"><span class="named-paragraph">Check that the kind is acceptable as the owner of a LP</span><span class="named-paragraph-number">24.6</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP24_3" class="named-paragraph-link"><span class="named-paragraph">Check that any other value mentioned as an equivalent or scaled equivalent has the right kind</span><span class="named-paragraph-number">24.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP24_7" class="named-paragraph-link"><span class="named-paragraph">Create the new literal pattern structure</span><span class="named-paragraph-number">24.7</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP24_8" class="named-paragraph-link"><span class="named-paragraph">Break down the specification text into tokens and elements</span><span class="named-paragraph-number">24.8</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP24_9" class="named-paragraph-link"><span class="named-paragraph">Adopt real arithmetic if this is called for</span><span class="named-paragraph-number">24.9</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP24_10" class="named-paragraph-link"><span class="named-paragraph">Calculate the multipliers for packing the elements into a single integer</span><span class="named-paragraph-number">24.10</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-lp.html#SP30" class="function-link"><span class="function-syntax">LiteralPatterns::list_of_literal_forms</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">benchmark</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="3-lp.html#SP29" class="function-link"><span class="function-syntax">LiteralPatterns::add_literal_pattern</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">part_np_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP24_11" class="named-paragraph-link"><span class="named-paragraph">Work through parts text to assign names to the individual elements</span><span class="named-paragraph-number">24.11</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP24_12" class="named-paragraph-link"><span class="named-paragraph">Check that any notes to do with optional elements are mutually compatible</span><span class="named-paragraph-number">24.12</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="3-lp.html#SP28" class="function-link"><span class="function-syntax">LiteralPatterns::define_packing_phrases</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">owner</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">owner</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP24_1" class="named-paragraph-link"><span class="named-paragraph">Add this new alternative to the list belonging to our owner</span><span class="named-paragraph-number">24.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">owner</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP24_1" class="paragraph-anchor"></a><b>&#167;24.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Add this new alternative to the list belonging to our owner</span><span class="named-paragraph-number">24.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">owner</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">alt</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_alternative_lp</span><span class="plain-syntax">)) </span><span class="identifier-syntax">alt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_alternative_lp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_alternative_lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lp</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP24">&#167;24</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP24_2" class="paragraph-anchor"></a><b>&#167;24.2. </b></p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">PARTS_LPC</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">SCALING_LPC</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">OFFSET_LPC</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">EQUIVALENT_LPC</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span>
</pre>
<p class="commentary firstcommentary"><a id="SP24_3" class="paragraph-anchor"></a><b>&#167;24.3. </b>That's it for syntax: now back to semantics.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Check that any other value mentioned as an equivalent or scaled equivalent has the right kind</span><span class="named-paragraph-number">24.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">equivalent_value</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-rvl.html#SP21" class="function-link"><span class="function-syntax">Rvalues::is_CONSTANT_of_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">equivalent_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">scaled_dir</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LP_SCALED_UP</span><span class="plain-syntax">; </span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">scale_factor</span><span class="plain-syntax"> = </span><a href="2-rvl.html#SP9" class="function-link"><span class="function-syntax">Rvalues::to_encoded_notation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">equivalent_value</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem_with_note</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_BadLPEquivalent</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the equivalent value needs to be a constant of the same kind "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"of value as you are specifying"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and this seems not to be."</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"Note that you can only use notations specified in sentences "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"before the current one."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">offset_value</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-rvl.html#SP21" class="function-link"><span class="function-syntax">Rvalues::is_CONSTANT_of_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">offset_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">offset</span><span class="plain-syntax"> = </span><a href="2-rvl.html#SP9" class="function-link"><span class="function-syntax">Rvalues::to_encoded_notation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">offset_value</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem_with_note</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_BadLPOffset</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the offset value needs to be a constant of the same kind "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"of value as you are specifying"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and this seems not to be."</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"Note that you can only use notations specified in sentences "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"before the current one."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP24">&#167;24</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP24_4" class="paragraph-anchor"></a><b>&#167;24.4. </b>We parse the specification text as if it were a constant value, hoping
for the result <span class="extract"><span class="extract-syntax">NULL</span></span> &mdash; so that it doesn't already mean something else.
During this process, we waive checking of numerical overflows in matching
an LP: this is done so that
</p>
<blockquote>
<p>3/13 specifies a bar. 2/19 specifies a foo.</p>
</blockquote>
<p class="commentary">reports "2/19" as a duplicate using the following problem message, but
does not throw a problem message as being a bar which is out of range
(because in the bar notation, the number after the slash can be at most
13, so that 19 is illegal).
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Check that the new notation does not overlap with that of any existing LP</span><span class="named-paragraph-number">24.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">waive_lp_overflows</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;s-literal&gt;(lps-&gt;</span><span class="identifier-syntax">notation_wording</span><span class="plain-syntax">)) </span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><a href="2-rvl.html#SP24" class="function-link"><span class="function-syntax">Rvalues::to_kind</span></a><span class="plain-syntax">(</span><span class="function-syntax">&lt;&lt;rp&gt;&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">waive_lp_overflows</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">notation_wording</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_DuplicateUnitSpec</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"In the sentence %1, it looks as if you intend to give a new meaning "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"to expressions like '%3', but this is already something I "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"recognise - specifying %2 - so a more distinctive specification "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"must be chosen."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">owner</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP24">&#167;24</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP24_5" class="paragraph-anchor"></a><b>&#167;24.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem message warning that real arithmetic is needed</span><span class="named-paragraph-number">24.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_LPNeedsReal</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"In the sentence %1, it looks as if you intend to give a real "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"number as a scale factor for values of %2. However, as you've "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"defined it here, %2 uses only whole numbers, so this wouldn't "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"work. %PYou can probably fix this by making the example "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"amount a real number too - say, writing '1.0 rel specifies...' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"instead of '1 rel specifies...'."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">owner</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP24">&#167;24</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP24_6" class="paragraph-anchor"></a><b>&#167;24.6. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Check that the kind is acceptable as the owner of a LP</span><span class="named-paragraph-number">24.6</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Behaviour::is_built_in</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Behaviour::get_index_priority</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_LPBuiltInKOVHidden</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"you can only specify ways to write new kinds of value"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"as created with sentences like 'A weight is a kind of value.', "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and not the built-in ones like 'number' or 'time'. (This one is "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"a kind used behind the scenes by Inform, so it's reserved "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"for Inform's own use, and you can't do much else with it.)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_LPBuiltInKOV</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"you can only specify ways to write new kinds of value"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"as created with sentences like 'A weight is a kind of value.', "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and not the built-in ones like 'number' or 'time'."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">owner</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Behaviour::convert_to_unit</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_LPEnumeration</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this is a kind of value which already has named values"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"so it can't have a basically numerical form as well."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">owner</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP24">&#167;24</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP24_7" class="paragraph-anchor"></a><b>&#167;24.7. </b>All the hard work here was done during parsing.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Create the new literal pattern structure</span><span class="named-paragraph-number">24.7</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax"> = </span><a href="3-lp.html#SP7" class="function-link"><span class="function-syntax">LiteralPatterns::lp_new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">notation_wording</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">equivalent_value</span><span class="plain-syntax">) </span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">scale_factor_as_double</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">equivalent_value_as_double</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">scale_factor</span><span class="plain-syntax"> &lt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_LPNonpositiveScaling</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"you can only scale by a positive multiple"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"so something like 'scaled up by -1' is not allowed."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">scale_factor</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::Scalings::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">integer_scaling</span><span class="plain-syntax">, </span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">scaled_dir</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">scale_factor</span><span class="plain-syntax">, </span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">scale_factor_as_double</span><span class="plain-syntax">, </span><span class="identifier-syntax">offset</span><span class="plain-syntax">, </span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">offset_value_as_double</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">owner</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">primary_alternative</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">equivalent_value</span><span class="plain-syntax">) </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">equivalent_unit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">notation_options</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">SINGULAR_LPN</span><span class="plain-syntax">) </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">singular_form_only</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">notation_options</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">PLURAL_LPN</span><span class="plain-syntax">) </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">plural_form_only</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">literal_pattern_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lpn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">notation_groups</span><span class="plain-syntax">; </span><span class="identifier-syntax">lpn</span><span class="plain-syntax">; </span><span class="identifier-syntax">lpn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lpn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_with_rp</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lpn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">can_use_this_lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lp</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP24">&#167;24</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP24_8" class="paragraph-anchor"></a><b>&#167;24.8. </b>Each word is either a whole token in itself, or a stream of tokens representing
alphabetic vs numeric pieces of a word:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Break down the specification text into tokens and elements</span><span class="named-paragraph-number">24.8</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">, </span><span class="identifier-syntax">tc</span><span class="plain-syntax">, </span><span class="identifier-syntax">ec</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0, </span><span class="identifier-syntax">tc</span><span class="plain-syntax">=0, </span><span class="identifier-syntax">ec</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax">&lt;Wordings::length(lps-&gt;</span><span class="identifier-syntax">notation_wording</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_token</span><span class="plain-syntax"> </span><span class="identifier-syntax">new_token</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">digit_found</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text_of_word</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lexer::word_raw_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">notation_wording</span><span class="plain-syntax">)+</span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">text_of_word</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">]; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++) </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Characters::isdigit</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_of_word</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">])) </span><span class="identifier-syntax">digit_found</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">digit_found</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP24_8_1" class="named-paragraph-link"><span class="named-paragraph">Break up the word into at least one element token, and perhaps also character tokens</span><span class="named-paragraph-number">24.8.1</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_token</span><span class="plain-syntax"> = </span><a href="3-lp.html#SP8" class="function-link"><span class="function-syntax">LiteralPatterns::lpt_new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">WORD_LPT</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_token</span><span class="plain-syntax">.</span><span class="element-syntax">token_wn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">notation_wording</span><span class="plain-syntax">)+</span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP24_8_2" class="named-paragraph-link"><span class="named-paragraph">Add new token to LP</span><span class="named-paragraph-number">24.8.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_lp_tokens</span><span class="plain-syntax"> = </span><span class="identifier-syntax">tc</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_lp_elements</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ec</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_lp_elements</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_LPWithoutElement</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"a way to specify a kind of value must involve numbers"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"so '10kg specifies a weight' is allowed, but not 'tonne "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"specifies a weight'."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">owner</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP24">&#167;24</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP24_8_1" class="paragraph-anchor"></a><b>&#167;24.8.1. </b>Bounds checking is easier here since we know that a LP specification will
not ever need to create the maximum conceivable value which a C integer can
hold &mdash; so we need not fool around with long long ints.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Break up the word into at least one element token, and perhaps also character tokens</span><span class="named-paragraph-number">24.8.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">, </span><span class="identifier-syntax">sgn</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">next_token_begins_word</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">text_of_word</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">]; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">tot</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">digit_found</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">point_found</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">text_of_word</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] == </span><span class="character-syntax">'-'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Characters::isdigit</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_of_word</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">+1])) &amp;&amp; (</span><span class="identifier-syntax">ec</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sgn</span><span class="plain-syntax"> = -1; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Characters::isdigit</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_of_word</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">++])) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">digit_found</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tot</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">999999999</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_LPElementTooLarge</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"that specification contains numbers that are too large"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and would construct values which could not sensibly "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"be stored at run-time."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">owner</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">tot</span><span class="plain-syntax"> = </span><span class="constant-syntax">10</span><span class="plain-syntax">*</span><span class="identifier-syntax">tot</span><span class="plain-syntax"> + (</span><span class="identifier-syntax">text_of_word</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">-1]-</span><span class="character-syntax">'0'</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">text_of_word</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] == </span><span class="character-syntax">'.'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">text_of_word</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">+1] == </span><span class="character-syntax">'0'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">ec</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax"> += </span><span class="constant-syntax">2</span><span class="plain-syntax">; </span><span class="identifier-syntax">point_found</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">digit_found</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_element</span><span class="plain-syntax"> </span><span class="identifier-syntax">new_element</span><span class="plain-syntax"> = </span><a href="3-lp.html#SP9" class="function-link"><span class="function-syntax">LiteralPatterns::lpe_new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ec</span><span class="plain-syntax">, </span><span class="identifier-syntax">tot</span><span class="plain-syntax">+1, </span><span class="identifier-syntax">sgn</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ec</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">MAX_ELEMENTS_PER_LITERAL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_LPTooManyElements</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"that specification contains too many numerical elements"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and is too complicated for Inform to handle."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">owner</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_element</span><span class="plain-syntax">.</span><span class="element-syntax">is_real</span><span class="plain-syntax"> = </span><span class="identifier-syntax">point_found</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">point_found</span><span class="plain-syntax">) </span><span class="identifier-syntax">integer_scaling</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_elements</span><span class="plain-syntax">[</span><span class="identifier-syntax">ec</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">new_element</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sgn</span><span class="plain-syntax"> == -1) </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">number_signed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_token</span><span class="plain-syntax"> = </span><a href="3-lp.html#SP8" class="function-link"><span class="function-syntax">LiteralPatterns::lpt_new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">ELEMENT_LPT</span><span class="plain-syntax">, </span><span class="identifier-syntax">next_token_begins_word</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP24_8_2" class="named-paragraph-link"><span class="named-paragraph">Add new token to LP</span><span class="named-paragraph-number">24.8.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_token</span><span class="plain-syntax"> = </span><a href="3-lp.html#SP8" class="function-link"><span class="function-syntax">LiteralPatterns::lpt_new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">CHARACTER_LPT</span><span class="plain-syntax">, </span><span class="identifier-syntax">next_token_begins_word</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_token</span><span class="plain-syntax">.</span><span class="element-syntax">token_char</span><span class="plain-syntax"> = </span><span class="identifier-syntax">text_of_word</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP24_8_2" class="named-paragraph-link"><span class="named-paragraph">Add new token to LP</span><span class="named-paragraph-number">24.8.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sgn</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="identifier-syntax">next_token_begins_word</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP24_8">&#167;24.8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP24_8_2" class="paragraph-anchor"></a><b>&#167;24.8.2. </b>In fact counting tokens is not necessarily a good way to measure the
complexity of an LP, since any long run of characters in a word which
also contains a number will splurge the number of tokens. So
<span class="extract"><span class="extract-syntax">MAX_TOKENS_PER_LITERAL</span></span> is set to a high enough value that this will
not really distort matters.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Add new token to LP</span><span class="named-paragraph-number">24.8.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tc</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">MAX_TOKENS_PER_LITERAL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_LPTooComplicated</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"that specification is too complicated"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and will have to be shortened."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">owner</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_tokens</span><span class="plain-syntax">[</span><span class="identifier-syntax">tc</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">new_token</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP24_8">&#167;24.8</a>, <a href="3-lp.html#SP24_8_1">&#167;24.8.1</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP24_9" class="paragraph-anchor"></a><b>&#167;24.9. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Adopt real arithmetic if this is called for</span><span class="named-paragraph-number">24.9</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">integer_scaling</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::Behaviour::convert_to_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::Scalings::convert_to_real</span><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP24">&#167;24</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP24_10" class="paragraph-anchor"></a><b>&#167;24.10. </b>The elements are created in parsing order, that is, left to right. But
the multipliers can only be calculated by working from right to left, so
this is deferred until all elements exist, at which point we &mdash;
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Calculate the multipliers for packing the elements into a single integer</span><span class="named-paragraph-number">24.10</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">m</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_lp_elements</span><span class="plain-syntax">-1; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&gt;=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">--) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_element</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lpe</span><span class="plain-syntax"> = &amp;(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_elements</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_multiplier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">m</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">m</span><span class="plain-syntax"> = </span><span class="identifier-syntax">m</span><span class="plain-syntax">*(</span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_range</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP24">&#167;24</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP24_11" class="paragraph-anchor"></a><b>&#167;24.11. </b>Today, we have naming of parts:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Work through parts text to assign names to the individual elements</span><span class="named-paragraph-number">24.11</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0, </span><span class="identifier-syntax">p</span><span class="plain-syntax">=</span><span class="identifier-syntax">lps</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">part_np_list</span><span class="plain-syntax">; (</span><span class="identifier-syntax">i</span><span class="function-syntax">&lt;lp-&gt;</span><span class="element-syntax">no_lp_elements</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">++, </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_element</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lpe</span><span class="plain-syntax"> = &amp;(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_elements</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">O</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">lpe_options_ANNOT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">O</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">OPTIONAL_LSO</span><span class="plain-syntax">) </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_optional</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">O</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">PREAMBLE_OPTIONAL_LSO</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_optional</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">preamble_optional</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">O</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">WITHOUT_LEADING_ZEROS_LSO</span><span class="plain-syntax">) </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">without_leading_zeros</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">i</span><span class="plain-syntax"> == </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_lp_elements</span><span class="plain-syntax"> - </span><span class="constant-syntax">1</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_LPTooManyPartNames</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this gives names for too many parts"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"that is, for more parts than there are in the pattern."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">owner</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">j</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">i</span><span class="plain-syntax">; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::match</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_elements</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">element_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_elements</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">].</span><span class="element-syntax">element_name</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_LPRepeatedPartNames</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this repeats a part name"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"that is, it uses the same name for two different parts "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"of the pattern."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">i</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> != </span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_lp_elements</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_LPNotAllNamed</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"you must supply names for all the parts"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"if for any"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">owner</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP24">&#167;24</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP24_12" class="paragraph-anchor"></a><b>&#167;24.12. </b>In fact, the test is a simple one: there can be only one element declared
optional, and it must not be the first.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Check that any notes to do with optional elements are mutually compatible</span><span class="named-paragraph-number">24.12</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">opt_count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax">&lt;lp-&gt;</span><span class="element-syntax">no_lp_elements</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_elements</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">element_optional</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">opt_count</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_LPFirstOptional</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the first part is not allowed to be optional"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"since it is needed to identify the value."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">owner</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">opt_count</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_LPMultipleOptional</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"only one part can be called optional"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"since if any part is omitted then so are all subsequent parts."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">owner</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP24">&#167;24</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP25" class="paragraph-anchor"></a><b>&#167;25. </b>Group names are created when first seen; the following recognises one which
has been seen before.
</p>
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;lp-group-name&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">internal</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">{</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">literal_pattern_name</span><span class="Preform-plain-syntax"> *</span><span class="Preform-identifier-syntax">lpn</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">LOOP_OVER</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">lpn</span><span class="Preform-plain-syntax">, </span><span class="Preform-reserved-syntax">literal_pattern_name</span><span class="Preform-plain-syntax">) {</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><span class="Preform-identifier-syntax">Wordings::match</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">lpn</span><span class="Preform-plain-syntax">-&gt;</span><span class="Preform-identifier-syntax">notation_name</span><span class="Preform-plain-syntax">, </span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">)) {</span>
<span class="Preform-plain-syntax"> ==&gt; { -, </span><span class="Preform-identifier-syntax">lpn</span><span class="Preform-plain-syntax"> }; </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> }</span>
<span class="Preform-plain-syntax"> }</span>
<span class="Preform-plain-syntax"> ==&gt; { </span><span class="Preform-identifier-syntax">fail</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">nonterminal</span><span class="Preform-plain-syntax"> };</span>
<span class="Preform-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP26" class="paragraph-anchor"></a><b>&#167;26. </b>And this is the routine which does the creation. The text will actually be
empty where there's an existing literal pattern name. (For instance, each
time we see a literal pattern given as "in Imperial units", we create a
fresh LPN structure, but only the first one to be created contains the
wording.)
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">literal_pattern_name</span><span class="plain-syntax"> *</span><span class="function-syntax">LiteralPatterns::new_lpn</span><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">literal_pattern_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">existing</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">preform_lookahead_mode</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">new</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">literal_pattern_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">notation_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">W</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">can_use_this_lp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_with_rp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">existing</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">existing</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">existing</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">)) </span><span class="identifier-syntax">existing</span><span class="plain-syntax"> = </span><span class="identifier-syntax">existing</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">existing</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">new</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP27" class="paragraph-anchor"></a><b>&#167;27. I7 phrases to print values in specified ways. </b>When an LP has a name, it's a notation which the source text can request
to be used in saying a value. This is where the corresponding text substitutions
are declared.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LiteralPatterns::define_named_phrases</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lpn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">lpn</span><span class="plain-syntax">, </span><span class="reserved-syntax">literal_pattern_name</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lpn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lpn_compiled_already</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">lpn</span><span class="plain-syntax">, </span><span class="reserved-syntax">literal_pattern_name</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">lpn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">notation_name</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lpn2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lpn2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lpn</span><span class="plain-syntax">; </span><span class="identifier-syntax">lpn2</span><span class="plain-syntax">; </span><span class="identifier-syntax">lpn2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lpn2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lpn2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lpn_compiled_already</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP27_1" class="named-paragraph-link"><span class="named-paragraph">Compile the printing phrase for this and perhaps subsequent LPs</span><span class="named-paragraph-number">27.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ImperativeSubtrees::accept_all</span><span class="plain-syntax">();</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP27_1" class="paragraph-anchor"></a><b>&#167;27.1. </b>These text substitutions correspond exactly neither to the LPs nor to the
names. For instance, "in tonnes" produces a text substitution which takes
in both the LP for "1 tonne" and for "2 tonnes", deciding at run-time
which to use. And on the other hand, "in metric units" may produce text
substitutions for many different kinds, distinguished by type-checking:
</p>
<blockquote>
<p>To say (val - mass) in metric units: ...</p>
</blockquote>
<blockquote>
<p>To say (val - length) in metric units: ...</p>
</blockquote>
<p class="commentary">The following creates one text substitution for each different kind among
the LPs under each named possibility.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile the printing phrase for this and perhaps subsequent LPs</span><span class="named-paragraph-number">27.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lpn2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">can_use_this_lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_specified</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::Textual::write</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">feed_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">id</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Feeds::begin</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Feeds::feed_C_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"To say ( val - "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Feeds::feed_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Feeds::feed_C_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">" ) "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Feeds::feed_wording</span><span class="plain-syntax">(</span><span class="identifier-syntax">lpn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">notation_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">XW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Feeds::end</span><span class="plain-syntax">(</span><span class="identifier-syntax">id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Sentences::make_node</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">XW</span><span class="plain-syntax">, </span><span class="character-syntax">':'</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">id</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Feeds::begin</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">, </span><span class="string-syntax">" (- {-printing-routine:%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">, </span><span class="string-syntax">"}({val}, %d); -) "</span><span class="plain-syntax">, </span><span class="identifier-syntax">lpn</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Feeds::feed_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">XW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Feeds::end</span><span class="plain-syntax">(</span><span class="identifier-syntax">id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Sentences::make_node</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">XW</span><span class="plain-syntax">, </span><span class="character-syntax">'.'</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lpn3</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lpn3</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lpn2</span><span class="plain-syntax">; </span><span class="identifier-syntax">lpn3</span><span class="plain-syntax">; </span><span class="identifier-syntax">lpn3</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lpn3</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">lpn3</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">can_use_this_lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_specified</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lpn3</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lpn_compiled_already</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP27">&#167;27</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP28" class="paragraph-anchor"></a><b>&#167;28. I7 phrases to pack and unpack the value. </b>Creating a LP implicitly defines further I7 source text, as follows.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LiteralPatterns::define_packing_phrases</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">LiteralPatterns::define_packing_phrases</span></span>:<br/><a href="3-lp.html#SP24">&#167;24</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lp</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::Textual::write</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP28_1" class="named-paragraph-link"><span class="named-paragraph">Define phrases to convert from a packed value to individual parts</span><span class="named-paragraph-number">28.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP28_2" class="named-paragraph-link"><span class="named-paragraph">Define a phrase to convert from numerical parts to a packed value</span><span class="named-paragraph-number">28.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ImperativeSubtrees::accept_all</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">)</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP28_1" class="paragraph-anchor"></a><b>&#167;28.1. </b>First, we automatically create \(n\) phrases to unpack the elements given the value.
For instance, defining:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">$10.99 </span><span class="identifier-syntax">specifies</span><span class="plain-syntax"> </span><span class="identifier-syntax">a</span><span class="plain-syntax"> </span><span class="identifier-syntax">price</span><span class="plain-syntax"> </span><span class="identifier-syntax">with</span><span class="plain-syntax"> </span><span class="identifier-syntax">parts</span><span class="plain-syntax"> </span><span class="identifier-syntax">dollars</span><span class="plain-syntax"> </span><span class="identifier-syntax">and</span><span class="plain-syntax"> </span><span class="identifier-syntax">cents</span><span class="plain-syntax">.</span>
</pre>
<p class="commentary">automatically generates:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">To</span><span class="plain-syntax"> </span><span class="identifier-syntax">define</span><span class="plain-syntax"> </span><span class="identifier-syntax">which</span><span class="plain-syntax"> </span><span class="identifier-syntax">number</span><span class="plain-syntax"> </span><span class="identifier-syntax">is</span><span class="plain-syntax"> </span><span class="identifier-syntax">dollars</span><span class="plain-syntax"> </span><span class="identifier-syntax">part</span><span class="plain-syntax"> </span><span class="identifier-syntax">of</span><span class="plain-syntax"> ( </span><span class="identifier-syntax">full</span><span class="plain-syntax"> - </span><span class="identifier-syntax">price</span><span class="plain-syntax"> ) : |(- ({</span><span class="identifier-syntax">full</span><span class="plain-syntax">}/100) -)|.</span>
<span class="identifier-syntax">To</span><span class="plain-syntax"> </span><span class="identifier-syntax">define</span><span class="plain-syntax"> </span><span class="identifier-syntax">which</span><span class="plain-syntax"> </span><span class="identifier-syntax">number</span><span class="plain-syntax"> </span><span class="identifier-syntax">is</span><span class="plain-syntax"> </span><span class="identifier-syntax">cents</span><span class="plain-syntax"> </span><span class="identifier-syntax">part</span><span class="plain-syntax"> </span><span class="identifier-syntax">of</span><span class="plain-syntax"> ( </span><span class="identifier-syntax">full</span><span class="plain-syntax"> - </span><span class="identifier-syntax">price</span><span class="plain-syntax"> ) : |(- ({</span><span class="identifier-syntax">full</span><span class="plain-syntax">}%100) -)|.</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Define phrases to convert from a packed value to individual parts</span><span class="named-paragraph-number">28.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax">&lt;lp-&gt;</span><span class="element-syntax">no_lp_elements</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_element</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lpe</span><span class="plain-syntax"> = &amp;(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_elements</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">feed_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">id</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Feeds::begin</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Feeds::feed_C_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"To decide which number is "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Feeds::feed_wording</span><span class="plain-syntax">(</span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">element_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Feeds::feed_C_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">" part of ( full - "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Feeds::feed_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Feeds::feed_C_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">" ) "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">XW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Feeds::end</span><span class="plain-syntax">(</span><span class="identifier-syntax">id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Sentences::make_node</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">XW</span><span class="plain-syntax">, </span><span class="character-syntax">':'</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">id</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Feeds::begin</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">==0)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">, </span><span class="string-syntax">" (- ({full}/%d) -) "</span><span class="plain-syntax">, </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_multiplier</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_multiplier</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">, </span><span class="string-syntax">" (- (({full}/%d)%%%d) -) "</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_multiplier</span><span class="plain-syntax">, </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_range</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">, </span><span class="string-syntax">" (- ({full}%%%d) -) "</span><span class="plain-syntax">, </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_range</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Feeds::feed_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">XW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Feeds::end</span><span class="plain-syntax">(</span><span class="identifier-syntax">id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::phrasual_length</span><span class="plain-syntax">(</span><span class="identifier-syntax">XW</span><span class="plain-syntax">) &gt;= </span><span class="identifier-syntax">MAX_WORDS_PER_PHRASE</span><span class="plain-syntax"> + </span><span class="constant-syntax">5</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP28_1_1" class="named-paragraph-link"><span class="named-paragraph">Issue a problem for overly long part names</span><span class="named-paragraph-number">28.1.1</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Sentences::make_node</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">XW</span><span class="plain-syntax">, </span><span class="character-syntax">'.'</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP28">&#167;28</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP28_2" class="paragraph-anchor"></a><b>&#167;28.2. </b>And similarly, a packing phrase to calculate the value given its elements.
For instance, the dollars-and-cents example compiles:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">To</span><span class="plain-syntax"> </span><span class="identifier-syntax">decide</span><span class="plain-syntax"> </span><span class="identifier-syntax">which</span><span class="plain-syntax"> </span><span class="identifier-syntax">price</span><span class="plain-syntax"> </span><span class="identifier-syntax">is</span><span class="plain-syntax"> </span><span class="identifier-syntax">price</span><span class="plain-syntax"> </span><span class="identifier-syntax">with</span><span class="plain-syntax"> </span><span class="identifier-syntax">dollars</span><span class="plain-syntax"> </span><span class="identifier-syntax">part</span><span class="plain-syntax"> ( </span><span class="identifier-syntax">part0</span><span class="plain-syntax"> - </span><span class="identifier-syntax">a</span><span class="plain-syntax"> </span><span class="identifier-syntax">number</span><span class="plain-syntax"> ) </span><span class="identifier-syntax">cents</span><span class="plain-syntax"> </span><span class="identifier-syntax">part</span><span class="plain-syntax"> ( </span><span class="identifier-syntax">part1</span><span class="plain-syntax"> - </span><span class="identifier-syntax">a</span><span class="plain-syntax"> </span><span class="identifier-syntax">number</span><span class="plain-syntax">) :</span>
<span class="plain-syntax"> |(- ({</span><span class="identifier-syntax">part0</span><span class="plain-syntax">}*100+{</span><span class="identifier-syntax">part1</span><span class="plain-syntax">}) -).|</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Define a phrase to convert from numerical parts to a packed value</span><span class="named-paragraph-number">28.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_lp_elements</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">feed_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">id</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Feeds::begin</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Feeds::feed_C_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"To decide which "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Feeds::feed_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Feeds::feed_C_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">" is "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Feeds::feed_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Feeds::feed_C_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">" with "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax">&lt;lp-&gt;</span><span class="element-syntax">no_lp_elements</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_element</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lpe</span><span class="plain-syntax"> = &amp;(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_elements</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">, </span><span class="string-syntax">" part%d "</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Feeds::feed_wording</span><span class="plain-syntax">(</span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Feeds::feed_C_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">" part ( "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Feeds::feed_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Feeds::feed_C_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">" - a number ) "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">XW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Feeds::end</span><span class="plain-syntax">(</span><span class="identifier-syntax">id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::phrasual_length</span><span class="plain-syntax">(</span><span class="identifier-syntax">XW</span><span class="plain-syntax">) &gt;= </span><span class="identifier-syntax">MAX_WORDS_PER_PHRASE</span><span class="plain-syntax"> + </span><span class="constant-syntax">5</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lp.html#SP28_1_1" class="named-paragraph-link"><span class="named-paragraph">Issue a problem for overly long part names</span><span class="named-paragraph-number">28.1.1</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Sentences::make_node</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">XW</span><span class="plain-syntax">, </span><span class="character-syntax">':'</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">id</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Feeds::begin</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::clear</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">, </span><span class="string-syntax">" (- ("</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax">&lt;lp-&gt;</span><span class="element-syntax">no_lp_elements</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">literal_pattern_element</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lpe</span><span class="plain-syntax"> = &amp;(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lp_elements</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">&gt;0) </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">, </span><span class="string-syntax">"+"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_multiplier</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">, </span><span class="string-syntax">"%d*"</span><span class="plain-syntax">, </span><span class="identifier-syntax">lpe</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_multiplier</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">, </span><span class="string-syntax">"{part%d}"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">, </span><span class="string-syntax">") -) "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Feeds::feed_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">XW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Feeds::end</span><span class="plain-syntax">(</span><span class="identifier-syntax">id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Sentences::make_node</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">XW</span><span class="plain-syntax">, </span><span class="character-syntax">'.'</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">print_rule_buff</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP28">&#167;28</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP28_1_1" class="paragraph-anchor"></a><b>&#167;28.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem for overly long part names</span><span class="named-paragraph-number">28.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_LPPartNamesTooLong</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the names for these parts are too long"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and will have to be cut down."</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lp.html#SP28_1">&#167;28.1</a>, <a href="3-lp.html#SP28_2">&#167;28.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP29" class="paragraph-anchor"></a><b>&#167;29. The kind's list. </b>On reading "5 feet 4 inches specifies a height", Inform parses
"5 feet 4 inches" into a <span class="extract"><span class="extract-syntax">literal_pattern</span></span> structure and then calls this
routine to attach it to the kind "height". (Multiple patterns can be
attached to the same kind, and they become alternative syntaxes.)
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LiteralPatterns::add_literal_pattern</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">LiteralPatterns::add_literal_pattern</span></span>:<br/><a href="3-lp.html#SP24">&#167;24</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"can't add LP to null kind"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">construct</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">ways_to_write_literals</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><a href="3-lp.html#SP10" class="function-link"><span class="function-syntax">LiteralPatterns::list_add</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">construct</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">ways_to_write_literals</span><span class="plain-syntax">, </span><span class="identifier-syntax">lp</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::uses_floating_point</span><span class="plain-syntax">(</span><span class="identifier-syntax">lp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_specified</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP30" class="paragraph-anchor"></a><b>&#167;30. </b>And here we find the list of such notations.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">literal_pattern</span><span class="plain-syntax"> *</span><span class="function-syntax">LiteralPatterns::list_of_literal_forms</span><button class="popup" onclick="togglePopup('usagePopup17')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup17">Usage of <span class="code-font"><span class="function-syntax">LiteralPatterns::list_of_literal_forms</span></span>:<br/><a href="3-lp.html#SP1">&#167;1</a>, <a href="3-lp.html#SP24">&#167;24</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">construct</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">ways_to_write_literals</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP31" class="paragraph-anchor"></a><b>&#167;31. Literal patterns in Preform. </b>Everything is finally set up so that we can define the following, which
recognises any literal written using a pattern. On success, it produces a
specification for an rvalue of the kind in question.
</p>
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;s-literal-unit-notation&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">internal</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">{</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">literal_pattern</span><span class="Preform-plain-syntax"> *</span><span class="Preform-identifier-syntax">lp</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">LOOP_OVER</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">lp</span><span class="Preform-plain-syntax">, </span><span class="Preform-reserved-syntax">literal_pattern</span><span class="Preform-plain-syntax">) {</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">int</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">val</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">kind</span><span class="Preform-plain-syntax"> *</span><span class="Preform-identifier-syntax">K</span><span class="Preform-plain-syntax"> = </span><a href="3-lp.html#SP16" class="function-link"><span class="Preform-function-syntax">LiteralPatterns::match</span></a><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">lp</span><span class="Preform-plain-syntax">, </span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">, &amp;</span><span class="Preform-identifier-syntax">val</span><span class="Preform-plain-syntax">);</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><span class="Preform-identifier-syntax">K</span><span class="Preform-plain-syntax">) { ==&gt; { </span><span class="Preform-identifier-syntax">val</span><span class="Preform-plain-syntax">, </span><a href="2-rvl.html#SP9" class="function-link"><span class="Preform-function-syntax">Rvalues::from_encoded_notation</span></a><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">K</span><span class="Preform-plain-syntax">, </span><span class="Preform-identifier-syntax">val</span><span class="Preform-plain-syntax">, </span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">) }; </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">; }</span>
<span class="Preform-plain-syntax"> }</span>
<span class="Preform-plain-syntax"> ==&gt; { </span><span class="Preform-identifier-syntax">fail</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">nonterminal</span><span class="Preform-plain-syntax"> };</span>
<span class="Preform-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="3-pl.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-vm.html">1</a></li><li class="progresschapter"><a href="2-spc.html">2</a></li><li class="progresscurrentchapter">3</li><li class="progresssection"><a href="3-pl.html">pl</a></li><li class="progresscurrent">lp</li><li class="progresssection"><a href="3-lrn.html">lrn</a></li><li class="progresssection"><a href="3-tod.html">tod</a></li><li class="progresssection"><a href="3-ul.html">ul</a></li><li class="progresssection"><a href="3-tt.html">tt</a></li><li class="progresssection"><a href="3-ll.html">ll</a></li><li class="progresschapter"><a href="4-ets.html">4</a></li><li class="progresschapter"><a href="5-dsh.html">5</a></li><li class="progressnext"><a href="3-lrn.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>