1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 00:24:22 +03:00
inform7/docs/imperative-module/3-cb.html
2022-04-28 17:37:28 +01:00

379 lines
59 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Code Blocks</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 'Code Blocks' 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#3">Chapter 3: Functions</a></li><li><b>Code Blocks</b></li></ul></div>
<p class="purpose">Blocks of code are used to give conditionals and loops greater scope, as in more traditional programming languages.</p>
<ul class="toc"><li><a href="3-cb.html#SP2">&#167;2. Pushing, popping</a></li><li><a href="3-cb.html#SP7">&#167;7. Activation and deactivation</a></li><li><a href="3-cb.html#SP9">&#167;9. The life of a block</a></li><li><a href="3-cb.html#SP14">&#167;14. Bodies</a></li><li><a href="3-cb.html#SP16">&#167;16. Breakage</a></li><li><a href="3-cb.html#SP17">&#167;17. Blocks and scope</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. </b>During code compilation, we must keep track of statement blocks: those
forming the body of "if", "while" or "repeat". The phrase as a whole does
not count as a block as such, unlike in C. In the following example, <span class="extract"><span class="extract-syntax">S</span></span>
is the "scope level", i.e., the number of blocks currently open:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">To</span><span class="plain-syntax"> </span><span class="identifier-syntax">show</span><span class="plain-syntax"> </span><span class="identifier-syntax">what</span><span class="plain-syntax"> </span><span class="identifier-syntax">this</span><span class="plain-syntax"> </span><span class="identifier-syntax">means</span><span class="plain-syntax">:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">if</span><span class="plain-syntax"> </span><span class="identifier-syntax">the</span><span class="plain-syntax"> </span><span class="identifier-syntax">player</span><span class="plain-syntax"> </span><span class="identifier-syntax">is</span><span class="plain-syntax"> </span><span class="identifier-syntax">in</span><span class="plain-syntax"> </span><span class="identifier-syntax">the</span><span class="plain-syntax"> </span><span class="identifier-syntax">Arboretum</span><span class="plain-syntax">: </span><span class="comment-syntax"> = 0</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">say</span><span class="plain-syntax"> </span><span class="string-syntax">"You are surrounded by trees."</span><span class="plain-syntax">; </span><span class="comment-syntax"> = 1</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">repeat</span><span class="plain-syntax"> </span><span class="identifier-syntax">with</span><span class="plain-syntax"> </span><span class="identifier-syntax">the</span><span class="plain-syntax"> </span><span class="identifier-syntax">menace</span><span class="plain-syntax"> </span><span class="identifier-syntax">running</span><span class="plain-syntax"> </span><span class="identifier-syntax">through</span><span class="plain-syntax"> </span><span class="identifier-syntax">trees</span><span class="plain-syntax"> </span><span class="identifier-syntax">in</span><span class="plain-syntax"> </span><span class="identifier-syntax">the</span><span class="plain-syntax"> </span><span class="identifier-syntax">Arboretum</span><span class="plain-syntax">: </span><span class="comment-syntax"> = 1</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">say</span><span class="plain-syntax"> </span><span class="string-syntax">"[The menace] crowds in."</span><span class="plain-syntax">; </span><span class="comment-syntax"> = 2</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">otherwise</span><span class="plain-syntax">: </span><span class="comment-syntax"> = 0</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">say</span><span class="plain-syntax"> </span><span class="string-syntax">"This is a thankfully open space."</span><span class="plain-syntax"> </span><span class="comment-syntax"> = 1</span>
</pre>
<p class="commentary">In principle, this information belongs to the current stack frame, since
it's within the context of a stack frame that code is compiled. But it
would be wasteful to store arrays for statement blocks inside every stack
frame structure, because in practice we only compile within one stack
frame at a time, and we finish each before beginning the next. So we
store the block stack in the only instance of a private structure.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_BLOCK_NESTING</span><span class="plain-syntax"> </span><span class="constant-syntax">50</span><span class="plain-syntax"> </span><span class="comment-syntax"> largest possible value of S at any position</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">block_stack</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">pb_sp</span><span class="plain-syntax">; </span><span class="comment-syntax"> stack pointer for the block stack which follows:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">phrase_block</span><span class="plain-syntax"> </span><span class="identifier-syntax">pb_stack</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_BLOCK_NESTING</span><span class="plain-syntax">+1];</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">block_stack</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">phrase_block</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from_structure</span><span class="plain-syntax">; </span><span class="comment-syntax"> e.g., "if" or "while"</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">block_location</span><span class="plain-syntax">; </span><span class="comment-syntax"> where block begins</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">switch_val</span><span class="plain-syntax">; </span><span class="comment-syntax"> for a switch statement</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">inter_schema</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tail_schema</span><span class="plain-syntax">; </span><span class="comment-syntax"> code to add when the block closes</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">csi_state</span><span class="plain-syntax"> </span><span class="identifier-syntax">compilation_state</span><span class="plain-syntax">; </span><span class="comment-syntax"> details needed to compile that code</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">label_following</span><span class="plain-syntax">; </span><span class="comment-syntax"> or -1 if none is used</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">phrase_block</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure block_stack is private to this section.</li><li>The structure phrase_block is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. Pushing, popping. </b>We need to keep track of two positions on the stack: the top (filled) entry,
and, sometimes, the one above it.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">block_stack</span><span class="plain-syntax"> </span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">phrase_block</span><span class="plain-syntax"> *</span><span class="identifier-syntax">block_being_compiled</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> the one being compiled, if any</span>
<span class="reserved-syntax">phrase_block</span><span class="plain-syntax"> *</span><span class="identifier-syntax">block_being_opened</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> the one about to open, if any</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>We need to be careful changing any of these without keeping the others in
line, so the only code allowed to change them is 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">CodeBlocks::empty_stack</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">CodeBlocks::empty_stack</span></span>:<br/><a href="3-cb.html#SP7">&#167;7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">block_being_compiled</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">block_being_opened</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>Pushing happens in two stages. First we make a pointer to what will be, but
is not yet, the top of the stack:
</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">CodeBlocks::prepush_stack</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">CodeBlocks::prepush_stack</span></span>:<br/><a href="3-cb.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">block_being_opened</span><span class="plain-syntax"> = &amp;(</span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_sp</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>And then we actually increment the stack pointer:
</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">CodeBlocks::push_stack</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">CodeBlocks::push_stack</span></span>:<br/><a href="3-cb.html#SP11">&#167;11</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_sp</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">block_being_compiled</span><span class="plain-syntax"> = </span><span class="identifier-syntax">block_being_opened</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">block_being_opened</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>Popping is easier:
</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">CodeBlocks::pop_stack</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">CodeBlocks::pop_stack</span></span>:<br/><a href="3-cb.html#SP8">&#167;8</a>, <a href="3-cb.html#SP9">&#167;9</a>, <a href="3-cb.html#SP13">&#167;13</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_sp</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_sp</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">block_being_compiled</span><span class="plain-syntax"> = &amp;(</span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_sp</span><span class="plain-syntax"> - </span><span class="constant-syntax">1</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">block_being_compiled</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">block_being_opened</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> which should be true anyway</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. Activation and deactivation. </b>If a phrase needs code blocks, Inform should call this when compilation
begins:
</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">CodeBlocks::begin_code_blocks</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">CodeBlocks::begin_code_blocks</span></span>:<br/>Functions - <a href="3-fnc.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><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">NULL</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">"tried to use blocks outside stack frame"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">block_being_compiled</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">"tried to begin block stack already in use"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-cb.html#SP3" class="function-link"><span class="function-syntax">CodeBlocks::empty_stack</span></a><span class="plain-syntax">(); </span><span class="comment-syntax"> which it should be anyway</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">LOCAL_VARIABLES</span><span class="plain-syntax">, </span><span class="string-syntax">"Block stack now active\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. </b>And this when it ends. The stack should in fact be empty, but just in
case we are recovering from some kind of problem, we'll empty anything
somehow left on 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">CodeBlocks::end_code_blocks</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">CodeBlocks::end_code_blocks</span></span>:<br/>Functions - <a href="3-fnc.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">block_being_compiled</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">block_being_compiled</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">block_location</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="3-cb.html#SP6" class="function-link"><span class="function-syntax">CodeBlocks::pop_stack</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">block_being_compiled</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">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">LOCAL_VARIABLES</span><span class="plain-syntax">, </span><span class="string-syntax">"Block stack now inactive\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. The life of a block. </b>So now let's follow what happens when a block is being compiled. Suppose
we have:
</p>
<blockquote>
<p>repeat through the Table of Odds:</p>
</blockquote>
<p class="commentary">When Inform begins to compile this invocation, it observes that the phrase
being invoked is followed by a code block, and calls the following routine
to warn us. (That doesn't mean the block is opening yet: the setup code
for the loop hasn't been compiled yet.)
</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">CodeBlocks::beginning_block_phrase</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">CodeBlocks::beginning_block_phrase</span></span>:<br/>Compile Blocks and Lines - <a href="5-cbal.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">csp</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">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_sp</span><span class="plain-syntax"> == </span><span class="constant-syntax">MAX_BLOCK_NESTING</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"block stack overflow"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-cb.html#SP6" class="function-link"><span class="function-syntax">CodeBlocks::pop_stack</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="3-cb.html#SP4" class="function-link"><span class="function-syntax">CodeBlocks::prepush_stack</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">block_being_opened</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-cb.html#SP9_1" class="named-paragraph-link"><span class="named-paragraph">Construct the next phrase block</span><span class="named-paragraph-number">9.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9_1" class="paragraph-anchor"></a><b>&#167;9.1. </b>In the case of a repeat through a Table, we need to create two loop
variables. In addition to those, the loop we're compiling will inevitably
change the two row selection variables (always called <span class="extract"><span class="extract-syntax">ct_0</span></span> and <span class="extract"><span class="extract-syntax">ct_1</span></span>),
so we need to protect their contents; we push them onto the stack before
the loop begins, and pull them again when it finishes.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Construct the next phrase block</span><span class="named-paragraph-number">9.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">block_being_opened</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">switch_val</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">block_being_opened</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">tail_schema</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">block_being_opened</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">block_location</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">block_being_opened</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">from_structure</span><span class="plain-syntax"> = </span><span class="identifier-syntax">csp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">block_being_opened</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">label_following</span><span class="plain-syntax"> = -1;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-cb.html#SP9">&#167;9</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. </b>Slightly later on, we know these:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">CodeBlocks::attach_back_schema</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">CodeBlocks::attach_back_schema</span></span>:<br/>Compile Invocations Inline - <a href="5-cii.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">inter_schema</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="reserved-syntax">csi_state</span><span class="plain-syntax"> </span><span class="identifier-syntax">CSIS</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">block_being_opened</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">block_being_opened</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">switch_val</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">Invocations::get_no_tokens</span><span class="plain-syntax">(</span><span class="identifier-syntax">CSIS</span><span class="plain-syntax">.</span><span class="element-syntax">inv</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">block_being_opened</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">switch_val</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CSIS</span><span class="plain-syntax">.</span><span class="element-syntax">tokens</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">token_vals</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">block_being_opened</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">tail_schema</span><span class="plain-syntax"> = </span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">block_being_opened</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">compilation_state</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CSIS</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>At this next stage, the preliminary code for the loop (if it's a loop)
has been compiled, and we're ready to open the actual block:
</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">CodeBlocks::open_code_block</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">CodeBlocks::open_code_block</span></span>:<br/>Compile Blocks and Lines - <a href="5-cbal.html#SP4_3_4">&#167;4.3.4</a>, <a href="5-cbal.html#SP4_3_5">&#167;4.3.5</a>, <a href="5-cbal.html#SP4_4_5">&#167;4.4.5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_sp</span><span class="plain-syntax"> != </span><span class="constant-syntax">MAX_BLOCK_NESTING</span><span class="plain-syntax">) </span><a href="3-cb.html#SP5" class="function-link"><span class="function-syntax">CodeBlocks::push_stack</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">LOCAL_VARIABLES</span><span class="plain-syntax">, </span><span class="string-syntax">"Start of block level %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_sp</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. </b>A division in a code block occurs at the "otherwise" point of an "if",
for example, but also for cases in a switch-style "if", so there can be
many of them.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CodeBlocks::divide_code_block</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">CodeBlocks::divide_code_block</span></span>:<br/>Compile Blocks and Lines - <a href="5-cbal.html#SP4_3_4">&#167;4.3.4</a>, <a href="5-cbal.html#SP4_3_5">&#167;4.3.5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">block_being_compiled</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">; </span><span class="comment-syntax"> for problem recovery only</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">LOCAL_VARIABLES</span><span class="plain-syntax">, </span><span class="string-syntax">"Division in block level %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_sp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lvs.html#SP17" class="function-link"><span class="function-syntax">LocalVariableSlates::end_scope</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_sp</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. </b>Whatever we pushed earlier, we now pull:
</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">CodeBlocks::close_code_block</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">CodeBlocks::close_code_block</span></span>:<br/>Compile Blocks and Lines - <a href="5-cbal.html#SP4_3_4">&#167;4.3.4</a>, <a href="5-cbal.html#SP4_3_5_4">&#167;4.3.5.4</a>, <a href="5-cbal.html#SP4_3_5_7">&#167;4.3.5.7</a>, <a href="5-cbal.html#SP4_4_5">&#167;4.4.5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">block_being_compiled</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">; </span><span class="comment-syntax"> for problem recovery only</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">block_being_compiled</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">label_following</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</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">TL</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">TL</span><span class="plain-syntax">, </span><span class="string-syntax">".loop_break_%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">block_being_compiled</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">label_following</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::place_label</span><span class="plain-syntax">(</span><span class="identifier-syntax">EmitCode::reserve_label</span><span class="plain-syntax">(</span><span class="identifier-syntax">TL</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">TL</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">LOCAL_VARIABLES</span><span class="plain-syntax">, </span><span class="string-syntax">"End of block level %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_sp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lvs.html#SP17" class="function-link"><span class="function-syntax">LocalVariableSlates::end_scope</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_sp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="5-cii.html#SP4" class="function-link"><span class="function-syntax">CSIInline::csi_inline_back</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">block_being_compiled</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">tail_schema</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> &amp;(</span><span class="identifier-syntax">block_being_compiled</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">compilation_state</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="3-cb.html#SP6" class="function-link"><span class="function-syntax">CodeBlocks::pop_stack</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. Bodies. </b>Are we in the body of a loop, perhaps indirectly?
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">CodeBlocks::inside_a_loop_body</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">CodeBlocks::inside_a_loop_body</span></span>:<br/>Compile Invocations Inline - <a href="5-cii.html#SP6_5_3">&#167;6.5.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="identifier-syntax">pb_sp</span><span class="plain-syntax">-1; </span><span class="identifier-syntax">i</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">--)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ControlStructures::is_a_loop</span><span class="plain-syntax">(</span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">from_structure</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. </b>What can we find about the block we are most immediately in? Note that
if there is no current block stack, we behave as if the block stack were
empty, but (as long as nobody tries to open or close any blocks) no
internal errors are issued. This allows the typechecker to run even when
there is no current block stack, which is important when typechecking an
expression whose evaluation requires the use of a phrase.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">CodeBlocks::current_block_level</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_sp</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> *</span><span class="function-syntax">CodeBlocks::name_of_current_block</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">block_being_compiled</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">ControlStructures::incipit</span><span class="plain-syntax">(</span><span class="identifier-syntax">block_being_compiled</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">from_structure</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">CodeBlocks::start_of_current_block</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">block_being_compiled</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">block_being_compiled</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">block_location</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">CodeBlocks::switch_value</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">CodeBlocks::switch_value</span></span>:<br/>Compile Blocks and Lines - <a href="5-cbal.html#SP4_3_5">&#167;4.3.5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">block_being_compiled</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">block_being_compiled</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">switch_val</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. Breakage. </b>We break out of the current loop by jumping to a label placed just after the loop ends.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">unique_breakage_count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CodeBlocks::emit_break</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">CodeBlocks::emit_break</span></span>:<br/>Compile Invocations Inline - <a href="5-cii.html#SP6_7">&#167;6.7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_sp</span><span class="plain-syntax">-1; </span><span class="identifier-syntax">i</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">--)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ControlStructures::permits_break</span><span class="plain-syntax">(</span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">from_structure</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">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">label_following</span><span class="plain-syntax"> == -1)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">label_following</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">unique_breakage_count</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">JUMP_BIP</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="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">TL</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">TL</span><span class="plain-syntax">, </span><span class="string-syntax">".loop_break_%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">label_following</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::lab</span><span class="plain-syntax">(</span><span class="identifier-syntax">EmitCode::reserve_label</span><span class="plain-syntax">(</span><span class="identifier-syntax">TL</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">TL</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="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"not inside a loop block"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. Blocks and scope. </b>When "let" creates something, this is called:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CodeBlocks::set_scope_to_current_block</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">CodeBlocks::set_scope_to_current_block</span></span>:<br/>Compile Invocations Inline - <a href="5-cii.html#SP3_2">&#167;3.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><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="plain-syntax"> </span><a href="3-lvs.html#SP15" class="function-link"><span class="function-syntax">LocalVariableSlates::set_scope_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_sp</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. </b>But when loops create something, this is called instead, because the loop
counter exists in one scope level inside the one holding the loop header
phrase:
</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">CodeBlocks::set_scope_to_block_about_to_open</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">CodeBlocks::set_scope_to_block_about_to_open</span></span>:<br/>Compile Loops - <a href="4-cl.html#SP1">&#167;1</a>, <a href="4-cl.html#SP4">&#167;4</a><br/>Compile Invocations Inline - <a href="5-cii.html#SP3_2">&#167;3.2</a>, <a href="5-cii.html#SP6_5_1_1">&#167;6.5.1.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><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="plain-syntax"> </span><a href="3-lvs.html#SP15" class="function-link"><span class="function-syntax">LocalVariableSlates::set_scope_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_block_stack</span><span class="plain-syntax">.</span><span class="element-syntax">pb_sp</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</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="3-lp.html">&#10094;</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="progresscurrentchapter">3</li><li class="progresssection"><a href="3-sf.html">sf</a></li><li class="progresssection"><a href="3-lvs.html">lvs</a></li><li class="progresssection"><a href="3-lv.html">lv</a></li><li class="progresssection"><a href="3-tv.html">tv</a></li><li class="progresssection"><a href="3-lp.html">lp</a></li><li class="progresscurrent">cb</li><li class="progresssection"><a href="3-fnc.html">fnc</a></li><li class="progresssection"><a href="3-jl.html">jl</a></li><li class="progresssection"><a href="3-pr.html">pr</a></li><li class="progresssection"><a href="3-cls.html">cls</a></li><li class="progresssection"><a href="3-cid.html">cid</a></li><li class="progresschapter"><a href="4-cs.html">4</a></li><li class="progresschapter"><a href="5-cbal.html">5</a></li><li class="progressnext"><a href="3-fnc.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>