mirror of
https://github.com/ganelson/inform.git
synced 2024-07-16 22:14:23 +03:00
379 lines
59 KiB
HTML
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">§2. Pushing, popping</a></li><li><a href="3-cb.html#SP7">§7. Activation and deactivation</a></li><li><a href="3-cb.html#SP9">§9. The life of a block</a></li><li><a href="3-cb.html#SP14">§14. Bodies</a></li><li><a href="3-cb.html#SP16">§16. Breakage</a></li><li><a href="3-cb.html#SP17">§17. Blocks and scope</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§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>§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>§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">§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>§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">§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"> = &(</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>§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">§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>§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">§8</a>, <a href="3-cb.html#SP9">§9</a>, <a href="3-cb.html#SP13">§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"> > </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">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>§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">§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>§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">§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">-></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>§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">§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>§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">-></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">-></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">-></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">-></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">-></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">§9</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>§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">§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">-></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">) > </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">-></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">-></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">-></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">-></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>§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">§4.3.4</a>, <a href="5-cbal.html#SP4_3_5">§4.3.5</a>, <a href="5-cbal.html#SP4_4_5">§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>§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">§4.3.4</a>, <a href="5-cbal.html#SP4_3_5">§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>§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">§4.3.4</a>, <a href="5-cbal.html#SP4_3_5_4">§4.3.5.4</a>, <a href="5-cbal.html#SP4_3_5_7">§4.3.5.7</a>, <a href="5-cbal.html#SP4_4_5">§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">-></span><span class="element-syntax">label_following</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">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">-></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">-></span><span class="element-syntax">tail_schema</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="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>§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">§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"> >= </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>§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">-></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">-></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">§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">-></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>§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">§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"> >= </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>§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">§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>§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">§1</a>, <a href="4-cl.html#SP4">§4</a><br/>Compile Invocations Inline - <a href="5-cii.html#SP3_2">§3.2</a>, <a href="5-cii.html#SP6_5_1_1">§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">❮</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">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|