mirror of
https://github.com/ganelson/inform.git
synced 2024-07-16 22:14:23 +03:00
383 lines
61 KiB
HTML
383 lines
61 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>Compile Solutions to 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>
|
|
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">
|
|
|
|
</head>
|
|
<body class="commentary-font">
|
|
<nav role="navigation">
|
|
<h1><a href="../index.html">
|
|
<img src="../docs-assets/Inform.png" height=72">
|
|
</a></h1>
|
|
<ul><li><a href="../index.html">home</a></li>
|
|
</ul><h2>Compiler</h2><ul>
|
|
<li><a href="../structure.html">structure</a></li>
|
|
<li><a href="../inbuildn.html">inbuild</a></li>
|
|
<li><a href="../inform7n.html">inform7</a></li>
|
|
<li><a href="../intern.html">inter</a></li>
|
|
<li><a href="../services.html">services</a></li>
|
|
<li><a href="../secrets.html">secrets</a></li>
|
|
</ul><h2>Other Tools</h2><ul>
|
|
<li><a href="../inblorbn.html">inblorb</a></li>
|
|
<li><a href="../indocn.html">indoc</a></li>
|
|
<li><a href="../inform6.html">inform6</a></li>
|
|
<li><a href="../inpolicyn.html">inpolicy</a></li>
|
|
<li><a href="../inrtpsn.html">inrtps</a></li>
|
|
</ul><h2>Resources</h2><ul>
|
|
<li><a href="../extensions.html">extensions</a></li>
|
|
<li><a href="../kits.html">kits</a></li>
|
|
</ul><h2>Repository</h2><ul>
|
|
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=18> github</a></li>
|
|
</ul><h2>Related Projects</h2><ul>
|
|
<li><a href="../../../inweb/docs/index.html">inweb</a></li>
|
|
<li><a href="../../../intest/docs/index.html">intest</a></li>
|
|
|
|
</ul>
|
|
</nav>
|
|
<main role="main">
|
|
<!--Weave of 'Compile Solutions to Equations' generated by Inweb-->
|
|
<div class="breadcrumbs">
|
|
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inform7n.html">Inform7</a></li><li><a href="index.html">imperative</a></li><li><a href="index.html#5">Chapter 5: Invocations</a></li><li><b>Compile Solutions to Equations</b></li></ul></div>
|
|
<p class="purpose">To compile code to solve an equation involving numerical quantities.</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§1. </b>This section implements the <span class="extract"><span class="extract-syntax">{-primitive-definition:solve-equation}</span></span>
|
|
bracing for an inline invocation.
|
|
</p>
|
|
|
|
<p class="commentary">Nothing here will entirely make sense without first having read
|
|
<a href="../assertions-module/7-eqt.html" class="internal">Equations (in assertions)</a>, but briefly: equations written in the source
|
|
text have been turned into <span class="extract"><span class="extract-syntax">equation</span></span> structures, and we are asked to solve
|
|
the one held in <span class="extract"><span class="extract-syntax">eqn</span></span>. It involves symbols (consider "F", "m" and "a" in the
|
|
equation "F = ma"), each of which is an <span class="extract"><span class="extract-syntax">equation_symbol</span></span>. And the structure
|
|
of the equation has been turned into a tree where each node is an <span class="extract"><span class="extract-syntax">equation_node</span></span>.
|
|
The leaves in this tree are symbols or values; the other nodes represent
|
|
operations to perform.
|
|
</p>
|
|
|
|
<p class="commentary">Before getting under way, a detail. When a named equation is used, a
|
|
"where..." clause is sometimes given to make temporary assignments; what
|
|
happens is that the S-parser temporarily sets the usage words of the equation
|
|
to the relevant 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">EquationSolver::set_usage_notes</span><span class="plain-syntax">(</span><span class="identifier-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="identifier-syntax">usage_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="SP2" class="paragraph-anchor"></a><b>§2. </b>...so that, when we come to solve the equation (i.e., later on in the
|
|
invocation compiler), we know where to find these temporary assignments.
|
|
They are wiped out once this compilation is over.
|
|
</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">EquationSolver::compile_solution</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">EquationSolver::compile_solution</span></span>:<br/>Compile Invocations Inline - <a href="5-cii.html#SP6_7_3">§6.7.3</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="identifier-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::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="identifier-syntax">usage_text</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Equations::eqn_declare_variables_inner</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="identifier-syntax">usage_text</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="5-cste.html#SP3" class="function-link"><span class="function-syntax">EquationSolver::compile_solution_inner</span></a><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="plain-syntax"> </span><span class="identifier-syntax">Equations::eqn_remove_temp_variables</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">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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>§3. </b>With that dance out of the way, we can concentrate on the actual task.
|
|
We have to compile code which assigns the correct value to the symbol
|
|
specified by <span class="extract"><span class="extract-syntax">W</span></span>, according to the equation <span class="extract"><span class="extract-syntax">eqn</span></span>.
|
|
</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">EquationSolver::compile_solution_inner</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">EquationSolver::compile_solution_inner</span></span>:<br/><a href="5-cste.html#SP2">§2</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="identifier-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">equation_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to_solve</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="5-cste.html#SP3_1" class="named-paragraph-link"><span class="named-paragraph">Identify which symbol in the equation we are solving for</span><span class="named-paragraph-number">3.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-cste.html#SP3_2" class="named-paragraph-link"><span class="named-paragraph">Rearrange the equation so that this symbol is the entire LHS</span><span class="named-paragraph-number">3.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-cste.html#SP3_3" class="named-paragraph-link"><span class="named-paragraph">Identify the symbols in the equation with local variables</span><span class="named-paragraph-number">3.3</span></a></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">C</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="string-syntax">"Solving %n for '$w'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="identifier-syntax">compilation_data</span><span class="plain-syntax">.</span><span class="identifier-syntax">eqn_iname</span><span class="plain-syntax">, </span><span class="identifier-syntax">to_solve</span><span class="plain-syntax">-></span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::comment</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">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="5-cste.html#SP4" class="function-link"><span class="function-syntax">EquationSolver::compile_enode</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="identifier-syntax">parsed_equation</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP3_1" class="paragraph-anchor"></a><b>§3.1. </b>Note the case sensitivity here.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Identify which symbol in the equation we are solving for</span><span class="named-paragraph-number">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">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="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-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="identifier-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="identifier-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="identifier-syntax">name</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">to_solve</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">to_solve</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">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="identifier-syntax">equation_text</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(),</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationBadTarget</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"In %1, you asked to let %2 be given by the equation '%3', but '%2' isn't "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"a symbol in that equation."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">to_solve</span><span class="plain-syntax">-></span><span class="identifier-syntax">var_const</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="identifier-syntax">equation_text</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_spec</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">to_solve</span><span class="plain-syntax">-></span><span class="identifier-syntax">var_const</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="plain-syntax"> </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationConstantTarget</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"In %1, you asked to let %2 be given by the equation '%3', but '%2' isn't "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"something which can vary freely in that equation - it's been set equal to %4."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="5-cste.html#SP3">§3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_2" class="paragraph-anchor"></a><b>§3.2. </b>By far the hardest part of the problem is to rearrange the equation so that
|
|
the variable we want to find is the entire left hand side, but this is done
|
|
for us by code in <a href="../assertions-module/7-eqt.html" class="internal">Equations (in assertions)</a>, so it looks easy here.
|
|
</p>
|
|
|
|
<p class="commentary">The surprising thing is the fresh round of typechecking: why do we do that?
|
|
The answer is not that we doubt whether the equation is still valid — the
|
|
rearranged equation should pass if and only if the original did, if we've
|
|
implemented all of this correctly — but because the alterations made to the
|
|
tree mean that the assignments of kinds at each node are now potentially
|
|
incorrect. Re-typechecking will recalculate these.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Rearrange the equation so that this symbol is the entire LHS</span><span class="named-paragraph-number">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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Equations::eqn_rearrange</span><span class="plain-syntax">(</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-syntax">to_solve</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">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="identifier-syntax">equation_text</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(),</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationInsoluble</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"In %1, you asked to let %2 be given by the equation '%3', but I am unable "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"to rearrange the equation in any simple way so that it sets '%2' equal to "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"something else. Maybe you could write a more explicit equation? (You're "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"certainly better at maths than I am; I can only make easy deductions.)"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Equations::eqn_typecheck</span><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>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="5-cste.html#SP3">§3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_3" class="paragraph-anchor"></a><b>§3.3. </b>Suppose we read a phrase such as
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>let PE be given by PE = mgh, where g = 9.801 m/ss;</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">We can only compile code to do this if we can identify values for the symbols.
|
|
"g" is not a problem because a temporary assignment supplies this. For each
|
|
symbol <span class="extract"><span class="extract-syntax">ev</span></span> which isn't a constant, we must set <span class="extract"><span class="extract-syntax">ev->local_map</span></span> to the
|
|
corresponding local variable.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Identify the symbols in the equation with local variables</span><span class="named-paragraph-number">3.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">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="identifier-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="identifier-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="identifier-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="identifier-syntax">local_map</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP17" class="function-link"><span class="function-syntax">LocalVariables::parse</span></a><span class="plain-syntax">(</span><a href="3-sf.html#SP2" class="function-link"><span class="function-syntax">Frames::current_stack_frame</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="identifier-syntax">name</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">promote_local_to_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">ev</span><span class="plain-syntax">-></span><span class="identifier-syntax">local_map</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="5-cste.html#SP3_3_1" class="named-paragraph-link"><span class="named-paragraph">Can't find an unset symbol among the local variables</span><span class="named-paragraph-number">3.3.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="5-cste.html#SP3_3_2" class="named-paragraph-link"><span class="named-paragraph">Check that the kind of the local variable matches that of the symbol</span><span class="named-paragraph-number">3.3.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="5-cste.html#SP3">§3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_3_1" class="paragraph-anchor"></a><b>§3.3.1. </b>In the above example, finding "PE" should not be a problem: this
|
|
is the <span class="extract"><span class="extract-syntax">to_solve</span></span> symbol, and it must be a current local variable name
|
|
since the "let" will have created it as such if it didn't already
|
|
exist. But things can certainly go wrong with "m" and "h", which
|
|
need to exist as local variables in the current stack frame.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Can't find an unset symbol among the local variables</span><span class="named-paragraph-number">3.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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ev</span><span class="plain-syntax"> == </span><span class="identifier-syntax">to_solve</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"can't find 'let' variable to assign"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="identifier-syntax">equation_text</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="identifier-syntax">name</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_EquationSymbolMissing</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"In %1, you asked to let %2 be given by the equation '%3', but I can't see "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"what to use for '%4'. The usual idea is to set the other variables in the "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"equation using 'let': so adding 'let %4 be ...' before trying to find '%2' "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"should work."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="5-cste.html#SP3_3">§3.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_3_2" class="paragraph-anchor"></a><b>§3.3.2. </b>In the case of the symbol we are setting, the local variable might be one
|
|
which has only just been created and thus has no value yet — not having
|
|
set it, Inform hasn't given it a kind more explicit than "value".
|
|
We can improve that by giving it the kind of the symbol it is to match.
|
|
</p>
|
|
|
|
<p class="commentary">In all other cases, the local variable already exists and has a fixed kind.
|
|
This must exactly match that of the symbol. (Again, if we ever need implicit
|
|
casting between quasinumerical kinds, we'll have to return to this.)
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Check that the kind of the local variable matches that of the symbol</span><span class="named-paragraph-number">3.3.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP24" class="function-link"><span class="function-syntax">LocalVariables::kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="identifier-syntax">local_map</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">K_value</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">ev</span><span class="plain-syntax">-></span><span class="identifier-syntax">var_kind</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="3-lv.html#SP25" class="function-link"><span class="function-syntax">LocalVariables::set_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="identifier-syntax">local_map</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</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">Kinds::eq</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">K_real_number</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">K_real_number</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">promote_local_to_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="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">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="identifier-syntax">equation_text</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">ev</span><span class="plain-syntax">-></span><span class="identifier-syntax">name</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">K</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(6, </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="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="plain-syntax"> </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EquationSymbolWrongKOV</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"In %1, you asked to let %2 be given by the equation '%3', but in that "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"equation '%4' is supposedly %6 - whereas right here, it seems to be %5. "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"Perhaps two different quantities have ended up with the same symbol in "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"the source text?"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="5-cste.html#SP3_3">§3.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>§4. </b>Actual compilation is simple, since the tree is set up for 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">EquationSolver::compile_enode</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">EquationSolver::compile_enode</span></span>:<br/><a href="5-cste.html#SP3">§3</a><br/>Compile Arithmetic - <a href="5-ca.html#SP1_3_1">§1.3.1</a>, <a href="5-ca.html#SP1_3_2">§1.3.2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-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">a</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::FloatingPoint::is_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="identifier-syntax">gK_before</span><span class="plain-syntax">)) </span><span class="identifier-syntax">a</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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::FloatingPoint::is_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="identifier-syntax">gK_after</span><span class="plain-syntax">)) </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">f</span><span class="plain-syntax"> = </span><span class="identifier-syntax">b</span><span class="plain-syntax"> - </span><span class="identifier-syntax">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">f</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">Kinds::FloatingPoint::begin_flotation_emit</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="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="identifier-syntax">gK_before</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">f</span><span class="plain-syntax"> == -1) </span><span class="identifier-syntax">Kinds::FloatingPoint::begin_deflotation_emit</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="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="identifier-syntax">gK_before</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="identifier-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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="identifier-syntax">leaf_symbol</span><span class="plain-syntax">-></span><span class="identifier-syntax">var_const</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="2-cv.html#SP5" class="function-link"><span class="function-syntax">CompileValues::to_code_val</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="identifier-syntax">leaf_symbol</span><span class="plain-syntax">-></span><span class="identifier-syntax">var_const</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="identifier-syntax">leaf_symbol</span><span class="plain-syntax">-></span><span class="identifier-syntax">local_map</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">leaf_symbol</span><span class="plain-syntax">-></span><span class="identifier-syntax">promote_local_to_real</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::call</span><span class="plain-syntax">(</span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">NUMBER_TY_TO_REAL_NUMBER_TY_HL</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tok_s</span><span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> </span><a href="3-lv.html#SP1" class="function-link"><span class="function-syntax">LocalVariables::declare</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="identifier-syntax">leaf_symbol</span><span class="plain-syntax">-></span><span class="identifier-syntax">local_map</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">tok_s</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">leaf_symbol</span><span class="plain-syntax">-></span><span class="identifier-syntax">promote_local_to_real</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</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="identifier-syntax">leaf_symbol</span><span class="plain-syntax">-></span><span class="identifier-syntax">function_notated</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">RS</span><span class="plain-syntax"> = </span><a href="3-pr.html#SP1" class="function-link"><span class="function-syntax">PhraseRequests::simple_request</span></a><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="identifier-syntax">leaf_symbol</span><span class="plain-syntax">-></span><span class="identifier-syntax">function_notated</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">IDTypeData::kind</span><span class="plain-syntax">(&(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="identifier-syntax">leaf_symbol</span><span class="plain-syntax">-></span><span class="identifier-syntax">function_notated</span><span class="plain-syntax">-></span><span class="identifier-syntax">type_data</span><span class="plain-syntax">)));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">RS</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">"uncompilable equation node"</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><a href="2-cv.html#SP5" class="function-link"><span class="function-syntax">CompileValues::to_code_val</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="identifier-syntax">leaf_constant</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="named-paragraph-container code-font"><a href="5-cste.html#SP4_1" class="named-paragraph-link"><span class="named-paragraph">Emit a single operation</span><span class="named-paragraph-number">4.1</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">f</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">Kinds::FloatingPoint::end_flotation_emit</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="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="identifier-syntax">gK_before</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">f</span><span class="plain-syntax"> == -1) </span><span class="identifier-syntax">Kinds::FloatingPoint::end_deflotation_emit</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="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="identifier-syntax">gK_before</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP4_1" class="paragraph-anchor"></a><b>§4.1. </b>And here we handle operation nodes:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Emit a single operation</span><span class="named-paragraph-number">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">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">X</span><span class="plain-syntax"> = </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="identifier-syntax">enode_operands</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">KX</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::FloatingPoint::underlying</span><span class="plain-syntax">(</span><span class="identifier-syntax">X</span><span class="plain-syntax">-></span><span class="identifier-syntax">gK_after</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">equation_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Y</span><span class="plain-syntax"> = </span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="identifier-syntax">enode_operands</span><span class="plain-syntax">[1];</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">KY</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">Y</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">Kinds::FloatingPoint::underlying</span><span class="plain-syntax">(</span><span class="identifier-syntax">Y</span><span class="plain-syntax">-></span><span class="identifier-syntax">gK_after</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">Kinds::FloatingPoint::is_real</span><span class="plain-syntax">(</span><span class="identifier-syntax">X</span><span class="plain-syntax">-></span><span class="identifier-syntax">gK_after</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">KX</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K_real_number</span><span class="plain-syntax">; </span><span class="identifier-syntax">KY</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="plain-syntax"> </span><a href="5-ca.html#SP1" class="function-link"><span class="function-syntax">Kinds::Compile::perform_arithmetic_emit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-></span><span class="identifier-syntax">eqn_operation</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">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">X</span><span class="plain-syntax">, </span><span class="identifier-syntax">KX</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y</span><span class="plain-syntax">, </span><span class="identifier-syntax">KY</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="5-cste.html#SP4">§4</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>§5. </b></p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">EquationSolver::issue_problem_on_root</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">EquationSolver::issue_problem_on_root</span></span>:<br/>Compile Arithmetic - <a href="5-ca.html#SP1_13">§1.13</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">equation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">eqn</span><span class="plain-syntax">, </span><span class="identifier-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="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">eqn</span><span class="plain-syntax">-></span><span class="identifier-syntax">equation_text</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_HardIntegerRoot</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"In %1, you asked me to solve the equation '%2', but that would have "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"involved taking a tricky root of a whole number. Using real numbers "</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"that would be easy, but with whole numbers I'm unable to get there."</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>
|
|
</pre>
|
|
<nav role="progress"><div class="progresscontainer">
|
|
<ul class="progressbar"><li class="progressprev"><a href="5-cii.html">❮</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-im.html">1</a></li><li class="progresschapter"><a href="2-cv.html">2</a></li><li class="progresschapter"><a href="3-sf.html">3</a></li><li class="progresschapter"><a href="4-cs.html">4</a></li><li class="progresscurrentchapter">5</li><li class="progresssection"><a href="5-cbal.html">cbal</a></li><li class="progresssection"><a href="5-ci.html">ci</a></li><li class="progresssection"><a href="5-ciac.html">ciac</a></li><li class="progresssection"><a href="5-cii.html">cii</a></li><li class="progresscurrent">cste</li><li class="progresssection"><a href="5-ca.html">ca</a></li><li class="progressnext"><a href="5-ca.html">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|