mirror of
https://github.com/ganelson/inform.git
synced 2024-07-17 06:24:24 +03:00
458 lines
48 KiB
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">★</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">§1. Literals in the S-grammar</a></li><li><a href="#SP2">§2. Response letters</a></li><li><a href="#SP3">§3. Truth states</a></li><li><a href="#SP5">§5. Real numbers</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="inwebparagraph"><a id="SP1"></a><b>§1. Literals in the S-grammar. </b>Most of this section of code defines <s-literal>, 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"><</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">literal</span><span class="plain">> ::=</span>
|
|
<span class="plain"><</span><span class="identifier">cardinal</span><span class="plain">-</span><span class="identifier">number</span><span class="plain">> | ==> </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"> <</span><span class="identifier">cardinal</span><span class="plain">-</span><span class="identifier">number</span><span class="plain">> | ==> </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"><</span><span class="identifier">quoted</span><span class="plain">-</span><span class="identifier">text</span><span class="plain">> ( <</span><span class="identifier">response</span><span class="plain">-</span><span class="identifier">letter</span><span class="plain">> ) | ==> </span><span class="functiontext">Rvalues::from_wording</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)</span>
|
|
<span class="plain"><</span><span class="identifier">quoted</span><span class="plain">-</span><span class="identifier">text</span><span class="plain">> | ==> </span><span class="functiontext">Rvalues::from_wording</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)</span>
|
|
<span class="plain"><</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">> | ==> </span><span class="identifier">RP</span><span class="plain">[1]</span>
|
|
<span class="plain"><</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">> | ==> </span><span class="identifier">RP</span><span class="plain">[1]</span>
|
|
<span class="plain"><</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">> | ==> </span><span class="identifier">RP</span><span class="plain">[1]</span>
|
|
<span class="identifier">unicode</span><span class="plain"> <</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">> | ==> </span><span class="identifier">RP</span><span class="plain">[1]</span>
|
|
<span class="plain"><</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">> | ==> </span><span class="identifier">RP</span><span class="plain">[1] </span> <span class="comment">times\_plugin</span>
|
|
<span class="plain"><</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">> ==> </span><span class="identifier">RP</span><span class="plain">[1]</span>
|
|
|
|
<span class="plain"><</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">> </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">, &</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>§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"><</span><span class="identifier">response</span><span class="plain">-</span><span class="identifier">letter</span><span class="plain">> </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">) && (</span><span class="identifier">p</span><span class="plain">[0] >= </span><span class="character">'A'</span><span class="plain">) && (</span><span class="identifier">p</span><span class="plain">[0] <= </span><span class="character">'Z'</span><span class="plain">) && (</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>§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"><</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">> ::=</span>
|
|
<span class="identifier">false</span><span class="plain"> | ==> </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"> ==> </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>§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>§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"><</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">> ::=</span>
|
|
<span class="identifier">_</span><span class="plain"> </span><span class="identifier">pi</span><span class="plain"> | ==> </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"> | ==> </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"> | ==> </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"> | ==> </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"><</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">> ==> </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"><</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">> </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) && (</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>
|
|
<<span class="cwebmacro">Parse the sign at the front</span> <span class="cwebmacronumber">5.1</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Parse any digits into intv</span> <span class="cwebmacronumber">5.2</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Parse a decimal expansion</span> <span class="cwebmacronumber">5.3</span>><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"> > 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">) > 1) || (</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">])) </span><<span class="cwebmacro">Parse an exponent</span> <span class="cwebmacronumber">5.4</span>><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>§5.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Parse the sign at the front</span> <span class="cwebmacronumber">5.1</span>> =
|
|
</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">§5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5_2"></a><b>§5.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Parse any digits into intv</span> <span class="cwebmacronumber">5.2</span>> =
|
|
</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">§5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5_3"></a><b>§5.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Parse a decimal expansion</span> <span class="cwebmacronumber">5.3</span>> =
|
|
</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">§5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5_4"></a><b>§5.4. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Parse an exponent</span> <span class="cwebmacronumber">5.4</span>> =
|
|
</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">) > 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])) && (</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"> > 0) && ((</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">) && (</span><span class="identifier">q</span><span class="plain">[1] == </span><span class="character">'0'</span><span class="plain">) && (</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">) && (</span><span class="identifier">allow_engineering_notation</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &&</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">§5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6"></a><b>§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">§5.4</a>, 5/lp (<a href="5-lp.html#SP18_1_3_2">§18.1.3.2</a>), 20/eq (<a href="20-eq.html#SP28_1_2_1">§28.1.2.1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7"></a><b>§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><<span class="cwebmacro">Return plus or minus infinity</span> <span class="cwebmacronumber">7.5</span>><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><<span class="cwebmacro">Return plus or minus Not-a-Number</span> <span class="cwebmacronumber">7.6</span>><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">, &</span><span class="identifier">expo</span><span class="plain">);</span>
|
|
<<span class="cwebmacro">Normalize mantissa to be in the range [1.0, 2.0)</span> <span class="cwebmacronumber">7.1</span>><span class="plain">;</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">expo</span><span class="plain"> >= 128) </span><<span class="cwebmacro">Return plus or minus infinity</span> <span class="cwebmacronumber">7.5</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">expo</span><span class="plain"> < -126) </span><<span class="cwebmacro">Denormalize this very small number</span> <span class="cwebmacronumber">7.2</span>>
|
|
<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 && </span><span class="identifier">mant</span><span class="plain"> == 0.0)) </span><<span class="cwebmacro">Denormalize this non-zero number</span> <span class="cwebmacronumber">7.3</span>><span class="plain">;</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">fbits</span><span class="plain"> = 0;</span>
|
|
<<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>><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"> << 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">§5</a>, 5/lp (<a href="5-lp.html#SP18_1_3_2">§18.1.3.2</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7_1"></a><b>§7.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Normalize mantissa to be in the range [1.0, 2.0)</span> <span class="cwebmacronumber">7.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> ((0.5 <= </span><span class="identifier">mant</span><span class="plain">) && (</span><span class="identifier">mant</span><span class="plain"> < 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><<span class="cwebmacro">Return plus or minus infinity</span> <span class="cwebmacronumber">7.5</span>><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7_2"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Denormalize this very small number</span> <span class="cwebmacronumber">7.2</span>> =
|
|
</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">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7_3"></a><b>§7.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Denormalize this non-zero number</span> <span class="cwebmacronumber">7.3</span>> =
|
|
</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">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7_4"></a><b>§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">
|
|
<<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>> =
|
|
</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"> >> 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"> >= 255) </span><<span class="cwebmacro">Return plus or minus infinity</span> <span class="cwebmacronumber">7.5</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7_5"></a><b>§7.5. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Return plus or minus infinity</span> <span class="cwebmacronumber">7.5</span>> =
|
|
</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">§7</a> (twice), <a href="#SP7_1">§7.1</a>, <a href="#SP7_4">§7.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7_6"></a><b>§7.6. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Return plus or minus Not-a-Number</span> <span class="cwebmacronumber">7.6</span>> =
|
|
</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">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP8"></a><b>§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"> < 0)</span>
|
|
<span class="reserved">for</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">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"> > </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">§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>
|
|
|