1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-17 06:24:24 +03:00
inform7/docs/core-module/10-pl.html

458 lines
48 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>10/aots</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '10/pl' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">core</a></li><li><a href="index.html#10">Chapter 10: The S-Parser</a></li><li><b>Parse Literals</b></li></ul><p class="purpose">To decide if an excerpt of text is a value referred to notationally rather than by name.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Literals in the S-grammar</a></li><li><a href="#SP2">&#167;2. Response letters</a></li><li><a href="#SP3">&#167;3. Truth states</a></li><li><a href="#SP5">&#167;5. Real numbers</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Literals in the S-grammar. </b>Most of this section of code defines &lt;s-literal&gt;, the nonterminal which
matches any literal constant. Literal values are explicitly written-out
constants such as "false", "182" or "4:33 PM". Names of objects, rules, and so
on, are also constants, but aren't literal in our sense; on the other hand,
anything which has been defined with a "specifies" sentence ("25 kg specifies
a weight", say) does count as literal. In a natural language, the distinction
is a little blurry, but it's still grammatically useful.
</p>
<p class="inwebparagraph">Note that ordinal numbers are not valid as literals: "2nd" is not a noun.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">literal</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">cardinal</span><span class="plain">-</span><span class="identifier">number</span><span class="plain">&gt; | ==&gt; </span><span class="functiontext">Rvalues::from_int</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">[1], </span><span class="identifier">W</span><span class="plain">)</span>
<span class="identifier">minus</span><span class="plain"> &lt;</span><span class="identifier">cardinal</span><span class="plain">-</span><span class="identifier">number</span><span class="plain">&gt; | ==&gt; </span><span class="functiontext">Rvalues::from_int</span><span class="plain">(-</span><span class="identifier">R</span><span class="plain">[1], </span><span class="identifier">W</span><span class="plain">)</span>
<span class="plain">&lt;</span><span class="identifier">quoted</span><span class="plain">-</span><span class="identifier">text</span><span class="plain">&gt; ( &lt;</span><span class="identifier">response</span><span class="plain">-</span><span class="identifier">letter</span><span class="plain">&gt; ) | ==&gt; </span><span class="functiontext">Rvalues::from_wording</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)</span>
<span class="plain">&lt;</span><span class="identifier">quoted</span><span class="plain">-</span><span class="identifier">text</span><span class="plain">&gt; | ==&gt; </span><span class="functiontext">Rvalues::from_wording</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">literal</span><span class="plain">-</span><span class="identifier">real</span><span class="plain">-</span><span class="identifier">number</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">literal</span><span class="plain">-</span><span class="identifier">truth</span><span class="plain">-</span><span class="identifier">state</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">literal</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="identifier">unicode</span><span class="plain"> &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">unicode</span><span class="plain">-</span><span class="identifier">character</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">literal</span><span class="plain">-</span><span class="identifier">time</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">RP</span><span class="plain">[1] </span> <span class="comment">times\_plugin</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">literal</span><span class="plain">-</span><span class="identifier">unit</span><span class="plain">-</span><span class="identifier">notation</span><span class="plain">&gt; ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">literal</span><span class="plain">-</span><span class="identifier">unit</span><span class="plain">-</span><span class="identifier">notation</span><span class="plain">&gt; </span><span class="identifier">internal</span><span class="plain"> {</span>
<span class="reserved">literal_pattern</span><span class="plain"> *</span><span class="identifier">lp</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">lp</span><span class="plain">, </span><span class="reserved">literal_pattern</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">val</span><span class="plain">;</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">LiteralPatterns::match</span><span class="plain">(</span><span class="identifier">lp</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, &amp;</span><span class="identifier">val</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">) { *</span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">val</span><span class="plain">; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="functiontext">Rvalues::from_encoded_notation</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">val</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">); </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">; }</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. Response letters. </b>Response letters mark certain texts as responses. These are capital letters
A to Z.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">response</span><span class="plain">-</span><span class="identifier">letter</span><span class="plain">&gt; </span><span class="identifier">internal</span><span class="plain"> 1 {</span>
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">Lexer::word_raw_text</span><span class="plain">(</span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">p</span><span class="plain">) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">[0] &gt;= </span><span class="character">'A'</span><span class="plain">) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">[0] &lt;= </span><span class="character">'Z'</span><span class="plain">) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">[1] == 0)) {</span>
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">[0] - </span><span class="character">'A'</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. Truth states. </b>It might seem odd that the truth states count as literals, whereas names of
instances of other kinds (people, say) do not. The argument for this is that
there are always necessarily exactly two truth states, whereas there could
in principle be any number of people, colours, vehicles, and such.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">literal</span><span class="plain">-</span><span class="identifier">truth</span><span class="plain">-</span><span class="identifier">state</span><span class="plain">&gt; ::=</span>
<span class="identifier">false</span><span class="plain"> | ==&gt; </span><span class="functiontext">Rvalues::from_boolean</span><span class="plain">(</span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">)</span>
<span class="identifier">true</span><span class="plain"> ==&gt; </span><span class="functiontext">Rvalues::from_boolean</span><span class="plain">(</span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">)</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>The problem message for engineering notation should only appear once:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">e_notation_problem_issued</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Real numbers. </b>I'm in two minds about whether giving "pi" and "e" special treatment is sensible.
Still:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">REAL_LITERALS</span>
</pre>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">literal</span><span class="plain">-</span><span class="identifier">real</span><span class="plain">-</span><span class="identifier">number</span><span class="plain">&gt; ::=</span>
<span class="identifier">_</span><span class="plain"> </span><span class="identifier">pi</span><span class="plain"> | ==&gt; </span><span class="functiontext">Rvalues::from_IEEE_754</span><span class="plain">(0</span><span class="identifier">x40490FDB</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">)</span>
<span class="identifier">_</span><span class="plain"> </span><span class="identifier">e</span><span class="plain"> | ==&gt; </span><span class="functiontext">Rvalues::from_IEEE_754</span><span class="plain">(0</span><span class="identifier">x402DF854</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">)</span>
<span class="identifier">plus</span><span class="plain"> </span><span class="identifier">infinity</span><span class="plain"> | ==&gt; </span><span class="functiontext">Rvalues::from_IEEE_754</span><span class="plain">(0</span><span class="identifier">x7F800000</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">)</span>
<span class="identifier">minus</span><span class="plain"> </span><span class="identifier">infinity</span><span class="plain"> | ==&gt; </span><span class="functiontext">Rvalues::from_IEEE_754</span><span class="plain">(0</span><span class="identifier">xFF800000</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">)</span>
<span class="plain">&lt;</span><span class="identifier">literal</span><span class="plain">-</span><span class="identifier">real</span><span class="plain">-</span><span class="identifier">in</span><span class="plain">-</span><span class="identifier">digits</span><span class="plain">&gt; ==&gt; </span><span class="functiontext">Rvalues::from_IEEE_754</span><span class="plain">((</span><span class="reserved">unsigned</span><span class="plain"> </span><span class="reserved">int</span><span class="plain">) </span><span class="identifier">R</span><span class="plain">[1], </span><span class="identifier">W</span><span class="plain">)</span>
<span class="plain">&lt;</span><span class="identifier">literal</span><span class="plain">-</span><span class="identifier">real</span><span class="plain">-</span><span class="identifier">in</span><span class="plain">-</span><span class="identifier">digits</span><span class="plain">&gt; </span><span class="identifier">internal</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Wordings::length</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">) != 1) &amp;&amp; (</span><span class="identifier">Wordings::length</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">) != 3)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">Lexer::word_raw_text</span><span class="plain">(</span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">expo</span><span class="plain">=0; </span><span class="reserved">double</span><span class="plain"> </span><span class="identifier">intv</span><span class="plain">=0, </span><span class="identifier">fracv</span><span class="plain">=0;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">expocount</span><span class="plain">=0, </span><span class="identifier">intcount</span><span class="plain">=0, </span><span class="identifier">fraccount</span><span class="plain">=0;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">signbit</span><span class="plain"> = 0;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">distinctive</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span> <span class="comment">as a floating-point rather than integer number</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> = 0;</span>
&lt;<span class="cwebmacro">Parse the sign at the front</span> <span class="cwebmacronumber">5.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Parse any digits into intv</span> <span class="cwebmacronumber">5.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Parse a decimal expansion</span> <span class="cwebmacronumber">5.3</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">intcount</span><span class="plain"> + </span><span class="identifier">fraccount</span><span class="plain"> &gt; 0) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Wordings::length</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">) &gt; 1) || (</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">])) </span>&lt;<span class="cwebmacro">Parse an exponent</span> <span class="cwebmacronumber">5.4</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">distinctive</span><span class="plain">) || (</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">CONSTANT_CMODE</span><span class="plain">))) {</span>
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = </span><span class="functiontext">Literals::construct_float</span><span class="plain">(</span><span class="identifier">signbit</span><span class="plain">, </span><span class="identifier">intv</span><span class="plain">, </span><span class="identifier">fracv</span><span class="plain">, </span><span class="identifier">expo</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP5_1"></a><b>&#167;5.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Parse the sign at the front</span> <span class="cwebmacronumber">5.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] == </span><span class="character">'-'</span><span class="plain">) { </span><span class="identifier">signbit</span><span class="plain"> = 1; </span><span class="identifier">i</span><span class="plain">++; }</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] == </span><span class="character">'+'</span><span class="plain">) { </span><span class="identifier">signbit</span><span class="plain"> = 0; </span><span class="identifier">i</span><span class="plain">++; }</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_2"></a><b>&#167;5.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Parse any digits into intv</span> <span class="cwebmacronumber">5.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Characters::isdigit</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">])) {</span>
<span class="identifier">intv</span><span class="plain"> = 10.0*</span><span class="identifier">intv</span><span class="plain"> + (</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] - </span><span class="character">'0'</span><span class="plain">);</span>
<span class="identifier">intcount</span><span class="plain">++;</span>
<span class="identifier">i</span><span class="plain">++;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_3"></a><b>&#167;5.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Parse a decimal expansion</span> <span class="cwebmacronumber">5.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] == </span><span class="character">'.'</span><span class="plain">) {</span>
<span class="identifier">distinctive</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">i</span><span class="plain">++;</span>
<span class="reserved">double</span><span class="plain"> </span><span class="identifier">fracpow</span><span class="plain"> = 1.0;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Characters::isdigit</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">])) {</span>
<span class="identifier">fracpow</span><span class="plain"> *= 0.1;</span>
<span class="identifier">fracv</span><span class="plain"> = </span><span class="identifier">fracv</span><span class="plain"> + </span><span class="identifier">fracpow</span><span class="plain">*(</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] - </span><span class="character">'0'</span><span class="plain">);</span>
<span class="identifier">fraccount</span><span class="plain">++;</span>
<span class="identifier">i</span><span class="plain">++;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_4"></a><b>&#167;5.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Parse an exponent</span> <span class="cwebmacronumber">5.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">q</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain"> + </span><span class="identifier">i</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">e_notation_used</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::length</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">) &gt; 1) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">q</span><span class="plain">[0] != 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">q</span><span class="plain"> = </span><span class="identifier">Lexer::word_raw_text</span><span class="plain">(</span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">) + 1);</span>
<span class="reserved">if</span><span class="plain"> (!((</span><span class="functiontext">Literals::ismultiplicationsign</span><span class="plain">(</span><span class="identifier">q</span><span class="plain">[0])) &amp;&amp; (</span><span class="identifier">q</span><span class="plain">[1] == 0))) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">q</span><span class="plain"> = </span><span class="identifier">Lexer::word_raw_text</span><span class="plain">(</span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">) + 2);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">fraccount</span><span class="plain"> &gt; 0) &amp;&amp; ((</span><span class="identifier">q</span><span class="plain">[0] == </span><span class="character">'e'</span><span class="plain">) || (</span><span class="identifier">q</span><span class="plain">[0] == </span><span class="character">'E'</span><span class="plain">))) </span><span class="identifier">e_notation_used</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (!(</span><span class="functiontext">Literals::ismultiplicationsign</span><span class="plain">(</span><span class="identifier">q</span><span class="plain">[0]))) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">q</span><span class="plain">++;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">e_notation_used</span><span class="plain">) {</span>
<span class="identifier">i</span><span class="plain"> = 0;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (!((</span><span class="identifier">q</span><span class="plain">[0] == </span><span class="character">'1'</span><span class="plain">) &amp;&amp; (</span><span class="identifier">q</span><span class="plain">[1] == </span><span class="character">'0'</span><span class="plain">) &amp;&amp; (</span><span class="identifier">q</span><span class="plain">[2] == </span><span class="character">'^'</span><span class="plain">))) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">i</span><span class="plain"> = 3;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">exposign</span><span class="plain"> = 0;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">q</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] == </span><span class="character">'+'</span><span class="plain">) </span><span class="identifier">i</span><span class="plain">++; </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">q</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] == </span><span class="character">'-'</span><span class="plain">) { </span><span class="identifier">exposign</span><span class="plain"> = 1; </span><span class="identifier">i</span><span class="plain">++; }</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Characters::isdigit</span><span class="plain">(</span><span class="identifier">q</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">])) {</span>
<span class="identifier">expo</span><span class="plain"> = 10*</span><span class="identifier">expo</span><span class="plain"> + (</span><span class="identifier">q</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] - </span><span class="character">'0'</span><span class="plain">);</span>
<span class="identifier">expocount</span><span class="plain">++;</span>
<span class="identifier">i</span><span class="plain">++;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">q</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">expocount</span><span class="plain"> == 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">exposign</span><span class="plain">) { </span><span class="identifier">expo</span><span class="plain"> = -</span><span class="identifier">expo</span><span class="plain">; }</span>
<span class="identifier">distinctive</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">e_notation_used</span><span class="plain">) &amp;&amp; (</span><span class="identifier">allow_engineering_notation</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">e_notation_problem_issued</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)) {</span>
<span class="identifier">e_notation_problem_issued</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_WantonEngineering</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In %1, you write '%2', which looks to me like the engineering "</span>
<span class="string">"notation for a real number - I'm guessing that the 'e' means "</span>
<span class="string">"exponent, so for example, 1E+6 means 1000000. Inform writes "</span>
<span class="string">"numbers like this as 1 x 10^6, or if you prefer 1.0 x 10^6; "</span>
<span class="string">"or you can use a multiplication sign instead of the 'x'."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Literals::ismultiplicationsign</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">c</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">c</span><span class="plain"> == </span><span class="character">'x'</span><span class="plain">) || (</span><span class="identifier">c</span><span class="plain"> == </span><span class="character">'*'</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Literals::ismultiplicationsign is used in <a href="#SP5_4">&#167;5.4</a>, 5/lp (<a href="5-lp.html#SP18_1_3_2">&#167;18.1.3.2</a>), 20/eq (<a href="20-eq.html#SP28_1_2_1">&#167;28.1.2.1</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>The following routine, adapted from code contributed to I6 by Andrew
Plotkin, returns the IEEE-754 single-precision encoding of a floating-point
number. See:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">http://www.psc.edu/general/software/packages/ieee/ieee.php</span>
</pre>
<p class="inwebparagraph">for an explanation.
</p>
<p class="inwebparagraph">If the magnitude is too large (beyond about <code class="display"><span class="extract">3.4e+38</span></code>), this returns plus or
minus infinity; if the magnitude is too small (below about <code class="display"><span class="extract">1e-45</span></code>), this returns
a zero value. If any of the inputs are NaN, this returns NaN.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Literals::construct_float</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">signbit</span><span class="plain">, </span><span class="reserved">double</span><span class="plain"> </span><span class="identifier">intv</span><span class="plain">, </span><span class="reserved">double</span><span class="plain"> </span><span class="identifier">fracv</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">expo</span><span class="plain">) {</span>
<span class="reserved">double</span><span class="plain"> </span><span class="identifier">absval</span><span class="plain"> = (</span><span class="identifier">intv</span><span class="plain"> + </span><span class="identifier">fracv</span><span class="plain">) * </span><span class="functiontext">Literals::ten_to_the</span><span class="plain">(</span><span class="identifier">expo</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">sign</span><span class="plain"> = (</span><span class="identifier">signbit</span><span class="plain"> ? ((</span><span class="reserved">int</span><span class="plain">) 0</span><span class="identifier">x80000000</span><span class="plain">) : 0</span><span class="identifier">x0</span><span class="plain">);</span>
<span class="identifier">latest_constructed_real</span><span class="plain"> = </span><span class="identifier">absval</span><span class="plain">; </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">signbit</span><span class="plain">) </span><span class="identifier">latest_constructed_real</span><span class="plain"> = -</span><span class="identifier">absval</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">isinf</span><span class="plain">(</span><span class="identifier">absval</span><span class="plain">)) </span>&lt;<span class="cwebmacro">Return plus or minus infinity</span> <span class="cwebmacronumber">7.5</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">isnan</span><span class="plain">(</span><span class="identifier">absval</span><span class="plain">)) </span>&lt;<span class="cwebmacro">Return plus or minus Not-a-Number</span> <span class="cwebmacronumber">7.6</span>&gt;<span class="plain">;</span>
<span class="reserved">double</span><span class="plain"> </span><span class="identifier">mant</span><span class="plain"> = </span><span class="identifier">frexp</span><span class="plain">(</span><span class="identifier">absval</span><span class="plain">, &amp;</span><span class="identifier">expo</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Normalize mantissa to be in the range [1.0, 2.0)</span> <span class="cwebmacronumber">7.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">expo</span><span class="plain"> &gt;= 128) </span>&lt;<span class="cwebmacro">Return plus or minus infinity</span> <span class="cwebmacronumber">7.5</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">expo</span><span class="plain"> &lt; -126) </span>&lt;<span class="cwebmacro">Denormalize this very small number</span> <span class="cwebmacronumber">7.2</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (!(</span><span class="identifier">expo</span><span class="plain"> == 0 &amp;&amp; </span><span class="identifier">mant</span><span class="plain"> == 0.0)) </span>&lt;<span class="cwebmacro">Denormalize this non-zero number</span> <span class="cwebmacronumber">7.3</span>&gt;<span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">fbits</span><span class="plain"> = 0;</span>
&lt;<span class="cwebmacro">Set fbits to the mantissa times 2 to the 23, rounded to the nearest integer</span> <span class="cwebmacronumber">7.4</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> (</span><span class="identifier">sign</span><span class="plain">) | ((</span><span class="reserved">int</span><span class="plain">)(</span><span class="identifier">expo</span><span class="plain"> &lt;&lt; 23)) | (</span><span class="identifier">fbits</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Literals::construct_float is used in <a href="#SP5">&#167;5</a>, 5/lp (<a href="5-lp.html#SP18_1_3_2">&#167;18.1.3.2</a>).</p>
<p class="inwebparagraph"><a id="SP7_1"></a><b>&#167;7.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Normalize mantissa to be in the range [1.0, 2.0)</span> <span class="cwebmacronumber">7.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((0.5 &lt;= </span><span class="identifier">mant</span><span class="plain">) &amp;&amp; (</span><span class="identifier">mant</span><span class="plain"> &lt; 1.0)) {</span>
<span class="identifier">mant</span><span class="plain"> *= 2.0;</span>
<span class="identifier">expo</span><span class="plain">--;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">mant</span><span class="plain"> == 0.0) {</span>
<span class="identifier">expo</span><span class="plain"> = 0;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Return plus or minus infinity</span> <span class="cwebmacronumber">7.5</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP7_2"></a><b>&#167;7.2. </b>One of the following two things then happens, resulting in the exponent
now being in the range 0 to 255, and the mantissa in [0, 1).
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Denormalize this very small number</span> <span class="cwebmacronumber">7.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">mant</span><span class="plain"> = </span><span class="identifier">ldexp</span><span class="plain">(</span><span class="identifier">mant</span><span class="plain">, 126 + </span><span class="identifier">expo</span><span class="plain">);</span>
<span class="identifier">expo</span><span class="plain"> = 0; </span> <span class="comment">0 now represents 10 to the minus 127</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP7_3"></a><b>&#167;7.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Denormalize this non-zero number</span> <span class="cwebmacronumber">7.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">expo</span><span class="plain"> += 127; </span> <span class="comment">127 now represents 10 to the 0, that is, 1</span>
<span class="identifier">mant</span><span class="plain"> -= 1.0; </span> <span class="comment">the mantissa was in the range [1, 2), is now in [0, 1)</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP7_4"></a><b>&#167;7.4. </b>At this point the mantissa is a number in the range [0, 1), so multiplying
it by 2 to the 23 will produce the bottom 22 bits of our answer. The case
we have to be wary of is where the carry propagates out of a string of 23
1 bits, that is, where we end up with bit 23 set as well: in that case, the
exponent increments, and we round to that power of 10 exactly.
</p>
<p class="inwebparagraph">Note that 2 to the 23 is 8388608.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Set fbits to the mantissa times 2 to the 23, rounded to the nearest integer</span> <span class="cwebmacronumber">7.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">fbits</span><span class="plain"> = (</span><span class="reserved">int</span><span class="plain">) ((</span><span class="identifier">mant</span><span class="plain">*8388608.0) + 0.5); </span> <span class="comment">round to nearest integer</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">fbits</span><span class="plain"> &gt;&gt; 23) {</span>
<span class="identifier">fbits</span><span class="plain"> = 0;</span>
<span class="identifier">expo</span><span class="plain">++; </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">expo</span><span class="plain"> &gt;= 255) </span>&lt;<span class="cwebmacro">Return plus or minus infinity</span> <span class="cwebmacronumber">7.5</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP7_5"></a><b>&#167;7.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">Return plus or minus infinity</span> <span class="cwebmacronumber">7.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">sign</span><span class="plain"> | 0</span><span class="identifier">x7f800000</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a> (twice), <a href="#SP7_1">&#167;7.1</a>, <a href="#SP7_4">&#167;7.4</a>.</p>
<p class="inwebparagraph"><a id="SP7_6"></a><b>&#167;7.6. </b><code class="display">
&lt;<span class="cwebmacrodefn">Return plus or minus Not-a-Number</span> <span class="cwebmacronumber">7.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">sign</span><span class="plain"> | 0</span><span class="identifier">x7fc00000</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>The following returns 10 to the given power.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">POW10_RANGE</span><span class="plain"> 8</span>
</pre>
<pre class="display">
<span class="reserved">double</span><span class="plain"> </span><span class="functiontext">Literals::ten_to_the</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">expo</span><span class="plain">) {</span>
<span class="reserved">static</span><span class="plain"> </span><span class="reserved">double</span><span class="plain"> </span><span class="identifier">powers</span><span class="plain">[</span><span class="constant">POW10_RANGE</span><span class="plain">*2+1] = {</span>
<span class="plain">0.00000001, 0.0000001, 0.000001, 0.00001, 0.0001, 0.001, 0.01, 0.1,</span>
<span class="plain">1.0,</span>
<span class="plain">10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 10000000.0, 100000000.0</span>
<span class="plain">};</span>
<span class="reserved">double</span><span class="plain"> </span><span class="identifier">res</span><span class="plain"> = 1.0;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">expo</span><span class="plain"> &lt; 0)</span>
<span class="reserved">for</span><span class="plain"> (; </span><span class="identifier">expo</span><span class="plain"> &lt; -</span><span class="constant">POW10_RANGE</span><span class="plain">; </span><span class="identifier">expo</span><span class="plain"> += </span><span class="constant">POW10_RANGE</span><span class="plain">)</span>
<span class="identifier">res</span><span class="plain"> *= </span><span class="identifier">powers</span><span class="plain">[0];</span>
<span class="reserved">else</span>
<span class="reserved">for</span><span class="plain"> (; </span><span class="identifier">expo</span><span class="plain"> &gt; </span><span class="constant">POW10_RANGE</span><span class="plain">; </span><span class="identifier">expo</span><span class="plain"> -= </span><span class="constant">POW10_RANGE</span><span class="plain">)</span>
<span class="identifier">res</span><span class="plain"> *= </span><span class="identifier">powers</span><span class="plain">[</span><span class="constant">POW10_RANGE</span><span class="plain">*2];</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">res</span><span class="plain"> * </span><span class="identifier">powers</span><span class="plain">[</span><span class="constant">POW10_RANGE</span><span class="plain">+</span><span class="identifier">expo</span><span class="plain">];</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Literals::ten_to_the is used in <a href="#SP7">&#167;7</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="10-aots.html">Back to 'Architecture of the S-Parser'</a></li><li><a href="10-cad.html">Continue with 'Constants and Descriptions'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>