mirror of
https://github.com/ganelson/inform.git
synced 2024-07-16 22:14:23 +03:00
2231 lines
430 KiB
HTML
2231 lines
430 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>Equations</title>
|
|
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<meta name="viewport" content="width=device-width initial-scale=1">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta http-equiv="Content-Language" content="en-gb">
|
|
|
|
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<script>
|
|
MathJax = {
|
|
tex: {
|
|
inlineMath: '$', '$'], ['\\(', '\\)'
|
|
},
|
|
svg: {
|
|
fontCache: 'global'
|
|
}
|
|
};
|
|
</script>
|
|
<script type="text/javascript" id="MathJax-script" async
|
|
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
|
|
</script>
|
|
|
|
<script>
|
|
function togglePopup(material_id) {
|
|
var popup = document.getElementById(material_id);
|
|
popup.classList.toggle("show");
|
|
}
|
|
</script>
|
|
|
|
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Preform-Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
|
|
</head>
|
|
<body class="commentary-font">
|
|
<nav role="navigation">
|
|
<h1><a href="../index.html">
|
|
<img src="../docs-assets/Inform.png" height=72">
|
|
</a></h1>
|
|
<ul><li><a href="../compiler.html">compiler tools</a></li>
|
|
<li><a href="../other.html">other tools</a></li>
|
|
<li><a href="../extensions.html">extensions and kits</a></li>
|
|
<li><a href="../units.html">unit test tools</a></li>
|
|
</ul><h2>Compiler Webs</h2><ul>
|
|
<li><a href="../inbuild/index.html">inbuild</a></li>
|
|
<li><a href="../inform7/index.html">inform7</a></li>
|
|
<li><a href="../inter/index.html">inter</a></li>
|
|
</ul><h2>Inbuild Modules</h2><ul>
|
|
<li><a href="../supervisor-module/index.html">supervisor</a></li>
|
|
</ul><h2>Inform7 Modules</h2><ul>
|
|
<li><a href="../core-module/index.html">core</a></li>
|
|
<li><a href="index.html"><span class="selectedlink">assertions</span></a></li>
|
|
<li><a href="../values-module/index.html">values</a></li>
|
|
<li><a href="../knowledge-module/index.html">knowledge</a></li>
|
|
<li><a href="../imperative-module/index.html">imperative</a></li>
|
|
<li><a href="../runtime-module/index.html">runtime</a></li>
|
|
<li><a href="../if-module/index.html">if</a></li>
|
|
<li><a href="../multimedia-module/index.html">multimedia</a></li>
|
|
<li><a href="../index-module/index.html">index</a></li>
|
|
</ul><h2>Inter Modules</h2><ul>
|
|
<li><a href="../bytecode-module/index.html">bytecode</a></li>
|
|
<li><a href="../building-module/index.html">building</a></li>
|
|
<li><a href="../codegen-module/index.html">codegen</a></li>
|
|
</ul><h2>Services</h2><ul>
|
|
<li><a href="../arch-module/index.html">arch</a></li>
|
|
<li><a href="../calculus-module/index.html">calculus</a></li>
|
|
<li><a href="../html-module/index.html">html</a></li>
|
|
<li><a href="../inflections-module/index.html">inflections</a></li>
|
|
<li><a href="../kinds-module/index.html">kinds</a></li>
|
|
<li><a href="../linguistics-module/index.html">linguistics</a></li>
|
|
<li><a href="../problems-module/index.html">problems</a></li>
|
|
<li><a href="../syntax-module/index.html">syntax</a></li>
|
|
<li><a href="../words-module/index.html">words</a></li>
|
|
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
|
|
|
|
</ul>
|
|
</nav>
|
|
<main role="main">
|
|
<!--Weave of 'Equations' generated by Inweb-->
|
|
<div class="breadcrumbs">
|
|
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inform7</a></li><li><a href="index.html">assertions</a></li><li><a href="index.html#7">Chapter 7: Other Gadgets</a></li><li><b>Equations</b></li></ul></div>
|
|
<p class="purpose">To manage and compile equations, which relate numerical quantities.</p>
|
|
|
|
<ul class="toc"><li><a href="7-eqt.html#SP10">§10. Parsing equations</a></li><li><a href="7-eqt.html#SP12">§12. Declaring symbols</a></li><li><a href="7-eqt.html#SP23">§23. Equation nodes</a></li><li><a href="7-eqt.html#SP26">§26. Tokenising equations</a></li><li><a href="7-eqt.html#SP29">§29. The shift-reduce parser</a></li><li><a href="7-eqt.html#SP37">§37. Typechecking equations</a></li><li><a href="7-eqt.html#SP40">§40. Flotation</a></li><li><a href="7-eqt.html#SP41">§41. Rearrangement</a></li><li><a href="7-eqt.html#SP43">§43. Internal test case</a></li><li><a href="7-eqt.html#SP44">§44. Logging</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§1. </b>As with tables, equations are detected early on in Inform's run but not
|
|
parsed for their contents until later, so we store several word ranges.
|
|
Also as with tables, each can have a number, a name or both.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">equation</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">equation_text</span><span class="plain-syntax">; </span><span class="comment-syntax"> the text of the actual equation</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">equation_no_text</span><span class="plain-syntax">; </span><span class="comment-syntax"> the equation number (if any)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">equation_name_text</span><span class="plain-syntax">; </span><span class="comment-syntax"> the equation name (if any)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">where_text</span><span class="plain-syntax">; </span><span class="comment-syntax"> declaration of symbols</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">usage_text</span><span class="plain-syntax">; </span><span class="comment-syntax"> usage notes</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">equation_created_at</span><span class="plain-syntax">; </span><span class="comment-syntax"> where created in source</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">examined_already</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parsed_equation</span><span class="plain-syntax">; </span><span class="comment-syntax"> and the equation itself (when eventually parsed)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">equation_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">symbol_list</span><span class="plain-syntax">; </span><span class="comment-syntax"> the symbols used</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">equation_compilation_data</span><span class="plain-syntax"> </span><span class="identifier-syntax">compilation_data</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">equation</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure equation is accessed in 3/nuor, 5/id, 5/idf, 5/adf, 5/tpf, 5/rf, 5/rcd, 6/rls, 6/rlb, 6/fao, 6/act, 7/tc, 7/tbl and here.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>§2. </b>Each equation is allowed to use one or more symbols. Some may correspond
|
|
to local variables in surrounding code from time to time, but others will
|
|
be constants, and it's better to think of these as placeholders in the
|
|
syntax of the equation, not as storage objects like variables. For instance,
|
|
in
|
|
$$ E = mc^2 $$
|
|
we have three symbols: \(E\), \(m\) and \(c\). (The 2 does not count.) There
|
|
might be symbols called \(m\) in any number of other equations; if so each
|
|
instance has its own <span class="extract"><span class="extract-syntax">equation_symbol</span></span> structure.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">equation_symbol</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">name</span><span class="plain-syntax">; </span><span class="comment-syntax"> always just one word, in fact</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var_kind</span><span class="plain-syntax">; </span><span class="comment-syntax"> if a variable — must be quasinumerical</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">id_body</span><span class="plain-syntax"> *</span><span class="identifier-syntax">function_notated</span><span class="plain-syntax">; </span><span class="comment-syntax"> if a phrase QN to QN</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var_const</span><span class="plain-syntax">; </span><span class="comment-syntax"> if a symbol for a constant value</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">temp_constant</span><span class="plain-syntax">; </span><span class="comment-syntax"> is this constant a substitution for one usage only?</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">equation_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next</span><span class="plain-syntax">; </span><span class="comment-syntax"> in the list belonging to the equation</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">local_map</span><span class="plain-syntax">; </span><span class="comment-syntax"> when being solved in a given stack frame</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">promote_local_to_real</span><span class="plain-syntax">; </span><span class="comment-syntax"> from integer, if necessary</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">equation_symbol</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure equation_symbol is accessed in 2/ptmn, 2/cs, 2/ps, 2/is, 3/dlr, 3/pr, 3/tr, 3/nuor, 3/uor, 3/tr2, 3/dbtr, 3/rpr, 3/nar, 3/nlpr, 3/nrr, 3/npr, 3/nvr, 3/nar2, 4/rpt, 4/tc, 4/ass, 4/npa, 4/rk, 4/ass2, 4/imp, 5/id, 5/adf, 5/tpf, 5/po, 5/rcd, 6/rls, 6/rlb, 6/fao, 6/act, 6/sv, 7/tc, 7/tbl, 8/tcp, 8/abp, 8/cu and here.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>§3. </b>In addition, there are some standing symbols used by all equations: the
|
|
constant "pi", for example. They're stored in this linked list:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">equation_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">standard_equation_symbols</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>§4. </b>When parsed, the equation is stored as a tree of <span class="extract"><span class="extract-syntax">equation_node</span></span> structures.
|
|
As usual, the leaves represent symbols or else constants not given symbol
|
|
status (such as the 2 in \(E = mc^2\)); the non-leaf nodes represent operations,
|
|
identified with the same codes as used in "Dimensions". Note
|
|
that the equals sign <span class="extract"><span class="extract-syntax">=</span></span> is itself considered an operation here.Thus:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> OPERATION_EQN =</span>
|
|
<span class="plain-syntax"> SYMBOL_EQN E</span>
|
|
<span class="plain-syntax"> OPERATION_EQN *</span>
|
|
<span class="plain-syntax"> SYMBOL_EQN m</span>
|
|
<span class="plain-syntax"> OPERATION_EQN ^</span>
|
|
<span class="plain-syntax"> SYMBOL_EQN c</span>
|
|
<span class="plain-syntax"> CONSTANT_EQN 2</span>
|
|
</pre>
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">CONSTANT_EQN</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax"> </span><span class="comment-syntax"> a leaf, representing a quasinumerical constant not given a symbol</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">SYMBOL_EQN</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax"> </span><span class="comment-syntax"> a leaf, representing a symbol</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">OPERATION_EQN</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax"> </span><span class="comment-syntax"> a non-leaf, representing an operation</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>§5. </b>However, because of the algorithm used to parse the text of the equation into
|
|
this tree, we also need certain other kinds of node to exist during parsing
|
|
only. They are syntactic gimmicks, and are forbidden in the final tree.
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">OPEN_BRACKET_EQN</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">CLOSE_BRACKET_EQN</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">END_EQN</span><span class="plain-syntax"> </span><span class="constant-syntax">6</span><span class="plain-syntax"> </span><span class="comment-syntax"> the end (left or right edge, really) of the equation</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>§6. </b>Another temporary trick in parsing is to distinguish between explicit
|
|
multiplication, where the source text uses an asterisk <span class="extract"><span class="extract-syntax">*</span></span>, and implicit,
|
|
as between \(m\) and \(c^2\) in \(E = mc^2\). We distinguish these so that they
|
|
can bind with different tightnesses, but both are represented just as
|
|
<span class="extract"><span class="extract-syntax">TIMES_OPERATION</span></span> nodes in the eventual tree.
|
|
</p>
|
|
|
|
<p class="commentary">Implicit function application is similarly used to represent the unwritten
|
|
operation in <span class="extract"><span class="extract-syntax">log pi</span></span> — where the function <span class="extract"><span class="extract-syntax">log</span></span> is being applied to the
|
|
value <span class="extract"><span class="extract-syntax">pi</span></span>.
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">IMPLICIT_TIMES_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">100</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">IMPLICIT_APPLICATION_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">101</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>§7. </b>And now the equation node structure:
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_EQN_ARITY</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax"> </span><span class="comment-syntax"> at present all operations are at most binary</span>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">eqn_type</span><span class="plain-syntax">; </span><span class="comment-syntax"> one of the </span><span class="extract"><span class="extract-syntax">*_EQN</span></span><span class="comment-syntax"> values</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">eqn_operation</span><span class="plain-syntax">; </span><span class="comment-syntax"> one of the </span><span class="extract"><span class="extract-syntax">*_OPERATION</span></span><span class="comment-syntax"> values (see "Dimensions.w")</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">enode_arity</span><span class="plain-syntax">; </span><span class="comment-syntax"> 0 for a leaf</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">enode_operands</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_EQN_ARITY</span><span class="plain-syntax">]; </span><span class="comment-syntax"> the operands</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">leaf_constant</span><span class="plain-syntax">; </span><span class="comment-syntax"> if e.g. "21"</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">equation_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">leaf_symbol</span><span class="plain-syntax">; </span><span class="comment-syntax"> if e.g. "G"</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">generalised_kind</span><span class="plain-syntax"> </span><span class="identifier-syntax">gK_before</span><span class="plain-syntax">; </span><span class="comment-syntax"> result of the node as it is</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">generalised_kind</span><span class="plain-syntax"> </span><span class="identifier-syntax">gK_after</span><span class="plain-syntax">; </span><span class="comment-syntax"> result of the node as we need it to be</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">enode_promotion</span><span class="plain-syntax">; </span><span class="comment-syntax"> promote this from an integer to a real number?</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rational_n</span><span class="plain-syntax">; </span><span class="comment-syntax"> represents the rational number </span><span class="extract"><span class="extract-syntax">n/m</span></span><span class="comment-syntax">...</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rational_m</span><span class="plain-syntax">; </span><span class="comment-syntax"> ...unless </span><span class="extract"><span class="extract-syntax">m</span></span><span class="comment-syntax"> is zero</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure equation_node is private to this section.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>§8. </b>Equation names follow the same conventions as table names.
|
|
</p>
|
|
|
|
<pre class="Preform-displayed-code all-displayed-code code-font">
|
|
<span class="Preform-function-syntax"><equation-name></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">equation</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">{<cardinal-number>}</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">-</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==></span><span class="Preform-plain-syntax"> { 3, - }</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">equation</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">{<cardinal-number>}</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==></span><span class="Preform-plain-syntax"> { 1, - }</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">equation</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">-</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==></span><span class="Preform-plain-syntax"> { 2, - }</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">equation</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">***</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==></span><span class="Preform-plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP8_3" class="named-paragraph-link"><span class="named-paragraph">Issue PM_EquationMisnumbered problem</span><span class="named-paragraph-number">8.3</span></a></span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP8_1" class="paragraph-anchor"></a><b>§8.1. </b>The above catches all of the named expressions written out in the
|
|
source text, but not the ones written "inline", in phrases like
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>let F be given by F = ma;</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">Those equations are created by calling <span class="extract"><span class="Preform-extract-syntax">Equations::new</span></span> direct from the
|
|
S-parser: such equations are called "anonymous", as they have no name. But in
|
|
either case, an equation begins here:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="function-syntax">Equations::new_at</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Equations::new_at</span></span>:<br/>Passes through Major Nodes - <a href="2-ptmn.html#SP3_1">§3.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">anonymous</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="7-eqt.html#SP8_1" class="function-link"><span class="function-syntax">Equations::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">anonymous</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="function-syntax">Equations::new</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Equations::new</span></span>:<br/><a href="7-eqt.html#SP43">§43</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">anonymous</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="reserved-syntax">equation</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">equation_created_at</span><span class="plain-syntax"> == </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">equation</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">equation_created_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">where_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">usage_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">symbol_list</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">examined_already</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">NO</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">, </span><span class="identifier-syntax">NA</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">anonymous</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP8_1_1" class="named-paragraph-link"><span class="named-paragraph">Parse the equation's number and/or name</span><span class="named-paragraph-number">8.1.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP8_1_3" class="named-paragraph-link"><span class="named-paragraph">Register any names for this equation</span><span class="named-paragraph-number">8.1.3</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax"><equation-where></span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax"><equation-where></span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP9" class="function-link"><span class="function-syntax">Equations::set_wherewithal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax"><equation-where></span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">equation_no_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NO</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">equation_name_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NA</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax"><text-ending-in-comma></span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax"><text-ending-in-comma></span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">equation_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">W</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">compilation_data</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RTEquations::new_compilation_data</span><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP8_2" class="paragraph-anchor"></a><b>§8.2. </b></p>
|
|
|
|
<pre class="Preform-displayed-code all-displayed-code code-font">
|
|
<span class="Preform-function-syntax"><text-ending-in-comma></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">,</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP8_3" class="paragraph-anchor"></a><b>§8.3. </b>We take the word range \((w_1, w_2)\) and shave off the first line, that is,
|
|
all the words up to the first line break occurring between words. (Compare
|
|
the syntax for a table declaration.) This becomes the word range \((tw_1, tw_2)\).
|
|
We know that this begins with the word "equation", or we wouldn't be here
|
|
(because the sentence would not have been classed an <span class="extract"><span class="Preform-extract-syntax">EQUATION_NT</span></span>).
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_EquationMisnumbered problem</span><span class="named-paragraph-number">8.3</span></span><span class="Preform-comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationMisnumbered</span><span class="plain-syntax">),</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"the top line of this equation declaration seems not to be a "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"legal equation number or name"</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"and should read something like 'Equation 6', or 'Equation - "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"Newton's Second Law', or 'Equation 41 - Coulomb's Law'."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> ==> { </span><span class="constant-syntax">0</span><span class="plain-syntax">, - };</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP8">§8</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP8_1_1" class="paragraph-anchor"></a><b>§8.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse the equation's number and/or name</span><span class="named-paragraph-number">8.1.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::last_word_of_formatted_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">TW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::up_to</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::from</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">+1);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax"><equation-name></span><span class="plain-syntax">(</span><span class="identifier-syntax">TW</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="function-syntax"><<r>></span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">: </span><span class="identifier-syntax">NO</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax"><equation-name></span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">: </span><span class="identifier-syntax">NA</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax"><equation-name></span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax">: </span><span class="identifier-syntax">NO</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax"><equation-name></span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">NA</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax"><equation-name></span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"malformed equation sentence"</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP8_1">§8.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP8_1_2" class="paragraph-anchor"></a><b>§8.1.2. </b>An equation can be referred to by its number, or by its name. Thus
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Equation 64 - Distribution of Cheese</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">could be referred to elsewhere in the text by any of three names:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>equation 64, Distribution of Cheese, Distribution of Cheese equation</p>
|
|
</blockquote>
|
|
|
|
<pre class="Preform-displayed-code all-displayed-code code-font">
|
|
<span class="Preform-function-syntax"><equation-names-construction></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">equation</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">equation</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP8_1_3" class="paragraph-anchor"></a><b>§8.1.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Register any names for this equation</span><span class="named-paragraph-number">8.1.3</span></span><span class="Preform-comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">NO</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">word_assemblage</span><span class="plain-syntax"> </span><span class="identifier-syntax">wa</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PreformUtilities::merge</span><span class="plain-syntax">(</span><span class="function-syntax"><equation-names-construction></span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WordAssemblages::from_wording</span><span class="plain-syntax">(</span><span class="identifier-syntax">NO</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">AW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">WordAssemblages::to_wording</span><span class="plain-syntax">(&</span><span class="identifier-syntax">wa</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Nouns::new_proper_noun</span><span class="plain-syntax">(</span><span class="identifier-syntax">AW</span><span class="plain-syntax">, </span><span class="identifier-syntax">NEUTER_GENDER</span><span class="plain-syntax">, </span><span class="identifier-syntax">ADD_TO_LEXICON_NTOPT</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EQUATION_MC</span><span class="plain-syntax">, </span><span class="identifier-syntax">Rvalues::from_equation</span><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">), </span><span class="identifier-syntax">Task::language_of_syntax</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> }</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">NA</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax"><s-type-expression-or-value></span><span class="plain-syntax">(</span><span class="identifier-syntax">NA</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording_as_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">NA</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationMisnamed</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"The equation name %1 will have to be disallowed as it is text "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"which already has a meaning to Inform. For instance, creating "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"an equation called 'Equation - 2 + 2' would be disallowed "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"because Inform would read '2 + 2' as arithmetic, not a name."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Nouns::new_proper_noun</span><span class="plain-syntax">(</span><span class="identifier-syntax">NA</span><span class="plain-syntax">, </span><span class="identifier-syntax">NEUTER_GENDER</span><span class="plain-syntax">, </span><span class="identifier-syntax">ADD_TO_LEXICON_NTOPT</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EQUATION_MC</span><span class="plain-syntax">, </span><span class="identifier-syntax">Rvalues::from_equation</span><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">), </span><span class="identifier-syntax">Task::language_of_syntax</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">word_assemblage</span><span class="plain-syntax"> </span><span class="identifier-syntax">wa</span><span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PreformUtilities::merge</span><span class="plain-syntax">(</span><span class="function-syntax"><equation-names-construction></span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WordAssemblages::from_wording</span><span class="plain-syntax">(</span><span class="identifier-syntax">NA</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">AW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">WordAssemblages::to_wording</span><span class="plain-syntax">(&</span><span class="identifier-syntax">wa</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Nouns::new_proper_noun</span><span class="plain-syntax">(</span><span class="identifier-syntax">AW</span><span class="plain-syntax">, </span><span class="identifier-syntax">NEUTER_GENDER</span><span class="plain-syntax">, </span><span class="identifier-syntax">ADD_TO_LEXICON_NTOPT</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EQUATION_MC</span><span class="plain-syntax">, </span><span class="identifier-syntax">Rvalues::from_equation</span><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">), </span><span class="identifier-syntax">Task::language_of_syntax</span><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP8_1">§8.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>§9. </b>A "where" clause following an equation defines its symbols, as we shall
|
|
see. That can be detected in the above parsing process where the equation
|
|
is displayed, but for anonymous equations occurring inline, the S-parser
|
|
has to discover it; and the S-parser then calls this routine:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::set_wherewithal</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Equations::set_wherewithal</span></span>:<br/><a href="7-eqt.html#SP8_1">§8.1</a>, <a href="7-eqt.html#SP43">§43</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">where_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">W</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>§10. Parsing equations. </b>So now it's later on. We can run through all the equations displayed in the
|
|
source text:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::traverse_to_stock</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="reserved-syntax">equation</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">equation_created_at</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP11" class="function-link"><span class="function-syntax">Equations::examine</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>§11. </b>And, as with creation, <span class="extract"><span class="extract-syntax">Equations::examine</span></span> is called explicitly in the meaning
|
|
list converter when an equation is found inline. So in all cases, we call the
|
|
following before we need to use the equation, which runs a three-stage process:
|
|
parsing the "where..." clause to declare the symbols, then parsing the equation,
|
|
then type-checking it.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::examine</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Equations::examine</span></span>:<br/><a href="7-eqt.html#SP10">§10</a>, <a href="7-eqt.html#SP43">§43</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">examined_already</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">examined_already</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="7-eqt.html#SP13" class="function-link"><span class="function-syntax">Equations::eqn_declare_symbols</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP19" class="function-link"><span class="function-syntax">Equations::eqn_declare_standard_symbols</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP26" class="function-link"><span class="function-syntax">Equations::eqn_parse</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="7-eqt.html#SP37" class="function-link"><span class="function-syntax">Equations::eqn_typecheck</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP25" class="function-link"><span class="function-syntax">Equations::log_equation_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>§12. Declaring symbols. </b>Equations are allowed to end with a "where..." clause, explaining what
|
|
the symbols in it mean. For example:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>where F is a force, a = 9.801 m/ss, m1 and m2 are masses;</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">At the earlier stages of parsing, we simply split the "where" text away
|
|
using this:
|
|
</p>
|
|
|
|
<pre class="Preform-displayed-code all-displayed-code code-font">
|
|
<span class="Preform-function-syntax"><equation-where></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">where</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>§13. </b>For a displayed equation, the following parses the "where..." text, which
|
|
is expected to declare every symbol occurring in it.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::eqn_declare_symbols</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Equations::eqn_declare_symbols</span></span>:<br/><a href="7-eqt.html#SP11">§11</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::empty</span><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">where_text</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP16" class="function-link"><span class="function-syntax">Equations::eqn_declare_variables_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">where_text</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">changed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">changed</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">changed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">equation_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">symbol_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">ev</span><span class="plain-syntax">; </span><span class="identifier-syntax">ev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">var_kind</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_symbol_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">BelievedImpossible</span><span class="plain-syntax">),</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">where_text</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"each symbol in a equation has to be declared with a kind of "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"value or else an actual value. So '...where N = 1701.' or "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"'...where N, M are numbers.' would be fine."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">var_kind</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax">-></span><span class="element-syntax">var_kind</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">var_const</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax">-></span><span class="element-syntax">var_const</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">changed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>§14. </b>But the following routine is also used with the "where" text supplied in
|
|
a phrase like so:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>let F be given by Newton's Second Law, where m = 101kg;</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">In this context the "where" text sets explicit values for symbols occurring
|
|
in the equation; these are temporary settings only and will not change the
|
|
equation's behaviour elsewhere.
|
|
</p>
|
|
|
|
<p class="commentary">So the following is called in either permanent mode, when it declares symbols
|
|
for an equation, or temporary mode, when it gives them temporary assignments.
|
|
It returns <span class="extract"><span class="extract-syntax">TRUE</span></span> if all went well, or <span class="extract"><span class="extract-syntax">FALSE</span></span> if problem messages had to be
|
|
issued.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">equation_being_declared</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">equation_declared_temporarily</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">eq_symbol_wn</span><span class="plain-syntax"> = -1;</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>§15. </b>The following grammar is later used to parse the text after "where". For
|
|
example:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>F is a force, a = 9.801 m/ss, m1 and m2 are masses</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">This is split into four clauses, of which the trickiest is the third, reading
|
|
just "m1". This abbreviated form is allowed only in permanent declarations
|
|
(i.e., not in equations defined inside "let" phrases) and gives the symbol
|
|
the same definition as the one following it — so m1 becomes defined as a
|
|
mass, too.
|
|
</p>
|
|
|
|
<pre class="Preform-displayed-code all-displayed-code code-font">
|
|
<span class="Preform-function-syntax"><equation-where-list></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==></span><span class="Preform-plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP15_1" class="named-paragraph-link"><span class="named-paragraph">Match only when looking ahead</span><span class="named-paragraph-number">15.1</span></a></span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><equation-where-setting-entry></span><span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><equation-where-tail></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==></span><span class="Preform-plain-syntax"> { 0, - }</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><equation-where-setting-entry></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==></span><span class="Preform-plain-syntax"> { 0, - }</span>
|
|
|
|
<span class="Preform-function-syntax"><equation-where-tail></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">,</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">_and</span><span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><equation-where-list></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==></span><span class="Preform-plain-syntax"> { 0, - }</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">_,/and</span><span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><equation-where-list></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==></span><span class="Preform-plain-syntax"> { 0, - }</span>
|
|
|
|
<span class="Preform-function-syntax"><equation-where-setting-entry></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==></span><span class="Preform-plain-syntax"> { lookahead }</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><equation-where-setting></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==></span><span class="Preform-plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP15_2" class="named-paragraph-link"><span class="named-paragraph">Declare an equation variable</span><span class="named-paragraph-number">15.2</span></a></span>
|
|
|
|
<span class="Preform-function-syntax"><equation-where-setting></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><equation-symbol></span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">is/are</span><span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><k-kind></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==></span><span class="Preform-plain-syntax"> { EQW_IDENTIFIES_KIND, RP[2] }; eq_symbol_wn = R[1];</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><equation-symbol></span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">is/are</span><span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><s-value></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==></span><span class="Preform-plain-syntax"> { EQW_IDENTIFIES_VALUE, RP[2] }; eq_symbol_wn = R[1];</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><equation-symbol></span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">is/are</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==></span><span class="Preform-plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP15_3" class="named-paragraph-link"><span class="named-paragraph">Issue PM_EquationSymbolNonValue problem</span><span class="named-paragraph-number">15.3</span></a></span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><equation-symbol></span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">=</span><span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><k-kind></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==></span><span class="Preform-plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP15_4" class="named-paragraph-link"><span class="named-paragraph">Issue PM_EquationSymbolEqualsKOV problem</span><span class="named-paragraph-number">15.4</span></a></span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><equation-symbol></span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">=</span><span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><s-value></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==></span><span class="Preform-plain-syntax"> { EQW_IDENTIFIES_VALUE, RP[2] }; eq_symbol_wn = R[1];</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><equation-symbol></span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">=</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==></span><span class="Preform-plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP15_3" class="named-paragraph-link"><span class="named-paragraph">Issue PM_EquationSymbolNonValue problem</span><span class="named-paragraph-number">15.3</span></a></span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><equation-symbol></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==></span><span class="Preform-plain-syntax"> { EQW_IDENTIFIES_NOTHING, NULL }; eq_symbol_wn = R[1];</span>
|
|
|
|
<span class="Preform-function-syntax"><equation-symbol></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><valid-equation-symbol></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==></span><span class="Preform-plain-syntax"> { pass 1 }</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">###</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==></span><span class="Preform-plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP15_5" class="named-paragraph-link"><span class="named-paragraph">Issue PM_EquationSymbolMalformed problem</span><span class="named-paragraph-number">15.5</span></a></span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==></span><span class="Preform-plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP15_6" class="named-paragraph-link"><span class="named-paragraph">Issue PM_EquationSymbolMisdeclared problem</span><span class="named-paragraph-number">15.6</span></a></span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP15_1" class="paragraph-anchor"></a><b>§15.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Match only when looking ahead</span><span class="named-paragraph-number">15.1</span></span><span class="Preform-comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eq_symbol_wn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> ==> { </span><span class="constant-syntax">0</span><span class="plain-syntax">, - };</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">preform_lookahead_mode</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP15">§15</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP15_2" class="paragraph-anchor"></a><b>§15.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Declare an equation variable</span><span class="named-paragraph-number">15.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP16" class="function-link"><span class="function-syntax">Equations::eqn_dec_var</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">equation_being_declared</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::one_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">eq_symbol_wn</span><span class="plain-syntax">), </span><span class="identifier-syntax">R</span><span class="plain-syntax">[1], </span><span class="identifier-syntax">RP</span><span class="plain-syntax">[1]);</span>
|
|
<span class="plain-syntax"> ==> { -, - };</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP15">§15</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP15_3" class="paragraph-anchor"></a><b>§15.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_EquationSymbolNonValue problem</span><span class="named-paragraph-number">15.3</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><span class="identifier-syntax">preform_lookahead_mode</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_symbol_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationSymbolNonValue</span><span class="plain-syntax">),</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">equation_being_declared</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::one_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">[1]),</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"this has neither a kind of value nor an actual value."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> ==> { </span><span class="constant-syntax">EQW_IDENTIFIES_PROBLEM</span><span class="plain-syntax">, - };</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP15">§15</a> (twice).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP15_4" class="paragraph-anchor"></a><b>§15.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_EquationSymbolEqualsKOV problem</span><span class="named-paragraph-number">15.4</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><span class="identifier-syntax">preform_lookahead_mode</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_symbol_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationSymbolEqualsKOV</span><span class="plain-syntax">),</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">equation_being_declared</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::one_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">[1]),</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"'is' should be used, not '=', for a kind of value rather "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"than an actual value."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> ==> { </span><span class="constant-syntax">EQW_IDENTIFIES_PROBLEM</span><span class="plain-syntax">, - };</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP15">§15</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP15_5" class="paragraph-anchor"></a><b>§15.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_EquationSymbolMalformed problem</span><span class="named-paragraph-number">15.5</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><span class="identifier-syntax">preform_lookahead_mode</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_symbol_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationSymbolMalformed</span><span class="plain-syntax">),</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">equation_being_declared</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"a symbol in a equation has to be a sequence of one to ten "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"letters optionally followed by a number from 0 to 99, so "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"'G', 'm', 'pi' and 'KE1' are all legal symbol names. But "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"this one is not."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> ==> { -1, - };</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP15">§15</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP15_6" class="paragraph-anchor"></a><b>§15.6. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_EquationSymbolMisdeclared problem</span><span class="named-paragraph-number">15.6</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><span class="identifier-syntax">preform_lookahead_mode</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(),</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationSymbolMisdeclared</span><span class="plain-syntax">),</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"the symbols here are not declared properly"</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"and should each be declared with a kind of value or else an "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"actual value."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> ==> { -1, - };</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP15">§15</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>§16. </b></p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">EQW_IDENTIFIES_KIND</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">EQW_IDENTIFIES_VALUE</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">EQW_IDENTIFIES_NOTHING</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">EQW_IDENTIFIES_PROBLEM</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::eqn_declare_variables_inner</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Equations::eqn_declare_variables_inner</span></span>:<br/><a href="7-eqt.html#SP13">§13</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">temp</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">equation_being_declared</span><span class="plain-syntax"> = </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">equation_declared_temporarily</span><span class="plain-syntax"> = </span><span class="identifier-syntax">temp</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">problem_count</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="function-syntax"><equation-where-list></span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> > </span><span class="identifier-syntax">pc</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::eqn_dec_var</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">Equations::eqn_dec_var</span></span>:<br/><a href="7-eqt.html#SP15_2">§15.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">X</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">XP</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">spec</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">temp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">equation_declared_temporarily</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">X</span><span class="plain-syntax"> == </span><span class="constant-syntax">EQW_IDENTIFIES_PROBLEM</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">Wordings::empty</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">))) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">X</span><span class="plain-syntax"> != </span><span class="constant-syntax">EQW_IDENTIFIES_NOTHING</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP16_1" class="named-paragraph-link"><span class="named-paragraph">Find the actual value, or kind of value, which the symbol is to match</span><span class="named-paragraph-number">16.1</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">temp</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP16_2" class="named-paragraph-link"><span class="named-paragraph">Assign the given value to this symbol on a temporary basis</span><span class="named-paragraph-number">16.2</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><a href="7-eqt.html#SP20" class="function-link"><span class="function-syntax">Equations::eqn_add_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">spec</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP16_1" class="paragraph-anchor"></a><b>§16.1. </b>Symbols are allowed to be set equal to kinds of value, but only quasinumerical
|
|
ones; or to quasinumerical constants; or to global variables which contain
|
|
quasinumerical values. The latter are included to make it easier for extensions
|
|
to set up sets of equations for, say, gravity, defining
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>The acceleration due to gravity is an acceleration that varies.</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">and thus letting the extension's user decide how strong gravity is, but
|
|
still using it in equations:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>let F be given by Newton's Second Law, where a = the acceleration due to gravity;</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Find the actual value, or kind of value, which the symbol is to match</span><span class="named-paragraph-number">16.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">spec</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">X</span><span class="plain-syntax"> == </span><span class="constant-syntax">EQW_IDENTIFIES_KIND</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">XP</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">temp</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_symbol_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationSymbolVague</span><span class="plain-syntax">), </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"when an equation is named for use in a 'let' "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"phrase, any variables listed under 'where...' have "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"to be given definite values, not just vaguely said "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"to have particular kinds. Otherwise, I can't do any "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"calculation with them."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">X</span><span class="plain-syntax"> == </span><span class="constant-syntax">EQW_IDENTIFIES_VALUE</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">spec</span><span class="plain-syntax"> = </span><span class="identifier-syntax">XP</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Specifications::to_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">K</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">Kinds::Behaviour::is_quasinumerical</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_symbol_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationSymbolNonNumeric</span><span class="plain-syntax">), </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"this has a kind of value on which arithmetic cannot be done, "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"so it can have no place in an equation."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP16">§16</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP16_2" class="paragraph-anchor"></a><b>§16.2. </b>At this point we know the user means the variable named at word <span class="extract"><span class="extract-syntax">wn</span></span>
|
|
to have the temporary value <span class="extract"><span class="extract-syntax">spec</span></span>, and we have to identify that as one
|
|
of the symbols:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Assign the given value to this symbol on a temporary basis</span><span class="named-paragraph-number">16.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">equation_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">symbol_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">ev</span><span class="plain-syntax">; </span><span class="identifier-syntax">ev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::match_cs</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">name</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="identifier-syntax">var_kind</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_symbol_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationSymbolBadSub</span><span class="plain-syntax">), </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"you're using 'where' to substitute something into this "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"symbol which has the wrong kind of value."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">temp_constant</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">var_const</span><span class="plain-syntax"> = </span><span class="identifier-syntax">spec</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_symbol_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationSymbolSpurious</span><span class="plain-syntax">), </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"when 'where' is used to supply values to plug into a "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"named equation as part of a 'let' phrase, you can only "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"supply values for symbols actually used in that equation. "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"This one doesn't seem to occur there."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP16">§16</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>§17. </b>We won't want those temporary assignments hanging around, so once the
|
|
hurly-burly is done, the following is called:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::eqn_remove_temp_variables</span><span class="plain-syntax">(</span><span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">equation_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">symbol_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">ev</span><span class="plain-syntax">; </span><span class="identifier-syntax">ev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">temp_constant</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">var_const</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">temp_constant</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>§18. </b>As we saw, permanent symbol declarations cause <span class="extract"><span class="extract-syntax">Equations::eqn_add_symbol</span></span> to be called.
|
|
But what about the symbols for an inline equation, like this one?
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>let F be given by F = ma;</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">These are not explicitly declared. What happens is that any local variable
|
|
on the current stack frame, whose name could plausibly be that of a symbol,
|
|
is made into one. Sometimes the locals won't be symbols in the equation at all,
|
|
but will just have short names and coincidentally hold quasinumeric values;
|
|
that doesn't matter, because if they're not in the equation, they'll never
|
|
be used.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::declare_local_variables</span><span class="plain-syntax">(</span><span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">stack_frame</span><span class="plain-syntax"> *</span><span class="identifier-syntax">frame</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Frames::current_stack_frame</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">frame</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LOCALS_IN_FRAME</span><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">, </span><span class="identifier-syntax">frame</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-></span><span class="identifier-syntax">allocated</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP18" class="function-link"><span class="function-syntax">Equations::declare_local</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-></span><span class="identifier-syntax">current_usage</span><span class="plain-syntax">.</span><span class="identifier-syntax">varname</span><span class="plain-syntax">, </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-></span><span class="identifier-syntax">current_usage</span><span class="plain-syntax">.</span><span class="identifier-syntax">kind_as_declared</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="comment-syntax"> which calls the following for each current local variable in turn:</span>
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::declare_local</span><span class="plain-syntax">(</span><span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="7-eqt.html#SP22" class="function-link"><span class="function-syntax">Equations::equation_symbol_legal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) && (</span><span class="identifier-syntax">Kinds::Behaviour::is_quasinumerical</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">)))</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP20" class="function-link"><span class="function-syntax">Equations::eqn_add_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>§19. </b>Next we add "e" and "pi". These are added last, so that any local
|
|
declarations will trump them.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::eqn_declare_standard_symbols</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">Equations::eqn_declare_standard_symbols</span></span>:<br/><a href="7-eqt.html#SP11">§11</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">standard_equation_symbols</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">TCW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Feeds::feed_C_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"e pi"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_WORDING</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">TCW</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">V</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::one_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax"><s-type-expression></span><span class="plain-syntax">(</span><span class="identifier-syntax">V</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">spec</span><span class="plain-syntax"> = </span><span class="function-syntax"><<rp>></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP20" class="function-link"><span class="function-syntax">Equations::eqn_add_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">V</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_real_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">spec</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">id_body</span><span class="plain-syntax"> *</span><span class="identifier-syntax">idb</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">idb</span><span class="plain-syntax">, </span><span class="reserved-syntax">id_body</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><a href="5-tpf.html#SP11" class="function-link"><span class="function-syntax">ToPhraseFamily::get_equation_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">idb</span><span class="plain-syntax">-></span><span class="element-syntax">head_of_defn</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ev</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP20" class="function-link"><span class="function-syntax">Equations::eqn_add_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_real_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">function_notated</span><span class="plain-syntax"> = </span><span class="identifier-syntax">idb</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>§20. </b>And that about wraps up symbol declaration, except for the routine which
|
|
actually declares symbols:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">equation_symbol</span><span class="plain-syntax"> *</span><span class="function-syntax">Equations::eqn_add_symbol</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Equations::eqn_add_symbol</span></span>:<br/><a href="7-eqt.html#SP16">§16</a>, <a href="7-eqt.html#SP18">§18</a>, <a href="7-eqt.html#SP19">§19</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">spec</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::first_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_symbol</span><span class="plain-syntax"> **</span><span class="identifier-syntax">list_head</span><span class="plain-syntax"> = &</span><span class="identifier-syntax">standard_equation_symbols</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">) </span><span class="identifier-syntax">list_head</span><span class="plain-syntax"> = &(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">symbol_list</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ev</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ev</span><span class="plain-syntax"> = *</span><span class="identifier-syntax">list_head</span><span class="plain-syntax">; </span><span class="identifier-syntax">ev</span><span class="plain-syntax">; </span><span class="identifier-syntax">ev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::match_cs</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">name</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">ev</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">equation_symbol</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">var_kind</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">function_notated</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">var_const</span><span class="plain-syntax"> = </span><span class="identifier-syntax">spec</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">list_head</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) *</span><span class="identifier-syntax">list_head</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ev</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">f</span><span class="plain-syntax"> = *</span><span class="identifier-syntax">list_head</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">f</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">f</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax">)) </span><span class="identifier-syntax">f</span><span class="plain-syntax"> = </span><span class="identifier-syntax">f</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">f</span><span class="plain-syntax">-></span><span class="identifier-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ev</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">W</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">temp_constant</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">ev</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>§21. </b>This is where the criterion for being a valid symbol name is expressed:
|
|
it matches only a single word, and only if the lettering matches the regular
|
|
expression <span class="extract"><span class="extract-syntax">[A-Za-z]?{1,8}\d?{0,2}</span></span>.
|
|
</p>
|
|
|
|
<pre class="Preform-displayed-code all-displayed-code code-font">
|
|
<span class="Preform-function-syntax"><valid-equation-symbol></span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">internal</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">{</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><a href="7-eqt.html#SP22" class="function-link"><span class="Preform-function-syntax">Equations::equation_symbol_legal</span></a><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">)) {</span>
|
|
<span class="Preform-plain-syntax"> ==> { </span><span class="Preform-identifier-syntax">Wordings::first_wn</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">), - };</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">;</span>
|
|
<span class="Preform-plain-syntax"> }</span>
|
|
<span class="Preform-plain-syntax"> ==> { </span><span class="Preform-identifier-syntax">fail</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">nonterminal</span><span class="Preform-plain-syntax"> };</span>
|
|
<span class="Preform-plain-syntax">}</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP22" class="paragraph-anchor"></a><b>§22. </b>Using:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::equation_symbol_legal</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">Equations::equation_symbol_legal</span></span>:<br/><a href="7-eqt.html#SP18">§18</a>, <a href="7-eqt.html#SP21">§21</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::length</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">) == </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lexer::word_raw_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">, </span><span class="identifier-syntax">letters</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">digits</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">name_legal</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">]; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Characters::isdigit</span><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">)) </span><span class="identifier-syntax">digits</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Characters::isalpha</span><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">)) { </span><span class="identifier-syntax">letters</span><span class="plain-syntax">++; </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">digits</span><span class="plain-syntax"> > </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">name_legal</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">name_legal</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax"> >= </span><span class="constant-syntax">13</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">letters</span><span class="plain-syntax"> > </span><span class="constant-syntax">10</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">digits</span><span class="plain-syntax"> > </span><span class="constant-syntax">2</span><span class="plain-syntax">)) </span><span class="identifier-syntax">name_legal</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">name_legal</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP23" class="paragraph-anchor"></a><b>§23. Equation nodes. </b>The parsed equation is a tree full of nodes, so we need routines to make
|
|
and examine them.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="function-syntax">Equations::enode_new</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">Equations::enode_new</span></span>:<br/><a href="7-eqt.html#SP24">§24</a>, <a href="7-eqt.html#SP26">§26</a>, <a href="7-eqt.html#SP26_1_3">§26.1.3</a>, <a href="7-eqt.html#SP30">§30</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">enode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">equation_node</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">enode</span><span class="plain-syntax">-></span><span class="identifier-syntax">eqn_type</span><span class="plain-syntax"> = </span><span class="identifier-syntax">t</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">enode</span><span class="plain-syntax">-></span><span class="identifier-syntax">eqn_operation</span><span class="plain-syntax"> = -1;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">enode</span><span class="plain-syntax">-></span><span class="identifier-syntax">enode_arity</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">enode</span><span class="plain-syntax">-></span><span class="identifier-syntax">leaf_constant</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">enode</span><span class="plain-syntax">-></span><span class="identifier-syntax">leaf_symbol</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">enode</span><span class="plain-syntax">-></span><span class="identifier-syntax">enode_operands</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">enode</span><span class="plain-syntax">-></span><span class="identifier-syntax">gK_before</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::FloatingPoint::new_gk</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">); </span><span class="comment-syntax"> unknown for now</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">enode</span><span class="plain-syntax">-></span><span class="identifier-syntax">gK_after</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::FloatingPoint::new_gk</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">); </span><span class="comment-syntax"> unknown for now</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">enode</span><span class="plain-syntax">-></span><span class="identifier-syntax">enode_promotion</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">enode</span><span class="plain-syntax">-></span><span class="identifier-syntax">rational_n</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">enode</span><span class="plain-syntax">-></span><span class="identifier-syntax">rational_m</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">enode</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP24" class="paragraph-anchor"></a><b>§24. </b>This is how we make the three kinds of enode permitted in the final compiled
|
|
equation. (The other kinds can be created using <span class="extract"><span class="extract-syntax">Equations::enode_new</span></span> directly.)
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="function-syntax">Equations::enode_new_op</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Equations::enode_new_op</span></span>:<br/><a href="7-eqt.html#SP26_1_3">§26.1.3</a>, <a href="7-eqt.html#SP26_2">§26.2</a>, <a href="7-eqt.html#SP41_3_1">§41.3.1</a>, <a href="7-eqt.html#SP41_4">§41.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">op</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">enode</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP23" class="function-link"><span class="function-syntax">Equations::enode_new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">OPERATION_EQN</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">enode</span><span class="plain-syntax">-></span><span class="identifier-syntax">eqn_operation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">op</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">enode</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="function-syntax">Equations::enode_new_symbol</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">Equations::enode_new_symbol</span></span>:<br/><a href="7-eqt.html#SP26_1_1_1">§26.1.1.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ev</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">enode</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP23" class="function-link"><span class="function-syntax">Equations::enode_new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">SYMBOL_EQN</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">enode</span><span class="plain-syntax">-></span><span class="identifier-syntax">leaf_symbol</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ev</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">enode</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="function-syntax">Equations::enode_new_constant</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">Equations::enode_new_constant</span></span>:<br/><a href="7-eqt.html#SP26_1_2">§26.1.2</a>, <a href="7-eqt.html#SP41_3_1">§41.3.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">spec</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">enode</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP23" class="function-link"><span class="function-syntax">Equations::enode_new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">CONSTANT_EQN</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">enode</span><span class="plain-syntax">-></span><span class="identifier-syntax">leaf_constant</span><span class="plain-syntax"> = </span><span class="identifier-syntax">spec</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">enode</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP25" class="paragraph-anchor"></a><b>§25. </b>Being able to log nodes is useful, if only because it's always pretty to
|
|
watch shift-reduce parsers in action.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::log_equation_node</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">Equations::log_equation_node</span></span>:<br/><a href="7-eqt.html#SP11">§11</a>, <a href="7-eqt.html#SP29">§29</a>, <a href="7-eqt.html#SP39_4">§39.4</a>, <a href="7-eqt.html#SP41_3_2">§41.3.2</a>, <a href="7-eqt.html#SP44">§44</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tok</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP25" class="function-link"><span class="function-syntax">Equations::log_equation_node_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::log_equation_node_inner</span><span class="plain-syntax">(</span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tok</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">d</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax"><</span><span class="identifier-syntax">d</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">+1<</span><span class="identifier-syntax">d</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" "</span><span class="plain-syntax">); </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"+---"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"<NULL>\n"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax"> == </span><span class="constant-syntax">OPERATION_EQN</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PLUS_OPERATION:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"<add>"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">MINUS_OPERATION:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"<subtract>"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">DIVIDE_OPERATION:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"<divide>"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TIMES_OPERATION:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"<multiply>"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">IMPLICIT_TIMES_OPERATION:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"<implicitly multiply>"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">IMPLICIT_APPLICATION_OPERATION:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"<apply function>"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EQUALS_OPERATION:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"<set equal>"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">ROOT_OPERATION:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"<square root>"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">REALROOT_OPERATION:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"<real square root>"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CUBEROOT_OPERATION:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"<cube root>"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">POWER_OPERATION:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"<to the power>"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">UNARY_MINUS_OPERATION:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"<unary subtraction>"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"<op-%d>"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax"> == </span><span class="constant-syntax">SYMBOL_EQN</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"<symbol-%W>"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">leaf_symbol</span><span class="plain-syntax">-></span><span class="element-syntax">name</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax"> == </span><span class="constant-syntax">CONSTANT_EQN</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"<constant-$P>"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">leaf_constant</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax"> == </span><span class="constant-syntax">OPEN_BRACKET_EQN</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"<open-bracket>"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax"> == </span><span class="constant-syntax">CLOSE_BRACKET_EQN</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"<close-bracket>"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax"> == </span><span class="constant-syntax">END_EQN</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"<end>"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"<bad-eqn>\n"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" : "</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::log_gk</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_before</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::log_gk</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax"> == </span><span class="constant-syntax">OPERATION_EQN</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax"><tok-></span><span class="element-syntax">enode_arity</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP25" class="function-link"><span class="function-syntax">Equations::log_equation_node_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">], </span><span class="identifier-syntax">d</span><span class="plain-syntax">+1);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP26" class="paragraph-anchor"></a><b>§26. Tokenising equations. </b>We break up the word range \((w_1, w_2)\) into tokens of equation matter. Word
|
|
boundaries divide tokens, but so do operators like <span class="extract"><span class="extract-syntax">+</span></span>, and boundaries can
|
|
also occur in runs of alphanumerics if we spot symbol names: thus <span class="extract"><span class="extract-syntax">mv^21</span></span>
|
|
will be divided into tokens <span class="extract"><span class="extract-syntax">m</span></span>, <span class="extract"><span class="extract-syntax">v</span></span>, <span class="extract"><span class="extract-syntax">^</span></span>, <span class="extract"><span class="extract-syntax">21</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary">The following routine sends each token in turn to the shift/reduce parser
|
|
below, encoding each token as an enode. We return <span class="extract"><span class="extract-syntax">NULL</span></span> if a problem message
|
|
has to be issued, or else a pointer to the parsed tree if we succeed.
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_ENODES_IN_EXPRESSION</span><span class="plain-syntax"> </span><span class="constant-syntax">100</span>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="function-syntax">Equations::eqn_parse</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">Equations::eqn_parse</span></span>:<br/><a href="7-eqt.html#SP11">§11</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">equation_text</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP30" class="function-link"><span class="function-syntax">Equations::enode_sr_start</span></a><span class="plain-syntax">(); </span><span class="comment-syntax"> start the shift-reduce parser</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">previous_token</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">enode_count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> number of tokens shipped so far</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bl</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> bracket nesting level</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">), </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">wn</span><span class="plain-syntax"> <= </span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) || (</span><span class="identifier-syntax">p</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lexer::word_raw_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">++); }</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> we are now at character </span><span class="extract"><span class="extract-syntax">i</span></span><span class="comment-syntax"> in string </span><span class="extract"><span class="extract-syntax">p</span></span><span class="comment-syntax">, while </span><span class="extract"><span class="extract-syntax">wn</span></span><span class="comment-syntax"> is the next word</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">token</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP26_1" class="named-paragraph-link"><span class="named-paragraph">Break off a token from the current position</span><span class="named-paragraph-number">26.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP26_2" class="named-paragraph-link"><span class="named-paragraph">Issue the token to the shift-reduce parser</span><span class="named-paragraph-number">26.2</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">previous_token</span><span class="plain-syntax"> = </span><span class="identifier-syntax">token</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="7-eqt.html#SP32" class="function-link"><span class="function-syntax">Equations::enode_sr_token</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><a href="7-eqt.html#SP23" class="function-link"><span class="function-syntax">Equations::enode_new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">END_EQN</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP26_3" class="named-paragraph-link"><span class="named-paragraph">Equation fails in the shift-reduce parser</span><span class="named-paragraph-number">26.3</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">result</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP31" class="function-link"><span class="function-syntax">Equations::enode_sr_result</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">BelievedImpossible</span><span class="plain-syntax">), </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="string-syntax">""</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"this seems to use brackets in a mismatched way, since there "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"are different numbers of left and right brackets '(' and ')'."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP26_1" class="paragraph-anchor"></a><b>§26.1. </b>Note that symbol names can't begin with a digit.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Break off a token from the current position</span><span class="named-paragraph-number">26.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Characters::isalpha</span><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">)) </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP26_1_1" class="named-paragraph-link"><span class="named-paragraph">Break off a symbol name as a token</span><span class="named-paragraph-number">26.1.1</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Characters::isdigit</span><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">)) </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP26_1_2" class="named-paragraph-link"><span class="named-paragraph">Break off a numeric constant as a token</span><span class="named-paragraph-number">26.1.2</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP26_1_3" class="named-paragraph-link"><span class="named-paragraph">Break off an operator or a piece of punctuation as a token</span><span class="named-paragraph-number">26.1.3</span></a></span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP26">§26</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP26_1_1" class="paragraph-anchor"></a><b>§26.1.1. </b>Note that symbols are identified by recognition: without knowing the identities
|
|
of the symbols, the syntax alone wouldn't tell us how to break them. We can only
|
|
break <span class="extract"><span class="extract-syntax">mc^2</span></span> as <span class="extract"><span class="extract-syntax">m</span></span> followed by <span class="extract"><span class="extract-syntax">c^2</span></span> if we know that <span class="extract"><span class="extract-syntax">m</span></span> and <span class="extract"><span class="extract-syntax">c</span></span> are symbols,
|
|
rather than <span class="extract"><span class="extract-syntax">mc</span></span>. (This is one reason why most programming languages don't
|
|
allow implicit multiplication.)
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Break off a symbol name as a token</span><span class="named-paragraph-number">26.1.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_of_symbol</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">; </span><span class="comment-syntax"> the length of the symbol name we try to break off</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax">=0; (</span><span class="identifier-syntax">j</span><span class="plain-syntax"><14) && (</span><span class="identifier-syntax">Characters::isalnum</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">+</span><span class="identifier-syntax">j</span><span class="plain-syntax">])) && (</span><span class="identifier-syntax">token</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">); </span><span class="identifier-syntax">j</span><span class="plain-syntax">++)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_of_symbol</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">+</span><span class="identifier-syntax">j</span><span class="plain-syntax">]);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">equation_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">standard_equation_symbols</span><span class="plain-syntax">; </span><span class="identifier-syntax">ev</span><span class="plain-syntax">; </span><span class="identifier-syntax">ev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP26_1_1_1" class="named-paragraph-link"><span class="named-paragraph">Look for this symbol name</span><span class="named-paragraph-number">26.1.1.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">token</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax">=1; (</span><span class="identifier-syntax">j</span><span class="plain-syntax"><15) && (</span><span class="identifier-syntax">Characters::isalnum</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">+</span><span class="identifier-syntax">j</span><span class="plain-syntax">-1])) && (</span><span class="identifier-syntax">token</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">); </span><span class="identifier-syntax">j</span><span class="plain-syntax">++) {</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> copy the first </span><span class="extract"><span class="extract-syntax">j</span></span><span class="comment-syntax"> characters into a C string:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::clear</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_of_symbol</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">k</span><span class="plain-syntax"><</span><span class="identifier-syntax">j</span><span class="plain-syntax">; </span><span class="identifier-syntax">k</span><span class="plain-syntax">++) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_of_symbol</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">+</span><span class="identifier-syntax">k</span><span class="plain-syntax">]);</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> try to identify this as one of the declared symbols:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ev</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">symbol_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">ev</span><span class="plain-syntax">; </span><span class="identifier-syntax">ev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP26_1_1_1" class="named-paragraph-link"><span class="named-paragraph">Look for this symbol name</span><span class="named-paragraph-number">26.1.1.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">token</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_problem_S</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationTokenUnrecognised</span><span class="plain-syntax">), </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_of_symbol</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"the symbol '%3' is one that I don't recognise. It doesn't "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"seem to be declared after the equation - for instance, "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"by adding 'where %3 is a number'."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_of_symbol</span><span class="plain-syntax">)</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP26_1">§26.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP26_1_1_1" class="paragraph-anchor"></a><b>§26.1.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Look for this symbol name</span><span class="named-paragraph-number">26.1.1.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_wide_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_of_symbol</span><span class="plain-syntax">, </span><span class="identifier-syntax">Lexer::word_raw_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">name</span><span class="plain-syntax">)))) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">token</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP24" class="function-link"><span class="function-syntax">Equations::enode_new_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ev</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> += </span><span class="identifier-syntax">j</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP26_1_1">§26.1.1</a> (twice).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP26_1_2" class="paragraph-anchor"></a><b>§26.1.2. </b>The following is reliable because a string of digits not starting with a
|
|
0 is always a valid number to Inform unless it overflows the virtual machine's
|
|
capacity; and so is the number 0 itself.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Break off a numeric constant as a token</span><span class="named-paragraph-number">26.1.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] == </span><span class="character-syntax">'0'</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">Characters::isdigit</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">+1]))) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationLeadingZero</span><span class="plain-syntax">), </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="string-syntax">""</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"a number in an equation isn't allowed to begin with a "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"'0' digit, so an equation like 'M = 007+Q' is against the rules."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_of_number</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP26_1_2_1" class="named-paragraph-link"><span class="named-paragraph">Copy the literal number into a C string, flanked by spaces</span><span class="named-paragraph-number">26.1.2.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> now sneakily add this to the word stream, and let the S-parser read it:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">NW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Feeds::feed_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_of_number</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_of_number</span><span class="plain-syntax">)</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">spec</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax"><s-type-expression></span><span class="plain-syntax">(</span><span class="identifier-syntax">NW</span><span class="plain-syntax">)) </span><span class="identifier-syntax">spec</span><span class="plain-syntax"> = </span><span class="function-syntax"><<rp>></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">BelievedImpossible</span><span class="plain-syntax">), </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="string-syntax">""</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"there's a literal number in that equation which doesn't make "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"sense to me."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> this can only go wrong if there was an overflow, and a problem will have been issued for that:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">CONSTANT_NT</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">token</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP24" class="function-link"><span class="function-syntax">Equations::enode_new_constant</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP26_1">§26.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP26_1_2_1" class="paragraph-anchor"></a><b>§26.1.2.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Copy the literal number into a C string, flanked by spaces</span><span class="named-paragraph-number">26.1.2.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Characters::isdigit</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">])) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_of_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">++]);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] == </span><span class="character-syntax">'.'</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_of_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">++]);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Characters::isdigit</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">])) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_of_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">++]);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">LiteralReals::ismultiplicationsign</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">])) && (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">+1] == </span><span class="character-syntax">'1'</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">+2] == </span><span class="character-syntax">'0'</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">+3] == </span><span class="character-syntax">'^'</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_of_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">++]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_of_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">++]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_of_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">++]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_of_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">++]);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Characters::isdigit</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">])) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_of_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">++]);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_of_number</span><span class="plain-syntax">, </span><span class="character-syntax">' '</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP26_1_2">§26.1.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP26_1_3" class="paragraph-anchor"></a><b>§26.1.3. </b>Which leaves just the easiest case:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Break off an operator or a piece of punctuation as a token</span><span class="named-paragraph-number">26.1.3</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'='</span><span class="plain-syntax">: </span><span class="identifier-syntax">token</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP24" class="function-link"><span class="function-syntax">Equations::enode_new_op</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">EQUALS_OPERATION</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'+'</span><span class="plain-syntax">: </span><span class="identifier-syntax">token</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP24" class="function-link"><span class="function-syntax">Equations::enode_new_op</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PLUS_OPERATION</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'-'</span><span class="plain-syntax">:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">previous_token</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) ||</span>
|
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">previous_token</span><span class="plain-syntax">-></span><span class="identifier-syntax">eqn_type</span><span class="plain-syntax"> == </span><span class="constant-syntax">OPERATION_EQN</span><span class="plain-syntax">) ||</span>
|
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">previous_token</span><span class="plain-syntax">-></span><span class="identifier-syntax">eqn_type</span><span class="plain-syntax"> == </span><span class="constant-syntax">OPEN_BRACKET_EQN</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">token</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP24" class="function-link"><span class="function-syntax">Equations::enode_new_op</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">UNARY_MINUS_OPERATION</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">token</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP24" class="function-link"><span class="function-syntax">Equations::enode_new_op</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">MINUS_OPERATION</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'/'</span><span class="plain-syntax">: </span><span class="identifier-syntax">token</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP24" class="function-link"><span class="function-syntax">Equations::enode_new_op</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">DIVIDE_OPERATION</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'*'</span><span class="plain-syntax">: </span><span class="identifier-syntax">token</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP24" class="function-link"><span class="function-syntax">Equations::enode_new_op</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">TIMES_OPERATION</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'^'</span><span class="plain-syntax">: </span><span class="identifier-syntax">token</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP24" class="function-link"><span class="function-syntax">Equations::enode_new_op</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">POWER_OPERATION</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'('</span><span class="plain-syntax">: </span><span class="identifier-syntax">token</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP23" class="function-link"><span class="function-syntax">Equations::enode_new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">OPEN_BRACKET_EQN</span><span class="plain-syntax">); </span><span class="identifier-syntax">bl</span><span class="plain-syntax">++; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">')'</span><span class="plain-syntax">: </span><span class="identifier-syntax">token</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP23" class="function-link"><span class="function-syntax">Equations::enode_new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">CLOSE_BRACKET_EQN</span><span class="plain-syntax">); </span><span class="identifier-syntax">bl</span><span class="plain-syntax">--; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">symbol</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">symbol</span><span class="plain-syntax">, (</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_problem_S</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationOperatorUnrecognised</span><span class="plain-syntax">), </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">symbol</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"the symbol '%3' is one that I don't recognise. I was "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"expecting an arithmetic sign, '+', '-', '*','/', or '^', "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"or else '=' or a bracket '(' or ')'."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Bad operator '%S'\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">symbol</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">symbol</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">++;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP26_1">§26.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP26_2" class="paragraph-anchor"></a><b>§26.2. </b>So now we have our next token, and are ready to ship it. But if we
|
|
detect an implicit multiplication, for instance between <span class="extract"><span class="extract-syntax">m</span></span> and <span class="extract"><span class="extract-syntax">c^2</span></span>
|
|
in <span class="extract"><span class="extract-syntax">E=mc^2</span></span>, we issue that as an <span class="extract"><span class="extract-syntax">IMPLICIT_TIMES_OPERATION</span></span> enode in
|
|
between; and in <span class="extract"><span class="extract-syntax">log pi</span></span> we issue an <span class="extract"><span class="extract-syntax">IMPLICIT_APPLICATION_OPERATION</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue the token to the shift-reduce parser</span><span class="named-paragraph-number">26.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="7-eqt.html#SP28" class="function-link"><span class="function-syntax">Equations::application_is_implied</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">previous_token</span><span class="plain-syntax">, </span><span class="identifier-syntax">token</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="7-eqt.html#SP32" class="function-link"><span class="function-syntax">Equations::enode_sr_token</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><a href="7-eqt.html#SP24" class="function-link"><span class="function-syntax">Equations::enode_new_op</span></a><span class="plain-syntax">(</span><span class="constant-syntax">IMPLICIT_APPLICATION_OPERATION</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP26_3" class="named-paragraph-link"><span class="named-paragraph">Equation fails in the shift-reduce parser</span><span class="named-paragraph-number">26.3</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">enode_count</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="7-eqt.html#SP27" class="function-link"><span class="function-syntax">Equations::multiplication_is_implied</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">previous_token</span><span class="plain-syntax">, </span><span class="identifier-syntax">token</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="7-eqt.html#SP32" class="function-link"><span class="function-syntax">Equations::enode_sr_token</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><a href="7-eqt.html#SP24" class="function-link"><span class="function-syntax">Equations::enode_new_op</span></a><span class="plain-syntax">(</span><span class="constant-syntax">IMPLICIT_TIMES_OPERATION</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP26_3" class="named-paragraph-link"><span class="named-paragraph">Equation fails in the shift-reduce parser</span><span class="named-paragraph-number">26.3</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">enode_count</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="7-eqt.html#SP32" class="function-link"><span class="function-syntax">Equations::enode_sr_token</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">token</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP26_3" class="named-paragraph-link"><span class="named-paragraph">Equation fails in the shift-reduce parser</span><span class="named-paragraph-number">26.3</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">enode_count</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">enode_count</span><span class="plain-syntax"> >= </span><span class="constant-syntax">MAX_ENODES_IN_EXPRESSION</span><span class="plain-syntax"> - </span><span class="constant-syntax">2</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationTooComplex</span><span class="plain-syntax">), </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="string-syntax">""</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"this is too long and complex an equation."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP26">§26</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP26_3" class="paragraph-anchor"></a><b>§26.3. </b>In case any of the enode insertions fail. It's tricky to generate good error
|
|
messages and recover well when an operator-precedence grammar fails to match in
|
|
a parser like this, so we'll fall back on this:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Equation fails in the shift-reduce parser</span><span class="named-paragraph-number">26.3</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationMispunctuated</span><span class="plain-syntax">), </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="string-syntax">""</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"this seems to be wrongly punctuated, and doesn't make sense as a "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"mathematical formula."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP26">§26</a>, <a href="7-eqt.html#SP26_2">§26.2</a> (three times).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP27" class="paragraph-anchor"></a><b>§27. </b>Lastly, here is when multiplication is implied:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::multiplication_is_implied</span><button class="popup" onclick="togglePopup('usagePopup17')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup17">Usage of <span class="code-font"><span class="function-syntax">Equations::multiplication_is_implied</span></span>:<br/><a href="7-eqt.html#SP26_2">§26.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">previous_token</span><span class="plain-syntax">, </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">token</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">lt</span><span class="plain-syntax">, </span><span class="identifier-syntax">rt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">token</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">previous_token</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">lt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">previous_token</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax">; </span><span class="identifier-syntax">rt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">token</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">lt</span><span class="plain-syntax"> == </span><span class="constant-syntax">SYMBOL_EQN</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">lt</span><span class="plain-syntax"> == </span><span class="constant-syntax">CONSTANT_EQN</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">lt</span><span class="plain-syntax"> == </span><span class="constant-syntax">CLOSE_BRACKET_EQN</span><span class="plain-syntax">)) &&</span>
|
|
<span class="plain-syntax"> ((</span><span class="identifier-syntax">rt</span><span class="plain-syntax"> == </span><span class="constant-syntax">SYMBOL_EQN</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">rt</span><span class="plain-syntax"> == </span><span class="constant-syntax">CONSTANT_EQN</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">rt</span><span class="plain-syntax"> == </span><span class="constant-syntax">OPEN_BRACKET_EQN</span><span class="plain-syntax">)))</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP28" class="paragraph-anchor"></a><b>§28. </b>And when function application is implied:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::application_is_implied</span><button class="popup" onclick="togglePopup('usagePopup18')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup18">Usage of <span class="code-font"><span class="function-syntax">Equations::application_is_implied</span></span>:<br/><a href="7-eqt.html#SP26_2">§26.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">previous_token</span><span class="plain-syntax">, </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">token</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">lt</span><span class="plain-syntax">, </span><span class="identifier-syntax">rt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">token</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">previous_token</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">lt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">previous_token</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax">; </span><span class="identifier-syntax">rt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">token</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">lt</span><span class="plain-syntax"> == </span><span class="constant-syntax">SYMBOL_EQN</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">previous_token</span><span class="plain-syntax">-></span><span class="element-syntax">leaf_symbol</span><span class="plain-syntax">-></span><span class="element-syntax">function_notated</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP29" class="paragraph-anchor"></a><b>§29. The shift-reduce parser. </b>This is a classic algorithm for expression-evaluator grammars; see for
|
|
instance Aho, Sethi and Ullman, "Compilers", section 4.6 in the second edition.
|
|
We use a pair of stacks. The SR stack holds possible attempts to understand
|
|
what we have so far, given the tokens that have arrived; the emitter stack
|
|
holds nodes which form pieces of the output tree as it is assembled. Nodes
|
|
flow from our input, are usually "shifted" onto the SR stack for a while,
|
|
are eventually "reduced" in clumps taken off this stack and "emitted",
|
|
then go onto the emitter stack, and are finally removed as they are made
|
|
into trees.
|
|
</p>
|
|
|
|
<p class="commentary">The flow is therefore always forwards; tokens can't slosh back and forth
|
|
between the stacks. On each iteration, at least one token makes progress,
|
|
so if there are \(N\) tokens of input (including both end marker tokens) then we
|
|
take at worst \(2N\) steps to finish. Each stack can't need more than \(N\)
|
|
entries, and \(N\) is bounded above by <span class="extract"><span class="extract-syntax">MAX_ENODES_IN_EXPRESSION</span></span> plus 2
|
|
(allowing for the end markers). So:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">SR_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">SR_stack</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_ENODES_IN_EXPRESSION</span><span class="plain-syntax">+2];</span>
|
|
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">emitter_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">emitter_stack</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_ENODES_IN_EXPRESSION</span><span class="plain-syntax">+2];</span>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::log_sr_stacks</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"SR: "</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax"><</span><span class="identifier-syntax">SR_sp</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" %d: "</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">); </span><a href="7-eqt.html#SP25" class="function-link"><span class="function-syntax">Equations::log_equation_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">SR_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]); }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"EMITTER: "</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax"><</span><span class="identifier-syntax">emitter_sp</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" %d: "</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">); </span><a href="7-eqt.html#SP25" class="function-link"><span class="function-syntax">Equations::log_equation_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">emitter_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]); }</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP30" class="paragraph-anchor"></a><b>§30. </b>The start and finish are as follows. At the start, the emitter stack is
|
|
empty and the SR stack contains an <span class="extract"><span class="extract-syntax">END_EQN</span></span> token, which represents the
|
|
left-hand end of the expression. (Another such token, this time representing the
|
|
right-hand end, will be sent by the routines above at the end of the stream. So
|
|
there will be two <span class="extract"><span class="extract-syntax">END_EQN</span></span> tokens in play.)
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::enode_sr_start</span><button class="popup" onclick="togglePopup('usagePopup19')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup19">Usage of <span class="code-font"><span class="function-syntax">Equations::enode_sr_start</span></span>:<br/><a href="7-eqt.html#SP26">§26</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">SR_stack</span><span class="plain-syntax">[0] = </span><a href="7-eqt.html#SP23" class="function-link"><span class="function-syntax">Equations::enode_new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">END_EQN</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">SR_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">emitter_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP31" class="paragraph-anchor"></a><b>§31. </b>If we have succeeded, the end state of the emitter stack contains a single
|
|
node: the head of the tree we have grown to represent the expression.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="function-syntax">Equations::enode_sr_result</span><button class="popup" onclick="togglePopup('usagePopup20')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup20">Usage of <span class="code-font"><span class="function-syntax">Equations::enode_sr_result</span></span>:<br/><a href="7-eqt.html#SP26">§26</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">emitter_stack</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP32" class="paragraph-anchor"></a><b>§32. </b>So the following is the routine which iteratively deals with tokens as
|
|
they arrive. As noted above, the loop however ominous always terminates.
|
|
</p>
|
|
|
|
<p class="commentary">For proofs and explanations see ASU, but the idea is simple enough: as we
|
|
see the expression a little at a time, we collect possibilities of how to
|
|
read it on the SR-stack, until we reach a point where it's possible to tell
|
|
what was meant; we then reduce the SR-stack by taking the winning possibility
|
|
off the top and moving it to the emitter stack. For instance, if we have
|
|
read <span class="extract"><span class="extract-syntax">4 + 5</span></span> then we don't know yet whether the <span class="extract"><span class="extract-syntax">+</span></span> will add the 4 to the 5;
|
|
if the next token is <span class="extract"><span class="extract-syntax">+</span></span> or <span class="extract"><span class="extract-syntax">END_EQN</span></span> then it will, but if the next token
|
|
is <span class="extract"><span class="extract-syntax">*</span></span> then it won't, because we're looking at something like <span class="extract"><span class="extract-syntax">4 + 5 * 6</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary">If the next token is of lower precedence than <span class="extract"><span class="extract-syntax">+</span></span> then we "reduce" —
|
|
telling the emitter about the addition, which we now understand — but if
|
|
it's higher, as with <span class="extract"><span class="extract-syntax">*</span></span>, then we "shift", meaning, we postpone worrying
|
|
about the addition and start worrying about the multiplication instead;
|
|
our new problem, working out what <span class="extract"><span class="extract-syntax">*</span></span> applies to, sits on top of the
|
|
addition problem on the SR-stack.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::enode_sr_token</span><button class="popup" onclick="togglePopup('usagePopup21')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup21">Usage of <span class="code-font"><span class="function-syntax">Equations::enode_sr_token</span></span>:<br/><a href="7-eqt.html#SP26">§26</a>, <a href="7-eqt.html#SP26_2">§26.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tok</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">safety_cutout</span><span class="plain-syntax"> = </span><span class="constant-syntax">3</span><span class="plain-syntax">*</span><span class="constant-syntax">MAX_ENODES_IN_EXPRESSION</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SR_sp</span><span class="plain-syntax"> <= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"SR stack empty"</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">SR_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">SR_sp</span><span class="plain-syntax">-1]-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax"> == </span><span class="constant-syntax">END_EQN</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax"> == </span><span class="constant-syntax">END_EQN</span><span class="plain-syntax">)) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="7-eqt.html#SP34" class="function-link"><span class="function-syntax">Equations::enode_lt</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">SR_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">SR_sp</span><span class="plain-syntax">-1], </span><span class="identifier-syntax">tok</span><span class="plain-syntax">)) || (</span><a href="7-eqt.html#SP34" class="function-link"><span class="function-syntax">Equations::enode_eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">SR_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">SR_sp</span><span class="plain-syntax">-1], </span><span class="identifier-syntax">tok</span><span class="plain-syntax">)))</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP32_1" class="named-paragraph-link"><span class="named-paragraph">Shift an enode onto the SR-stack</span><span class="named-paragraph-number">32.1</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="7-eqt.html#SP34" class="function-link"><span class="function-syntax">Equations::enode_gt</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">SR_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">SR_sp</span><span class="plain-syntax">-1], </span><span class="identifier-syntax">tok</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP32_2" class="named-paragraph-link"><span class="named-paragraph">Reduce some enodes from the SR-stack to the emitter stack</span><span class="named-paragraph-number">32.2</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">safety_cutout</span><span class="plain-syntax">-- < </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"SR parser deadlocked"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">emitter_sp</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">SR_sp</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP32_1" class="paragraph-anchor"></a><b>§32.1. </b>After shifting, we return a signal of success, which asks for the next
|
|
token to be sent.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Shift an enode onto the SR-stack</span><span class="named-paragraph-number">32.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">SR_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">SR_sp</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">tok</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP32">§32</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP32_2" class="paragraph-anchor"></a><b>§32.2. </b>The ASU book is a little vague about what happens if there is an underflow
|
|
here, I think because it's possible to set up the grammar such that an
|
|
underflow cannot occur. But I can see no obvious proof that it will never
|
|
occur for us given syntactically incorrect input, so we will return <span class="extract"><span class="extract-syntax">FALSE</span></span>
|
|
on an underflow to be safe.
|
|
</p>
|
|
|
|
<p class="commentary">Note that we can never emit the bottom-most token on the SR stack: that's the
|
|
left-hand end marker, so can never be validly part of any arithmetic. So
|
|
an underflow occurs if that's all that's left, i.e., when the SR stack pointer
|
|
is 1, not 0.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Reduce some enodes from the SR-stack to the emitter stack</span><span class="named-paragraph-number">32.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">do</span><span class="plain-syntax"> { </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SR_sp</span><span class="plain-syntax"> <= </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="7-eqt.html#SP33" class="function-link"><span class="function-syntax">Equations::enode_emit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">SR_stack</span><span class="plain-syntax">[--</span><span class="identifier-syntax">SR_sp</span><span class="plain-syntax">]) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">SR_sp</span><span class="plain-syntax"> >= </span><span class="constant-syntax">1</span><span class="plain-syntax">) && (</span><a href="7-eqt.html#SP34" class="function-link"><span class="function-syntax">Equations::enode_lt</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">SR_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">SR_sp</span><span class="plain-syntax">-1], </span><span class="identifier-syntax">SR_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">SR_sp</span><span class="plain-syntax">]) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">));</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP32">§32</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP33" class="paragraph-anchor"></a><b>§33. </b>The key point is that if nodes arrive at the SR parser in their
|
|
ordinary order of mathematical writing, then they "reduce" off the
|
|
SR stack and onto the emitter stack in reverse Polish notation order.
|
|
Thus the sequence <span class="extract"><span class="extract-syntax">4 + 2 * 7</span></span> is emitted as <span class="extract"><span class="extract-syntax">4 2 7 * +</span></span>. RPN has no
|
|
need of brackets to clarify the sequence of operation, and it's very
|
|
easy to build a tree from.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::enode_emit</span><button class="popup" onclick="togglePopup('usagePopup22')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup22">Usage of <span class="code-font"><span class="function-syntax">Equations::enode_emit</span></span>:<br/><a href="7-eqt.html#SP32_2">§32.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tok</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">SYMBOL_EQN:</span><span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CONSTANT_EQN:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">emitter_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">emitter_sp</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">tok</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">OPERATION_EQN:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax"> == </span><span class="constant-syntax">IMPLICIT_TIMES_OPERATION</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TIMES_OPERATION</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax"> == </span><span class="constant-syntax">IMPLICIT_APPLICATION_OPERATION</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_arity</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Dimensions::arithmetic_op_is_unary</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_arity</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_arity</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_arity</span><span class="plain-syntax"> - </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax"> >= </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">--) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">emitter_sp</span><span class="plain-syntax">--;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">emitter_sp</span><span class="plain-syntax"> < </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">emitter_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">emitter_sp</span><span class="plain-syntax">];</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">emitter_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">emitter_sp</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">tok</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP34" class="paragraph-anchor"></a><b>§34. </b>All we need now is to decide the order of precedence of our tokens,
|
|
though this isn't as simple as it looks, because they are not all
|
|
symmetrical left-right. That's obviously true of things like an open
|
|
bracket <span class="extract"><span class="extract-syntax">(</span></span>, which affects the stuff to the left very differently from
|
|
the stuff to the right. But it is also true of operators. <span class="extract"><span class="extract-syntax">+</span></span> may be
|
|
associative mathematically, but in computing there's a difference
|
|
between evaluating <span class="extract"><span class="extract-syntax">a + (b+c)</span></span> and <span class="extract"><span class="extract-syntax">(a+b) + c</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary">All of this means there's no simple order relationship on the tokens,
|
|
where \(T<S\) if and only if \(S>T\). We order them using a numerical score,
|
|
but they get one score \(f(T)\) if they appear on the left and another
|
|
score \(g(T)\) if they appear on the right:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::enode_lt</span><button class="popup" onclick="togglePopup('usagePopup23')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup23">Usage of <span class="code-font"><span class="function-syntax">Equations::enode_lt</span></span>:<br/><a href="7-eqt.html#SP32">§32</a>, <a href="7-eqt.html#SP32_2">§32.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tok1</span><span class="plain-syntax">, </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tok2</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">f_left</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP35" class="function-link"><span class="function-syntax">Equations::f_function</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">tok1</span><span class="plain-syntax">), </span><span class="identifier-syntax">g_right</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP36" class="function-link"><span class="function-syntax">Equations::g_function</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">tok2</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">f_left</span><span class="plain-syntax"> < </span><span class="identifier-syntax">g_right</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::enode_eq</span><button class="popup" onclick="togglePopup('usagePopup24')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup24">Usage of <span class="code-font"><span class="function-syntax">Equations::enode_eq</span></span>:<br/><a href="7-eqt.html#SP32">§32</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tok1</span><span class="plain-syntax">, </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tok2</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">f_left</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP35" class="function-link"><span class="function-syntax">Equations::f_function</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">tok1</span><span class="plain-syntax">), </span><span class="identifier-syntax">g_right</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP36" class="function-link"><span class="function-syntax">Equations::g_function</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">tok2</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">f_left</span><span class="plain-syntax"> == </span><span class="identifier-syntax">g_right</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::enode_gt</span><button class="popup" onclick="togglePopup('usagePopup25')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup25">Usage of <span class="code-font"><span class="function-syntax">Equations::enode_gt</span></span>:<br/><a href="7-eqt.html#SP32">§32</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tok1</span><span class="plain-syntax">, </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tok2</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">f_left</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP35" class="function-link"><span class="function-syntax">Equations::f_function</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">tok1</span><span class="plain-syntax">), </span><span class="identifier-syntax">g_right</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP36" class="function-link"><span class="function-syntax">Equations::g_function</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">tok2</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">f_left</span><span class="plain-syntax"> > </span><span class="identifier-syntax">g_right</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP35" class="paragraph-anchor"></a><b>§35. </b>And here are those scorings. Note that for the binary operators, \(f\)
|
|
scores are usually slightly higher than \(g\) scores: that's what makes
|
|
them left associative, that is, \(a+b+c\) is read as \((a+b)+c\). The
|
|
exception to this is raising to powers: <span class="extract"><span class="extract-syntax">a^2^3</span></span> evaluates \(a^8\), not
|
|
\(a^6\), because it is read as <span class="extract"><span class="extract-syntax">a^(2^3)</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary">Implicit multiplication has higher precedence than explicit. This is
|
|
actually to give it higher precedence than division (which has to have
|
|
the same precedence as explicit multiplication), and is so that
|
|
<span class="extract"><span class="extract-syntax">ab/cd</span></span> evaluates \((ab)/(cd)\) rather than \(a\cdot (b/c)\cdot d\).
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::f_function</span><button class="popup" onclick="togglePopup('usagePopup26')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup26">Usage of <span class="code-font"><span class="function-syntax">Equations::f_function</span></span>:<br/><a href="7-eqt.html#SP34">§34</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tok</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">SYMBOL_EQN:</span><span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CONSTANT_EQN:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">16</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">OPERATION_EQN:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EQUALS_OPERATION:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PLUS_OPERATION:</span><span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">MINUS_OPERATION:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TIMES_OPERATION:</span><span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">DIVIDE_OPERATION:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">6</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">IMPLICIT_TIMES_OPERATION:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">8</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">POWER_OPERATION:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">9</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">IMPLICIT_APPLICATION_OPERATION:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">UNARY_MINUS_OPERATION:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"unknown operator precedence"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">OPEN_BRACKET_EQN:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CLOSE_BRACKET_EQN:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">16</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">END_EQN:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"unknown f-value"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP36" class="paragraph-anchor"></a><b>§36. </b>And symmetrically:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::g_function</span><button class="popup" onclick="togglePopup('usagePopup27')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup27">Usage of <span class="code-font"><span class="function-syntax">Equations::g_function</span></span>:<br/><a href="7-eqt.html#SP34">§34</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tok</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">SYMBOL_EQN:</span><span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CONSTANT_EQN:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">15</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">OPERATION_EQN:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">) </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EQUALS_OPERATION:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PLUS_OPERATION:</span><span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">MINUS_OPERATION:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TIMES_OPERATION:</span><span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">DIVIDE_OPERATION:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">IMPLICIT_TIMES_OPERATION:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">7</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">POWER_OPERATION:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">10</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">IMPLICIT_APPLICATION_OPERATION:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">14</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">UNARY_MINUS_OPERATION:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">12</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"unknown operator precedence"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">OPEN_BRACKET_EQN:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">15</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CLOSE_BRACKET_EQN:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">END_EQN:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"unknown g-value"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP37" class="paragraph-anchor"></a><b>§37. Typechecking equations. </b>The SR parser can generate trees for any syntactically valid equation, but
|
|
it may be something using <span class="extract"><span class="extract-syntax">=</span></span> inappropriately or not at all. We rule that
|
|
out first: we want the top node in the tree to be the unique <span class="extract"><span class="extract-syntax">=</span></span> operator.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::eqn_typecheck</span><button class="popup" onclick="togglePopup('usagePopup28')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup28">Usage of <span class="code-font"><span class="function-syntax">Equations::eqn_typecheck</span></span>:<br/><a href="7-eqt.html#SP11">§11</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><a href="7-eqt.html#SP38" class="function-link"><span class="function-syntax">Equations::enode_count_equals</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationDoesntEquate</span><span class="plain-syntax">), </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="string-syntax">""</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"this equation doesn't seem to contain an equals sign, and "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"without '=' there is no equating anything with anything."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="7-eqt.html#SP38" class="function-link"><span class="function-syntax">Equations::enode_is_equals</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationEquatesBadly</span><span class="plain-syntax">), </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="string-syntax">""</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"the equals sign '=' here seems to be buried inside the "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"formula, not at the surface. For instance, 'F = ma' is "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"fine, but 'F(m=a)' would not make sense - the '=' would "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"be inside brackets."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationEquatesMultiply</span><span class="plain-syntax">), </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="string-syntax">""</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"this equation seems to contain more than one equals "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"sign '='."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="7-eqt.html#SP39" class="function-link"><span class="function-syntax">Equations::enode_typecheck</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP38" class="paragraph-anchor"></a><b>§38. </b>A recursive count of instances down the tree from <span class="extract"><span class="extract-syntax">tok</span></span>:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::enode_count_equals</span><button class="popup" onclick="togglePopup('usagePopup29')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup29">Usage of <span class="code-font"><span class="function-syntax">Equations::enode_count_equals</span></span>:<br/><a href="7-eqt.html#SP37">§37</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tok</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="7-eqt.html#SP38" class="function-link"><span class="function-syntax">Equations::enode_is_equals</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">)) </span><span class="identifier-syntax">c</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax"><tok-></span><span class="element-syntax">enode_arity</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> += </span><a href="7-eqt.html#SP38" class="function-link"><span class="function-syntax">Equations::enode_count_equals</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::enode_is_equals</span><button class="popup" onclick="togglePopup('usagePopup30')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup30">Usage of <span class="code-font"><span class="function-syntax">Equations::enode_is_equals</span></span>:<br/><a href="7-eqt.html#SP37">§37</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tok</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax"> == </span><span class="constant-syntax">OPERATION_EQN</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax"> == </span><span class="identifier-syntax">EQUALS_OPERATION</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP39" class="paragraph-anchor"></a><b>§39. </b>Now we come to the real typechecking. The following is called, depth-first,
|
|
at each node in the equation; it has to assign a kind at every node, in such
|
|
a way that all operations are dimensionally valid. We return <span class="extract"><span class="extract-syntax">FALSE</span></span> if we
|
|
are obliged to issue a problem message.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">float_terminal_nodes</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::enode_typecheck</span><button class="popup" onclick="togglePopup('usagePopup31')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup31">Usage of <span class="code-font"><span class="function-syntax">Equations::enode_typecheck</span></span>:<br/><a href="7-eqt.html#SP37">§37</a>, <a href="7-eqt.html#SP40">§40</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tok</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_INDENT</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax"><tok-></span><span class="element-syntax">enode_arity</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="7-eqt.html#SP39" class="function-link"><span class="function-syntax">Equations::enode_typecheck</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">result</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">SYMBOL_EQN:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_before</span><span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::new_gk</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">leaf_symbol</span><span class="plain-syntax">-></span><span class="element-syntax">var_kind</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CONSTANT_EQN:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_before</span><span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::new_gk</span><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::get_kind_of_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">leaf_constant</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_promotion</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">CompileValues::target_VM_supports_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_real_number</span><span class="plain-syntax">)))</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_before</span><span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::to_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_before</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">OPERATION_EQN:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax"> == </span><span class="identifier-syntax">EQUALS_OPERATION</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP39_1" class="named-paragraph-link"><span class="named-paragraph">Typecheck the set-equals node at the top level</span><span class="named-paragraph-number">39.1</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax"> == </span><span class="identifier-syntax">POWER_OPERATION</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP39_2" class="named-paragraph-link"><span class="named-paragraph">Typecheck a raise-to-integer-power node</span><span class="named-paragraph-number">39.2</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax"> == </span><span class="constant-syntax">IMPLICIT_APPLICATION_OPERATION</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP39_3" class="named-paragraph-link"><span class="named-paragraph">Typecheck a function application node</span><span class="named-paragraph-number">39.3</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP39_4" class="named-paragraph-link"><span class="named-paragraph">Typecheck a general operation node</span><span class="named-paragraph-number">39.4</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"forbidden enode found in parsed equation"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_after</span><span class="plain-syntax"> = </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_before</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">float_terminal_nodes</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_arity</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP40" class="function-link"><span class="function-syntax">Equations::promote_subequation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">tok</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP39_1" class="paragraph-anchor"></a><b>§39.1. </b>If we know that we need a real rather than integer answer, that has to
|
|
propagate downwards from the equality into the trees on either side, casting
|
|
integers to reals.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Typecheck the set-equals node at the top level</span><span class="named-paragraph-number">39.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::FloatingPoint::underlying</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0]-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::FloatingPoint::underlying</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::FloatingPoint::integer_equivalent</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::FloatingPoint::integer_equivalent</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Tried to equate %u and %u\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationIncomparable</span><span class="plain-syntax">), </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="string-syntax">""</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"this equation tries to set two values equal which have "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"different kinds from each other."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">lf</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::FloatingPoint::is_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0]-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rf</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::FloatingPoint::is_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">lf</span><span class="plain-syntax"> == </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">rf</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP40" class="function-link"><span class="function-syntax">Equations::promote_subequation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1], </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">lf</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">rf</span><span class="plain-syntax"> == </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP40" class="function-link"><span class="function-syntax">Equations::demote_subequation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_before</span><span class="plain-syntax"> = </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0]-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP39">§39</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP39_2" class="paragraph-anchor"></a><b>§39.2. </b>The restriction on powers is needed to make it possible to know the
|
|
dimensions of the result. If \(h\) is a length, \(h^2\) is an area but \(h^3\) is
|
|
a volume; so if all we have is \(h^n\), and we don't know the value of \(n\),
|
|
we're unable to see what equations \(h^n\) can appear in.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Typecheck a raise-to-integer-power node</span><span class="named-paragraph-number">39.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">base</span><span class="plain-syntax"> = </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">power</span><span class="plain-syntax"> = </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1];</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Dimensions::dimensionless</span><span class="plain-syntax">(</span><span class="identifier-syntax">Kinds::FloatingPoint::underlying</span><span class="plain-syntax">(</span><span class="identifier-syntax">base</span><span class="plain-syntax">-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">))) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_before</span><span class="plain-syntax"> = </span><span class="identifier-syntax">base</span><span class="plain-syntax">-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_after</span><span class="plain-syntax"> = </span><span class="identifier-syntax">base</span><span class="plain-syntax">-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP39_2_1" class="named-paragraph-link"><span class="named-paragraph">Take the dimensional power of the kind of the base</span><span class="named-paragraph-number">39.2.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">lf</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::FloatingPoint::is_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0]-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rf</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::FloatingPoint::is_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">lf</span><span class="plain-syntax"> == </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">rf</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP40" class="function-link"><span class="function-syntax">Equations::promote_subequation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1], </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">lf</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">rf</span><span class="plain-syntax"> == </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP40" class="function-link"><span class="function-syntax">Equations::promote_subequation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0], </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Kinds::FloatingPoint::is_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) && ((</span><span class="identifier-syntax">lf</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">rf</span><span class="plain-syntax">))) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_before</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::FloatingPoint::to_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_before</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP39">§39</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP39_3" class="paragraph-anchor"></a><b>§39.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Typecheck a function application node</span><span class="named-paragraph-number">39.3</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">fn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">fn</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax"> == </span><span class="constant-syntax">SYMBOL_EQN</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">fn</span><span class="plain-syntax">-></span><span class="element-syntax">leaf_symbol</span><span class="plain-syntax">-></span><span class="element-syntax">function_notated</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">id_body</span><span class="plain-syntax"> *</span><span class="identifier-syntax">idb</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fn</span><span class="plain-syntax">-></span><span class="element-syntax">leaf_symbol</span><span class="plain-syntax">-></span><span class="element-syntax">function_notated</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">RK</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-ptd.html#SP24" class="function-link"><span class="function-syntax">IDTypeData::arithmetic_operation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">idb</span><span class="plain-syntax">) == </span><span class="identifier-syntax">REALROOT_OPERATION</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OPK</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::FloatingPoint::underlying</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">RK</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::Dimensions::arithmetic_on_kinds</span><span class="plain-syntax">(</span><span class="identifier-syntax">OPK</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">REALROOT_OPERATION</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">RK</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationCantRoot</span><span class="plain-syntax">-</span><span class="identifier-syntax">G</span><span class="plain-syntax">), </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="string-syntax">""</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"the square root function 'root' can only be used on quantities "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"whose dimensions are themselves a square - for example, the "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"root of the area 100 sq m makes sense (it's 10m), but the root "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"of 4m doesn't make sense, because what's a square root of a meter?"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">RK</span><span class="plain-syntax"> = </span><a href="5-ptd.html#SP10" class="function-link"><span class="function-syntax">IDTypeData::get_return_kind</span></a><span class="plain-syntax">(&(</span><span class="identifier-syntax">idb</span><span class="plain-syntax">-></span><span class="element-syntax">type_data</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_before</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::FloatingPoint::to_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">Kinds::FloatingPoint::new_gk</span><span class="plain-syntax">(</span><span class="identifier-syntax">RK</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rf</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::FloatingPoint::is_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rf</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><a href="7-eqt.html#SP40" class="function-link"><span class="function-syntax">Equations::promote_subequation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1], </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP39">§39</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP39_2_1" class="paragraph-anchor"></a><b>§39.2.1. </b>To work out the kind of \(b^n\), we use repeated multiplication or division
|
|
of dimensions; if \(n=0\) then we have a dimensionless value, and choose
|
|
"number" as the simplest possibility.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Take the dimensional power of the kind of the base</span><span class="named-paragraph-number">39.2.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::integer_equivalent</span><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::underlying</span><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">base</span><span class="plain-syntax">-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">real</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::FloatingPoint::is_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">base</span><span class="plain-syntax">-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">)) </span><span class="identifier-syntax">real</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = -1, </span><span class="identifier-syntax">m</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">power</span><span class="plain-syntax">-></span><span class="element-syntax">rational_m</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="identifier-syntax">power</span><span class="plain-syntax">-></span><span class="element-syntax">rational_n</span><span class="plain-syntax">; </span><span class="identifier-syntax">m</span><span class="plain-syntax"> = </span><span class="identifier-syntax">power</span><span class="plain-syntax">-></span><span class="element-syntax">rational_m</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">m</span><span class="plain-syntax"> > </span><span class="constant-syntax">1</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">real</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationCantPower2</span><span class="plain-syntax">-</span><span class="identifier-syntax">G</span><span class="plain-syntax">), </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="string-syntax">""</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"except for the special cases of squaring and cubing, the '^' "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"raise-to-power symbol can only be used to power a value using "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"real rather than integer arithmetic."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">Kinds::FloatingPoint::underlying</span><span class="plain-syntax">(</span><span class="identifier-syntax">power</span><span class="plain-syntax">-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) ||</span>
|
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">power</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax"> != </span><span class="constant-syntax">CONSTANT_EQN</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationDimensionPower</span><span class="plain-syntax">), </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="string-syntax">""</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"the '^' raise-to-power symbol can only be used to raise a value "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"with dimensions to a specific number. So 'mv^2' is fine, but not "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"'mv^n' or 'mv^(1+n)'. (This is because I would need to work out what "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"kind of value 'v^n' would be, and the answer would depend on 'n', "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"but I wouldn't know what 'n' is.)"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Rvalues::to_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">power</span><span class="plain-syntax">-></span><span class="element-syntax">leaf_constant</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">n</span><span class="plain-syntax"> >= </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::Dimensions::to_rational_power</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">n</span><span class="plain-syntax">, </span><span class="identifier-syntax">m</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::equation_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">BelievedImpossible</span><span class="plain-syntax">), </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="string-syntax">""</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"this would involve taking a fractional power of an amount whose "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"dimensions are not of that power form - for example, the square "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"root of the area 100 sq m makes sense (it's 10m), but the square "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"root of 4m doesn't make sense, because what's a square root of "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"a meter?"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">real</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_before</span><span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::to_real</span><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::new_gk</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_before</span><span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::new_gk</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP39_2">§39.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP39_4" class="paragraph-anchor"></a><b>§39.4. </b>The following is easy because it was the content of the whole "Dimensions.w"
|
|
section:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Typecheck a general operation node</span><span class="named-paragraph-number">39.4</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">O1</span><span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::integer_equivalent</span><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::underlying</span><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0]-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">real</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::FloatingPoint::is_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0]-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">real</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Dimensions::arithmetic_op_is_unary</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::Dimensions::arithmetic_on_kinds</span><span class="plain-syntax">(</span><span class="identifier-syntax">O1</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">O2</span><span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::integer_equivalent</span><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::underlying</span><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::FloatingPoint::is_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">real</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::Dimensions::arithmetic_on_kinds</span><span class="plain-syntax">(</span><span class="identifier-syntax">O1</span><span class="plain-syntax">, </span><span class="identifier-syntax">O2</span><span class="plain-syntax">, </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">lf</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::FloatingPoint::is_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0]-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rf</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::FloatingPoint::is_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">lf</span><span class="plain-syntax"> == </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">rf</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP40" class="function-link"><span class="function-syntax">Equations::promote_subequation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1], </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">lf</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">rf</span><span class="plain-syntax"> == </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP40" class="function-link"><span class="function-syntax">Equations::promote_subequation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0], </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_before</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::FloatingPoint::new_gk</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Failed at operation:\n"</span><span class="plain-syntax">); </span><a href="7-eqt.html#SP25" class="function-link"><span class="function-syntax">Equations::log_equation_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Dimensions::arithmetic_op_is_unary</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP39_4_1" class="named-paragraph-link"><span class="named-paragraph">Issue unary equation typechecking problem message</span><span class="named-paragraph-number">39.4.1</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP39_4_2" class="named-paragraph-link"><span class="named-paragraph">Issue binary equation typechecking problem message</span><span class="named-paragraph-number">39.4.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">real</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_before</span><span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::to_real</span><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::new_gk</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_before</span><span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::new_gk</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP39">§39</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP39_4_1" class="paragraph-anchor"></a><b>§39.4.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue unary equation typechecking problem message</span><span class="named-paragraph-number">39.4.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(4,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::underlying</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0]-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">UNARY_MINUS_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(6, </span><span class="string-syntax">"negating"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">ROOT_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(6, </span><span class="string-syntax">"taking the square root of"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">REALROOT_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(6, </span><span class="string-syntax">"taking the (real-valued) square root of"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CUBEROOT_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(6, </span><span class="string-syntax">"taking the cube root of"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">BelievedImpossible</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"You wrote %1, but that equation seems to involve %6 %4, which is not "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"good arithmetic."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP39_4">§39.4</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP39_4_2" class="paragraph-anchor"></a><b>§39.4.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue binary equation typechecking problem message</span><span class="named-paragraph-number">39.4.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">Kinds::FloatingPoint::underlying</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0]-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(5, </span><span class="identifier-syntax">Kinds::FloatingPoint::underlying</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PLUS_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(6, </span><span class="string-syntax">"adding"</span><span class="plain-syntax">); </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(7, </span><span class="string-syntax">"to"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">MINUS_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(6, </span><span class="string-syntax">"subtracting"</span><span class="plain-syntax">); </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(7, </span><span class="string-syntax">"from"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TIMES_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(6, </span><span class="string-syntax">"multiplying"</span><span class="plain-syntax">); </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(7, </span><span class="string-syntax">"by"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">DIVIDE_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">REMAINDER_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(6, </span><span class="string-syntax">"dividing"</span><span class="plain-syntax">); </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(7, </span><span class="string-syntax">"by"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">POWER_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(6, </span><span class="string-syntax">"raising"</span><span class="plain-syntax">); </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(7, </span><span class="string-syntax">"to the power of"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(6, </span><span class="string-syntax">"combining"</span><span class="plain-syntax">); </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(7, </span><span class="string-syntax">"with"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationBadArithmetic</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"You wrote %1, but that equation seems to involve "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"%6 %4 %7 %5, which is not good arithmetic."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP39_4">§39.4</a>.</li></ul>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::promote_subequation</span><button class="popup" onclick="togglePopup('usagePopup32')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup32">Usage of <span class="code-font"><span class="function-syntax">Equations::promote_subequation</span></span>:<br/><a href="7-eqt.html#SP39">§39</a>, <a href="7-eqt.html#SP39_1">§39.1</a>, <a href="7-eqt.html#SP39_2">§39.2</a>, <a href="7-eqt.html#SP39_3">§39.3</a>, <a href="7-eqt.html#SP39_4">§39.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tok</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">deeply</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">deeply</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">float_terminal_nodes</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP39" class="function-link"><span class="function-syntax">Equations::enode_typecheck</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">tok</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">float_terminal_nodes</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_after</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::FloatingPoint::to_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::demote_subequation</span><button class="popup" onclick="togglePopup('usagePopup33')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup33">Usage of <span class="code-font"><span class="function-syntax">Equations::demote_subequation</span></span>:<br/><a href="7-eqt.html#SP39_1">§39.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tok</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_after</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::FloatingPoint::to_integer</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">gK_after</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP41" class="paragraph-anchor"></a><b>§41. Rearrangement. </b>We carry out only the simplest of operations, but it's surprising how often that's
|
|
good enough: if it isn't, we simply return <span class="extract"><span class="extract-syntax">FALSE</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary">Everything we do will be reversible, which is important since we are
|
|
changing the <span class="extract"><span class="extract-syntax">parsed_equation</span></span> tree, and we don't want to be changing our
|
|
view of what the equation means in the process. One thing that never changes
|
|
is that the top node of the equation is always the unique "equal to" node
|
|
in the tree.
|
|
</p>
|
|
|
|
<p class="commentary">Suppose we are solving for <span class="extract"><span class="extract-syntax">v</span></span>, which occurs in just one place in the equation.
|
|
Either it's at the top level under the <span class="extract"><span class="extract-syntax">=</span></span>, in which case we now have an
|
|
explicit formula for <span class="extract"><span class="extract-syntax">v</span></span>, or it's stuck underneath some operation node. We
|
|
rearrange the tree to move this operation over to the other side, which
|
|
allows <span class="extract"><span class="extract-syntax">v</span></span> to make progress — see below for a proof that this terminates.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::eqn_rearrange</span><button class="popup" onclick="togglePopup('usagePopup34')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup34">Usage of <span class="code-font"><span class="function-syntax">Equations::eqn_rearrange</span></span>:<br/><a href="7-eqt.html#SP43">§43</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="reserved-syntax">equation_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to_solve</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP41_1" class="named-paragraph-link"><span class="named-paragraph">Swap the two sides if necessary so that v occurs only once and on the left</span><span class="named-paragraph-number">41.1</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">old_RHS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1];</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax"> != </span><span class="constant-syntax">OPERATION_EQN</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_arity</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP41_3" class="named-paragraph-link"><span class="named-paragraph">Rearrange to move v upwards through this binary operator</span><span class="named-paragraph-number">41.3</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP41_4" class="named-paragraph-link"><span class="named-paragraph">Rearrange to move v upwards through this unary operator</span><span class="named-paragraph-number">41.4</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP41_1" class="paragraph-anchor"></a><b>§41.1. </b>We have no ability to gather terms, so the variable <span class="extract"><span class="extract-syntax">v</span></span> we are solving for can only
|
|
occur once in the formula. In Inform's idea of equations, <span class="extract"><span class="extract-syntax">A = B</span></span> and <span class="extract"><span class="extract-syntax">B = A</span></span>
|
|
have the same meaning, so we'll place <span class="extract"><span class="extract-syntax">v</span></span> on the left.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Swap the two sides if necessary so that v occurs only once and on the left</span><span class="named-paragraph-number">41.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">lc</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP42" class="function-link"><span class="function-syntax">Equations::enode_count_var</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0], </span><span class="identifier-syntax">to_solve</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rc</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP42" class="function-link"><span class="function-syntax">Equations::enode_count_var</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1], </span><span class="identifier-syntax">to_solve</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lc</span><span class="plain-syntax"> + </span><span class="identifier-syntax">rc</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lc</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">swap</span><span class="plain-syntax"> = </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1];</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1] = </span><span class="identifier-syntax">swap</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP41">§41</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP41_2" class="paragraph-anchor"></a><b>§41.2. </b>The main loop above terminates because on each iteration, either
|
|
</p>
|
|
|
|
<ul class="items"><li>(i) the tree depth of <span class="extract"><span class="extract-syntax">v</span></span> below <span class="extract"><span class="extract-syntax">=</span></span> decreases by 1, or
|
|
</li><li>(ii) the tree depth of <span class="extract"><span class="extract-syntax">v</span></span> remains the same but the number of <span class="extract"><span class="extract-syntax">MINUS_OPERATION</span></span> or
|
|
<span class="extract"><span class="extract-syntax">DIVIDE_OPERATION</span></span> nodes in the tree decreases by 1.
|
|
</li></ul>
|
|
<p class="commentary">Since at any given time there are a finite number of <span class="extract"><span class="extract-syntax">MINUS_OPERATION</span></span> or
|
|
<span class="extract"><span class="extract-syntax">DIVIDE_OPERATION</span></span> nodes, case (ii) cannot repeat indefinitely, and we must
|
|
therefore eventually fall into case (i); and then subsequently do so again,
|
|
and so on; and so the tree depth of <span class="extract"><span class="extract-syntax">v</span></span> will ultimately fall to 1, at which
|
|
point it is at the top level as required and we break out of the loop.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP41_3" class="paragraph-anchor"></a><b>§41.3. </b>So the rearrangement moves have to make sure the "(i) or (ii)" property
|
|
always holds. The simplest case to understand is <span class="extract"><span class="extract-syntax">+</span></span>. Suppose we have:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> +</span>
|
|
<span class="plain-syntax"> V</span>
|
|
<span class="plain-syntax"> E</span>
|
|
<span class="plain-syntax"> R</span>
|
|
</pre>
|
|
<p class="commentary">representing \((V+E) = R\), where \(V\) is the sub-equation containing
|
|
\(v\). (\(E\) is an arbitrary sub-equation, and \(R\) is the right hand
|
|
side.) One of the two operands of <span class="extract"><span class="extract-syntax">+</span></span> will be "promoted", moving
|
|
upwards in the tree, and since we can choose to promote either \(V\) or
|
|
\(E\), we'll choose \(V\), thus obtaining:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> V</span>
|
|
<span class="plain-syntax"> -</span>
|
|
<span class="plain-syntax"> R</span>
|
|
<span class="plain-syntax"> E</span>
|
|
</pre>
|
|
<p class="commentary">that is, \(V = (R - E)\). Since \(V\) has moved upwards, so has the unique instance
|
|
of \(v\), and therefore the tree depth of \(v\) has decreased by 1 — property (i).
|
|
Multiplication is similar, but turns into division on the right hand side.
|
|
</p>
|
|
|
|
<p class="commentary">But now consider <span class="extract"><span class="extract-syntax">-</span></span>. When we rearrange:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> -</span>
|
|
<span class="plain-syntax"> E</span>
|
|
<span class="plain-syntax"> V</span>
|
|
<span class="plain-syntax"> R</span>
|
|
</pre>
|
|
<p class="commentary">representing \((E-V) = R\) we no longer have a choice of which operand of <span class="extract"><span class="extract-syntax">-</span></span>
|
|
to promote: we have to promote the right operand, and that produces \(E = (R+V)\).
|
|
The tree depth of \(v\) is not improved, and it's now over on the right hand
|
|
side. The next iteration of the main loop will swap sides again so that we
|
|
have \((R+V) = E\). But a tricky node (subtraction or division) has been
|
|
exchanged out of the tree for an easy one (addition or multiplication), so
|
|
we fail property (i) but achieve property (ii).
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Rearrange to move v upwards through this binary operator</span><span class="named-paragraph-number">41.3</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> rearrange to move this operator</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">op</span><span class="plain-syntax"> = </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">op</span><span class="plain-syntax"> == </span><span class="identifier-syntax">POWER_OPERATION</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP41_3_1" class="named-paragraph-link"><span class="named-paragraph">Rearrange to remove a power</span><span class="named-paragraph-number">41.3.1</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">op</span><span class="plain-syntax"> == </span><span class="constant-syntax">IMPLICIT_APPLICATION_OPERATION</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="7-eqt.html#SP41_3_2" class="named-paragraph-link"><span class="named-paragraph">Rearrange using the inverse of function</span><span class="named-paragraph-number">41.3.2</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">promote</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">new_op</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PLUS_OPERATION</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="7-eqt.html#SP42" class="function-link"><span class="function-syntax">Equations::enode_count_var</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1], </span><span class="identifier-syntax">to_solve</span><span class="plain-syntax">) > </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">promote</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">op</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PLUS_OPERATION:</span><span class="plain-syntax"> </span><span class="identifier-syntax">new_op</span><span class="plain-syntax"> = </span><span class="identifier-syntax">MINUS_OPERATION</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">MINUS_OPERATION:</span><span class="plain-syntax"> </span><span class="identifier-syntax">new_op</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PLUS_OPERATION</span><span class="plain-syntax">; </span><span class="identifier-syntax">promote</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TIMES_OPERATION:</span><span class="plain-syntax"> </span><span class="identifier-syntax">new_op</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DIVIDE_OPERATION</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">DIVIDE_OPERATION:</span><span class="plain-syntax"> </span><span class="identifier-syntax">new_op</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TIMES_OPERATION</span><span class="plain-syntax">; </span><span class="identifier-syntax">promote</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">op</span><span class="plain-syntax">); </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"strange operator in rearrangement"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1 - </span><span class="identifier-syntax">promote</span><span class="plain-syntax">];</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> the new LHS is the promoted operand:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[</span><span class="identifier-syntax">promote</span><span class="plain-syntax">];</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> the new RHS is the operator which used to be the LHS...</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1] = </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> ...the former RHS being the operand replacing the promoted one...</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">old_RHS</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1] = </span><span class="identifier-syntax">E</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> ...except that the operator reverses in "sense"</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_op</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP41">§41</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP41_3_1" class="paragraph-anchor"></a><b>§41.3.1. </b>Solving \(x^v = y\) for \(v\) requires logs, which are not in our scheme; and
|
|
solving \(v^n = y\) for non-constant \(n\) is no better. So in either case we
|
|
surrender by returning <span class="extract"><span class="extract-syntax">FALSE</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary">In fact, the only cases we can solve at present are \(V^2 = y\) and \(V^3 = y\).
|
|
It would be easy to add solutions for \(V^4 = y\), \(V^6 = y\) and in general for
|
|
\(V^k = y\) where the only prime factors of \(k\) are 2 and 3, but this is not
|
|
something people are likely to need very much. The taking of 4th or higher roots
|
|
hardly ever occurs in physical equations, and anyone wanting this will have
|
|
to write more explicit source text.
|
|
</p>
|
|
|
|
<p class="commentary">Anyway, rearrangement for our easy cases is indeed easy:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> ^</span>
|
|
<span class="plain-syntax"> V</span>
|
|
<span class="plain-syntax"> 2</span>
|
|
<span class="plain-syntax"> R</span>
|
|
</pre>
|
|
<p class="commentary">becomes
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> V</span>
|
|
<span class="plain-syntax"> square-root</span>
|
|
<span class="plain-syntax"> R</span>
|
|
</pre>
|
|
<p class="commentary">and \(V\) is always promoted, so we achieve property (i); and similarly for
|
|
cube roots.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Rearrange to remove a power</span><span class="named-paragraph-number">41.3.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Rvalues::to_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">leaf_constant</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1] = </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ROOT_OPERATION</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_arity</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">old_RHS</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax"> == </span><span class="constant-syntax">3</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1] = </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CUBEROOT_OPERATION</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_arity</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">old_RHS</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1] = </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">POWER_OPERATION</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_arity</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">old_RHS</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">the_power</span><span class="plain-syntax"> = </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1];</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1] = </span><a href="7-eqt.html#SP24" class="function-link"><span class="function-syntax">Equations::enode_new_op</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">DIVIDE_OPERATION</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">enode_arity</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0] = </span><a href="7-eqt.html#SP24" class="function-link"><span class="function-syntax">Equations::enode_new_constant</span></a><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Rvalues::from_int</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0]-></span><span class="element-syntax">gK_before</span><span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::new_gk</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_number</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0]-></span><span class="element-syntax">enode_promotion</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1] = </span><span class="identifier-syntax">the_power</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">gK_before</span><span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::new_gk</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_number</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">enode_promotion</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">gK_before</span><span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::new_gk</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_real_number</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">gK_after</span><span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::FloatingPoint::new_gk</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_real_number</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">rational_n</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">rational_m</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">CompileValues::note_that_kind_is_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_real_number</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP41_3">§41.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP41_3_2" class="paragraph-anchor"></a><b>§41.3.2. </b>Here we have something like <span class="extract"><span class="extract-syntax">log x = y</span></span> and want to rewrite as <span class="extract"><span class="extract-syntax">x = exp y</span></span>,
|
|
which is only possible if we have an inverse available for our function —
|
|
in this case, <span class="extract"><span class="extract-syntax">exp</span></span> being the inverse of <span class="extract"><span class="extract-syntax">log</span></span>. Thus:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> apply</span>
|
|
<span class="plain-syntax"> function</span>
|
|
<span class="plain-syntax"> V</span>
|
|
<span class="plain-syntax"> R</span>
|
|
</pre>
|
|
<p class="commentary">must become
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> V</span>
|
|
<span class="plain-syntax"> apply</span>
|
|
<span class="plain-syntax"> inverse-of-function</span>
|
|
<span class="plain-syntax"> R</span>
|
|
</pre>
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Rearrange using the inverse of function</span><span class="named-paragraph-number">41.3.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">fnode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">fnode</span><span class="plain-syntax">-></span><span class="element-syntax">leaf_symbol</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) ||</span>
|
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">fnode</span><span class="plain-syntax">-></span><span class="element-syntax">leaf_symbol</span><span class="plain-syntax">-></span><span class="element-syntax">function_notated</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP25" class="function-link"><span class="function-syntax">Equations::log_equation_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">fnode</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"not a function being applied"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">id_body</span><span class="plain-syntax"> *</span><span class="identifier-syntax">f</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fnode</span><span class="plain-syntax">-></span><span class="element-syntax">leaf_symbol</span><span class="plain-syntax">-></span><span class="element-syntax">function_notated</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">id_body</span><span class="plain-syntax"> *</span><span class="identifier-syntax">finv</span><span class="plain-syntax"> = </span><a href="5-tpf.html#SP11" class="function-link"><span class="function-syntax">ToPhraseFamily::inverse</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">f</span><span class="plain-syntax">-></span><span class="element-syntax">head_of_defn</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">finv</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="comment-syntax"> no known inverse for this function</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ev</span><span class="plain-syntax">, *</span><span class="identifier-syntax">ev_inverse</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">standard_equation_symbols</span><span class="plain-syntax">; </span><span class="identifier-syntax">ev</span><span class="plain-syntax">; </span><span class="identifier-syntax">ev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">function_notated</span><span class="plain-syntax"> == </span><span class="identifier-syntax">finv</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ev_inverse</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ev</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ev_inverse</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="comment-syntax"> inverse can't be used in equations</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">fnode</span><span class="plain-syntax">-></span><span class="identifier-syntax">leaf_symbol</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ev_inverse</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1];</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1] = </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1] = </span><span class="identifier-syntax">old_RHS</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP41_3">§41.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP41_4" class="paragraph-anchor"></a><b>§41.4. </b>The unary operations are easy in a similar way — they only have one operand,
|
|
so we always promote \(V\) and achieve property (i). A square root is rearranged
|
|
as a square, and a cube root as a cube. (It's important that everything we do
|
|
is reversible — we generate exactly those powers which we are able to undo
|
|
again if necessary.) Unary minus is easier still — we need only move it to
|
|
the other side; thus \(-V = R\) becomes \(V=-R\), and <span class="extract"><span class="extract-syntax">v</span></span> again rises.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Rearrange to move v upwards through this unary operator</span><span class="named-paragraph-number">41.4</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">op</span><span class="plain-syntax"> = </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">op</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">UNARY_MINUS_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1] = </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">old_RHS</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">ROOT_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">REALROOT_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1] = </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TIMES_OPERATION</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_arity</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">old_RHS</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1] = </span><span class="identifier-syntax">old_RHS</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CUBEROOT_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1] = </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_operation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TIMES_OPERATION</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_arity</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">old_RHS</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1] = </span><a href="7-eqt.html#SP24" class="function-link"><span class="function-syntax">Equations::enode_new_op</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">TIMES_OPERATION</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">old_RHS</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">old_LHS</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1]-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[1] = </span><span class="identifier-syntax">old_RHS</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"unanticipated operator in rearrangement"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="7-eqt.html#SP41">§41</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP42" class="paragraph-anchor"></a><b>§42. </b>And that's the whole rearranger, except for the utility routine which
|
|
counts instances of the magic variable <span class="extract"><span class="extract-syntax">v</span></span> at or below a given point in the
|
|
equation tree.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::enode_count_var</span><button class="popup" onclick="togglePopup('usagePopup35')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup35">Usage of <span class="code-font"><span class="function-syntax">Equations::enode_count_var</span></span>:<br/><a href="7-eqt.html#SP41_1">§41.1</a>, <a href="7-eqt.html#SP41_3">§41.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tok</span><span class="plain-syntax">, </span><span class="reserved-syntax">equation_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to_solve</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">eqn_type</span><span class="plain-syntax"> == </span><span class="constant-syntax">SYMBOL_EQN</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">leaf_symbol</span><span class="plain-syntax"> == </span><span class="identifier-syntax">to_solve</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax"><tok-></span><span class="element-syntax">enode_arity</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> += </span><a href="7-eqt.html#SP42" class="function-link"><span class="function-syntax">Equations::enode_count_var</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="element-syntax">enode_operands</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">], </span><span class="identifier-syntax">to_solve</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP43" class="paragraph-anchor"></a><b>§43. Internal test case. </b>This is a little like those "advise all parties" law exam questions: we
|
|
parse the equation, then rearrange to solve it for each variable in turn.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::perform_equation_internal_test</span><button class="popup" onclick="togglePopup('usagePopup36')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup36">Usage of <span class="code-font"><span class="function-syntax">Equations::perform_equation_internal_test</span></span>:<br/>Assertions Module - <a href="1-am.html#SP2">§2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_test_case</span><span class="plain-syntax"> *</span><span class="identifier-syntax">itc</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><span class="identifier-syntax">itc</span><span class="plain-syntax">-></span><span class="identifier-syntax">text_supplying_the_case</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">WH</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax"><equation-where></span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax"><equation-where></span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WH</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax"><equation-where></span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax"> = </span><a href="7-eqt.html#SP8_1" class="function-link"><span class="function-syntax">Equations::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP9" class="function-link"><span class="function-syntax">Equations::set_wherewithal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">WH</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP11" class="function-link"><span class="function-syntax">Equations::examine</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP44" class="function-link"><span class="function-syntax">Equations::log_equation_parsed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">equation_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ev</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">symbol_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">ev</span><span class="plain-syntax">; </span><span class="identifier-syntax">ev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="7-eqt.html#SP41" class="function-link"><span class="function-syntax">Equations::eqn_rearrange</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">ev</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Too hard to rearrange to solve for %W\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">name</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Rearranged to solve for %W:\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="element-syntax">name</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="7-eqt.html#SP44" class="function-link"><span class="function-syntax">Equations::log_equation_parsed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP44" class="paragraph-anchor"></a><b>§44. Logging. </b>And finally:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::log</span><span class="plain-syntax">(</span><span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"{%W}"</span><span class="plain-syntax">, </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">equation_text</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Equations::log_equation_parsed</span><button class="popup" onclick="togglePopup('usagePopup37')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup37">Usage of <span class="code-font"><span class="function-syntax">Equations::log_equation_parsed</span></span>:<br/><a href="7-eqt.html#SP43">§43</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">eqn</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"<null>\n"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><a href="7-eqt.html#SP25" class="function-link"><span class="function-syntax">Equations::log_equation_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="element-syntax">parsed_equation</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<nav role="progress"><div class="progresscontainer">
|
|
<ul class="progressbar"><li class="progressprev"><a href="7-tbl.html">❮</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-am.html">1</a></li><li class="progresschapter"><a href="2-bv.html">2</a></li><li class="progresschapter"><a href="3-dlr.html">3</a></li><li class="progresschapter"><a href="4-nr.html">4</a></li><li class="progresschapter"><a href="5-id.html">5</a></li><li class="progresschapter"><a href="6-rls.html">6</a></li><li class="progresscurrentchapter">7</li><li class="progresssection"><a href="7-tc.html">tc</a></li><li class="progresssection"><a href="7-tbl.html">tbl</a></li><li class="progresscurrent">eqt</li><li class="progresschapter"><a href="8-kpr.html">8</a></li><li class="progressnext"><a href="8-kpr.html">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|