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

239 lines
38 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Vanilla Code</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/index.html">inweb</a></li>
<li><a href="../../../intest/index.html">intest</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Vanilla Code' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../intern.html">Inter Modules</a></li><li><a href="index.html">final</a></li><li><a href="index.html#2">Chapter 2: Mechanism</a></li><li><b>Vanilla Code</b></li></ul></div>
<p class="purpose">How the vanilla code generation strategy handles the actual code inside functions.</p>
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. </b>The subtrees of Inter inside function bodies are pretty simple. There are
some structural nodes, breaking up code-blocks and the like: and these we
simply recurse down through, except that in the case of <span class="extract"><span class="extract-syntax">code</span></span> we keep track
of the "void level". This is the level in the hierarchy where evaluation is
in a void context. For example,
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> code</span>
<span class="plain-syntax"> inv !printnumber</span>
<span class="plain-syntax"> inv !plus</span>
<span class="plain-syntax"> val K_number 12</span>
<span class="plain-syntax"> val K_number 2</span>
<span class="plain-syntax"> ^</span>
<span class="plain-syntax"> |</span>
<span class="plain-syntax"> void level</span>
</pre>
<p class="commentary">here the invocation of <span class="extract"><span class="extract-syntax">!printnumber</span></span> is in a void context (i.e., any value
produced is discarded), whereas the invocation of <span class="extract"><span class="extract-syntax">!plus</span></span> is not.
</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">VanillaCode::code</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">VanillaCode::code</span></span>:<br/>Vanilla - <a href="2-vnl.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">old_level</span><span class="plain-syntax"> = </span><span class="identifier-syntax">gen</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">void_level</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">gen</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">void_level</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Inode::get_level</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">) + </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="constant-syntax">VNODE_ALLC</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">gen</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">void_level</span><span class="plain-syntax"> = </span><span class="identifier-syntax">old_level</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">VanillaCode::evaluation</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">VanillaCode::evaluation</span></span>:<br/>Vanilla - <a href="2-vnl.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) { </span><span class="constant-syntax">VNODE_ALLC</span><span class="plain-syntax">; }</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">VanillaCode::reference</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">VanillaCode::reference</span></span>:<br/>Vanilla - <a href="2-vnl.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) { </span><span class="constant-syntax">VNODE_ALLC</span><span class="plain-syntax">; }</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">VanillaCode::cast</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">VanillaCode::cast</span></span>:<br/>Vanilla - <a href="2-vnl.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) { </span><span class="constant-syntax">VNODE_ALLC</span><span class="plain-syntax">; }</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>As with assembly language, Inter can contain positional markers called labels.
These we offer to the generator to deal with as it likes:
</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">VanillaCode::label</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">VanillaCode::label</span></span>:<br/>Vanilla - <a href="2-vnl.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lab_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LabelInstruction::label_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cg2.html#SP13" class="function-link"><span class="function-syntax">Generators::place_label</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterSymbol::identifier</span><span class="plain-syntax">(</span><span class="identifier-syntax">lab_name</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>There are three ways to perform an invocation. One of the three, assembly
language, can only in fact occur in void context, but we won't assume that here.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_OPERANDS_IN_INTER_ASSEMBLY</span><span class="plain-syntax"> </span><span class="constant-syntax">32</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">VanillaCode::inv</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">VanillaCode::inv</span></span>:<br/>Vanilla - <a href="2-vnl.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">void_context</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">Inode::get_level</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">) == </span><span class="identifier-syntax">gen</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">void_level</span><span class="plain-syntax">) </span><span class="identifier-syntax">void_context</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">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">InvInstruction::method</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">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PRIMITIVE_INVMETH:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-vc2.html#SP3_1" class="named-paragraph-link"><span class="named-paragraph">Invoke a primitive</span><span class="named-paragraph-number">3.1</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">FUNCTION_INVMETH:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-vc2.html#SP3_2" class="named-paragraph-link"><span class="named-paragraph">Invoke a function</span><span class="named-paragraph-number">3.2</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">OPCODE_INVMETH:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-vc2.html#SP3_3" class="named-paragraph-link"><span class="named-paragraph">Invoke an assembly-language opcode</span><span class="named-paragraph-number">3.3</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"unknown invocation method"</span><span class="plain-syntax">);</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>&#167;3.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Invoke a primitive</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="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">primitive_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InvInstruction::primitive</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">primitive_s</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no primitive"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cg2.html#SP14" class="function-link"><span class="function-syntax">Generators::invoke_primitive</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">primitive_s</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">void_context</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-vc2.html#SP3">&#167;3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_2" class="paragraph-anchor"></a><b>&#167;3.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Invoke a function</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="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">function_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InvInstruction::function</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">function_s</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no function"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-vf.html#SP9" class="function-link"><span class="function-syntax">VanillaFunctions::invoke_function</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">function_s</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">void_context</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-vc2.html#SP3">&#167;3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_3" class="paragraph-anchor"></a><b>&#167;3.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Invoke an assembly-language opcode</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">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">opcode_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InvInstruction::opcode</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">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">operands</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_OPERANDS_IN_INTER_ASSEMBLY</span><span class="plain-syntax">], *</span><span class="identifier-syntax">label</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">operand_count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">label_sense</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-vc2.html#SP3_3_1" class="named-paragraph-link"><span class="named-paragraph">Scan the operands</span><span class="named-paragraph-number">3.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="2-cg2.html#SP14" class="function-link"><span class="function-syntax">Generators::invoke_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">opcode_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">operand_count</span><span class="plain-syntax">, </span><span class="identifier-syntax">operands</span><span class="plain-syntax">, </span><span class="identifier-syntax">label</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">label_sense</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-vc2.html#SP3">&#167;3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_3_1" class="paragraph-anchor"></a><b>&#167;3.3.1. </b>Unusually, opcode invocations do not work by recursing down through the tree
to pick up the operands implicitly: instead we gather them into a small array.
This is because of the slightly clumsy way in which labels are represented in
Inter assembly, which we want to take care of here, so that generators don't
need to.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Scan the operands</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="identifier-syntax">LOOP_THROUGH_INTER_CHILDREN</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</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">Inode::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">ASSEMBLY_IST</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">AssemblyInstruction::which_marker</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">) == </span><span class="identifier-syntax">ASM_NEG_ASMMARKER</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">label_sense</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">continue</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">Inode::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">LAB_IST</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">label_sense</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">) </span><span class="identifier-syntax">label_sense</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">label</span><span class="plain-syntax"> = </span><span class="identifier-syntax">F</span><span class="plain-syntax">; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">operand_count</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">MAX_OPERANDS_IN_INTER_ASSEMBLY</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">operands</span><span class="plain-syntax">[</span><span class="identifier-syntax">operand_count</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">F</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-vc2.html#SP3_3">&#167;3.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>If they are not further invocations or code blocks, for which see above, the
nodes under an invocation will be <span class="extract"><span class="extract-syntax">val</span></span>, <span class="extract"><span class="extract-syntax">ref</span></span> or <span class="extract"><span class="extract-syntax">lab</span></span>.
</p>
<p class="commentary">A <span class="extract"><span class="extract-syntax">ref</span></span> can be to a variable; a <span class="extract"><span class="extract-syntax">val</span></span> can be to a named constant, a variable
or a literal. The special <span class="extract"><span class="extract-syntax">self</span></span> symbol, which has no definition, counts as
a variable here.
</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">VanillaCode::val_or_ref</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">VanillaCode::val_or_ref</span></span>:<br/>Vanilla - <a href="2-vnl.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree_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">ref</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_pair</span><span class="plain-syntax"> </span><span class="identifier-syntax">val</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InterValuePairs::undef</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">Inode::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">VAL_IST</span><span class="plain-syntax">)) </span><span class="identifier-syntax">val</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ValInstruction::value</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">Inode::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">REF_IST</span><span class="plain-syntax">)) </span><span class="identifier-syntax">val</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RefInstruction::value</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">InterValuePairs::is_symbolic</span><span class="plain-syntax">(</span><span class="identifier-syntax">val</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">named_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InterValuePairs::to_symbol_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">val</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">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">InterSymbol::trans</span><span class="plain-syntax">(</span><span class="identifier-syntax">named_s</span><span class="plain-syntax">), </span><span class="identifier-syntax">I</span><span class="string-syntax">"self"</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Inode::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">named_s</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">definition</span><span class="plain-syntax">, </span><span class="identifier-syntax">VARIABLE_IST</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><a href="2-cg2.html#SP17" class="function-link"><span class="function-syntax">Generators::evaluate_variable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">named_s</span><span class="plain-syntax">, </span><span class="identifier-syntax">ref</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><a href="2-cg2.html#SP19" class="function-link"><span class="function-syntax">Generators::compile_literal_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">named_s</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">InterValuePairs::is_undef</span><span class="plain-syntax">(</span><span class="identifier-syntax">val</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">"undef val/ref in Inter tree"</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><a href="2-cg.html#SP18" class="function-link"><span class="function-syntax">CodeGen::pair</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">val</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>A <span class="extract"><span class="extract-syntax">lab</span></span> works on a named label, which will be defined somewhere in the same
function body.
</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">VanillaCode::lab</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">VanillaCode::lab</span></span>:<br/>Vanilla - <a href="2-vnl.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">label_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LabInstruction::label_symbol</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">label_s</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"unknown label in lab in Inter tree"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cg2.html#SP13" class="function-link"><span class="function-syntax">Generators::evaluate_label</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterSymbol::identifier</span><span class="plain-syntax">(</span><span class="identifier-syntax">label_s</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>An <span class="extract"><span class="extract-syntax">assembly</span></span> specifies one of a fixed number of special assembly-language
punctuation marks:
</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">VanillaCode::assembly</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">VanillaCode::assembly</span></span>:<br/>Vanilla - <a href="2-vnl.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax"> </span><span class="identifier-syntax">which</span><span class="plain-syntax"> = </span><span class="identifier-syntax">AssemblyInstruction::which_marker</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cg2.html#SP14" class="function-link"><span class="function-syntax">Generators::assembly_marker</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">which</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="2-vo.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresssection"><a href="2-cg.html">cg</a></li><li class="progresssection"><a href="2-cg2.html">cg2</a></li><li class="progresssection"><a href="2-vnl.html">vnl</a></li><li class="progresssection"><a href="2-vc.html">vc</a></li><li class="progresssection"><a href="2-vf.html">vf</a></li><li class="progresssection"><a href="2-vo.html">vo</a></li><li class="progresscurrent">vc2</li><li class="progresssection"><a href="2-vi.html">vi</a></li><li class="progresschapter"><a href="3-fti.html">3</a></li><li class="progresschapter"><a href="4-fi6.html">4</a></li><li class="progresschapter"><a href="5-fnc.html">5</a></li><li class="progressnext"><a href="2-vi.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>