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-cls.html
2022-04-28 17:37:28 +01:00

286 lines
38 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Closures</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 src="http://code.jquery.com/jquery-1.12.4.min.js"
integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
<script src="../docs-assets/Bigfoot.js"></script>
<link href="../docs-assets/Bigfoot.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 'Closures' 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>Closures</b></li></ul></div>
<p class="purpose">To provide the names of phrases as first-class values.</p>
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. </b>Phrases which have been given names can be used as first-class values in
Inform, meaning that they can be stored in variables, have a kind which can
be expressed in Inform source text, and so on.
</p>
<p class="commentary">At runtime, it might be expected that such a constant would be stored just as
the address of the function. In fact it is stored as (the address of) a small
fixed-size array called a "closure", which does include the function address,
but also some metadata about it.
</p>
<p class="commentary">In the theory of compilers, the term "closure" is usually used more ambitiously
than this, in that closures "capture" references to local variables, thus enabling
"closed" functions to be made out of fragments occurring inside code. For example,
in the Swift programming language:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> var threshold = 10</span>
<span class="plain-syntax"> let fn = { x in return x &gt; threshold }</span>
<span class="plain-syntax"> return fn</span>
</pre>
<p class="commentary">a nameless function has been made with <span class="extract"><span class="extract-syntax">{ x in return x &gt; threshold }</span></span> which
includes a reference to a local variable not part of its own definition, i.e.,
<span class="extract"><span class="extract-syntax">threshold</span></span>. A reference to this must be "captured" and salted away in the
closure data, since otherwise by the time the <span class="extract"><span class="extract-syntax">fn</span></span> value is used, <span class="extract"><span class="extract-syntax">threshold</span></span>
will not exist.
</p>
<p class="commentary">This issue does not arise for Inform because, at present, there is no lambda
operator, or syntax like Swift's <span class="extract"><span class="extract-syntax">{ x in ... }</span></span>, for making one phrase inside
the body of another one.<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> So we never need capture anything, and phrases are
never half-open and so in that sense do not need closing, but we will continue
to use the flattering term "closure" anyway.
</p>
<ul class="footnotetexts"><li class="footnote" id="fn:1"><p class="inwebfootnote"><sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> Unless you count text substitutions, where exactly this issue of capturing
values does arise.
<a href="#fnref:1" title="return to text"> &#x21A9;</a></p></li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>This returns the iname for a closure array for <span class="extract"><span class="extract-syntax">cphr</span></span>. Since each phrase can
have at most one closure, and they occupy little memory, we do not need to
create or destroy them dynamically as small blocks: we can simply store them
in memory at known locations, and the iname here refers to that location.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">inter_name</span><span class="plain-syntax"> *</span><span class="function-syntax">Closures::iname</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">Closures::iname</span></span>:<br/><a href="3-cls.html#SP3_1">&#167;3.1</a><br/>Compile Rvalues - <a href="2-cr.html#SP1_3">&#167;1.3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">constant_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cphr</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">cphr</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">cphr_iname</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">id_body</span><span class="plain-syntax"> *</span><span class="identifier-syntax">idb</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ToPhraseFamily::body_of_constant</span><span class="plain-syntax">(</span><span class="identifier-syntax">cphr</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">idb</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"cannot reconstruct phrase from cphr"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">package_request</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Hierarchy::package_within</span><span class="plain-syntax">(</span><span class="identifier-syntax">CLOSURES_HAP</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="3-cid.html#SP8" class="function-link"><span class="function-syntax">CompileImperativeDefn::requests_package</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">idb</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cphr</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">cphr_iname</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Hierarchy::make_iname_in</span><span class="plain-syntax">(</span><span class="identifier-syntax">CLOSURE_DATA_HL</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</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">cphr</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">cphr_iname</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>And this is where those arrays are made:
</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">Closures::compile_closures</span><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">constant_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cphr</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">cphr</span><span class="plain-syntax">, </span><span class="identifier-syntax">constant_phrase</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">id_body</span><span class="plain-syntax"> *</span><span class="identifier-syntax">idb</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ToPhraseFamily::body_of_constant</span><span class="plain-syntax">(</span><span class="identifier-syntax">cphr</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">idb</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"cannot reconstruct phrase from cphr"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ToPhraseFamily::kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">cphr</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cls.html#SP3_1" class="named-paragraph-link"><span class="named-paragraph">Compile the closure array for this constant phrase</span><span class="named-paragraph-number">3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3_1" class="paragraph-anchor"></a><b>&#167;3.1. </b>The closure array consists of three words: the strong kind ID, the address
of the function, and the text of the name. (The latter enables us to print
phrase values efficiently.) Note that we make a compilation request for the
phrase in order to make sure somebody has actually compiled it: this is in
case the phrase occurs as a constant but is never explicitly invoked, as here &mdash;
</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">decide</span><span class="plain-syntax"> </span><span class="identifier-syntax">which</span><span class="plain-syntax"> </span><span class="identifier-syntax">number</span><span class="plain-syntax"> </span><span class="identifier-syntax">is</span><span class="plain-syntax"> (</span><span class="identifier-syntax">N</span><span class="plain-syntax"> - </span><span class="identifier-syntax">a</span><span class="plain-syntax"> </span><span class="identifier-syntax">number</span><span class="plain-syntax">) </span><span class="identifier-syntax">doubled</span><span class="plain-syntax"> (</span><span class="identifier-syntax">this</span><span class="plain-syntax"> </span><span class="identifier-syntax">is</span><span class="plain-syntax"> </span><span class="identifier-syntax">doubling</span><span class="plain-syntax">):</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">decide</span><span class="plain-syntax"> </span><span class="identifier-syntax">on</span><span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax"> + </span><span class="identifier-syntax">N</span><span class="plain-syntax">.</span>
<span class="identifier-syntax">To</span><span class="plain-syntax"> </span><span class="identifier-syntax">begin</span><span class="plain-syntax">:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">let</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax"> </span><span class="identifier-syntax">be</span><span class="plain-syntax"> { </span><span class="constant-syntax">2</span><span class="plain-syntax">, </span><span class="constant-syntax">3</span><span class="plain-syntax">, </span><span class="constant-syntax">5</span><span class="plain-syntax">, </span><span class="constant-syntax">7</span><span class="plain-syntax">, </span><span class="constant-syntax">11</span><span class="plain-syntax"> };</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">say</span><span class="plain-syntax"> </span><span class="string-syntax">"Doubling produces [doubling applied to L]."</span>
</pre>
<p class="commentary">In this source text, there is never an explicit invocation such as "4 doubled",
but the fact that the phrase has been given the name "doubling" is enough to
ensure that the closure array for it is compiled, and that forces a request
for the underlying function's compilation.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile the closure array for this constant phrase</span><span class="named-paragraph-number">3.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">iname</span><span class="plain-syntax"> = </span><a href="3-cls.html#SP2" class="function-link"><span class="function-syntax">Closures::iname</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cphr</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">packaging_state</span><span class="plain-syntax"> </span><span class="identifier-syntax">save</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EmitArrays::begin_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">iname</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">RTKindIDs::strong_ID_array_entry</span><span class="plain-syntax">(</span><span class="identifier-syntax">cphr</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">cphr_kind</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">RS</span><span class="plain-syntax"> = </span><a href="3-pr.html#SP1" class="function-link"><span class="function-syntax">PhraseRequests::simple_request</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">idb</span><span class="plain-syntax">, </span><span class="identifier-syntax">ToPhraseFamily::kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">cphr</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitArrays::iname_entry</span><span class="plain-syntax">(</span><span class="identifier-syntax">RS</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">name</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">name</span><span class="plain-syntax">, </span><span class="string-syntax">"%W"</span><span class="plain-syntax">, </span><span class="identifier-syntax">Nouns::nominative_singular</span><span class="plain-syntax">(</span><span class="identifier-syntax">cphr</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">name</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitArrays::text_entry</span><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitArrays::end</span><span class="plain-syntax">(</span><span class="identifier-syntax">save</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-cls.html#SP3">&#167;3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>Now we come to something trickier. We want default values for kinds of phrases,
because otherwise we can't have variables holding phrases unless they are
always initialised explicitly, and so on. Clearly the default value for a
phrase to nothing is one that does nothing, and for a phrase to some kind K
is one that returns the default value of kind K. For example, the default
value of
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> phrase (text, time) -&gt; number</span>
</pre>
<p class="commentary">is the function which takes any pair of a text and a time, does nothing with
them, and always returns the default number, i.e., 0. But this means we need
to actually compile such functions. Since there are in principle an infinite
number of distinct phrase kinds, we will only compile them for the phrase kinds
which actually arise during compilation.
</p>
<p class="commentary">The following function is called exactly once for each such kind <span class="extract"><span class="extract-syntax">K</span></span>.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">default_closure_request</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">inter_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">closure_identifier</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">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">default_closure_request</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Closures::compile_default_closure</span><span class="plain-syntax">(</span><span class="identifier-syntax">inter_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">closure_identifier</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">desc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::new</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">desc</span><span class="plain-syntax">, </span><span class="string-syntax">"default closure for %u"</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">default_closure_request</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dcr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">default_closure_request</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">dcr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">closure_identifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">closure_identifier</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">dcr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Sequence::queue</span><span class="plain-syntax">(&amp;</span><a href="3-cls.html#SP5" class="function-link"><span class="function-syntax">Closures::compilation_agent</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">STORE_POINTER_default_closure_request</span><span class="plain-syntax">(</span><span class="identifier-syntax">dcr</span><span class="plain-syntax">), </span><span class="identifier-syntax">desc</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure default_closure_request is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>And the actual compilation is done here, when we can be certain that no other
function is being compiled at the same time.
</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">Closures::compilation_agent</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">Closures::compilation_agent</span></span>:<br/><a href="3-cls.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">compilation_subtask</span><span class="plain-syntax"> *</span><span class="identifier-syntax">t</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">default_closure_request</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dcr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_default_closure_request</span><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">data</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">package_request</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RTKindConstructors::kind_package</span><span class="plain-syntax">(</span><span class="identifier-syntax">dcr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rname</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Hierarchy::make_iname_in</span><span class="plain-syntax">(</span><span class="identifier-syntax">DEFAULT_CLOSURE_FN_HL</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cls.html#SP5_1" class="named-paragraph-link"><span class="named-paragraph">Compile the default function</span><span class="named-paragraph-number">5.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cls.html#SP5_2" class="named-paragraph-link"><span class="named-paragraph">Compile its closure</span><span class="named-paragraph-number">5.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5_1" class="paragraph-anchor"></a><b>&#167;5.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile the default function</span><span class="named-paragraph-number">5.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">packaging_state</span><span class="plain-syntax"> </span><span class="identifier-syntax">save</span><span class="plain-syntax"> = </span><a href="3-fnc.html#SP2" class="function-link"><span class="function-syntax">Functions::begin</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lv.html#SP4" class="function-link"><span class="function-syntax">LocalVariables::new_other_parameter</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"a"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lv.html#SP4" class="function-link"><span class="function-syntax">LocalVariables::new_other_parameter</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"b"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lv.html#SP4" class="function-link"><span class="function-syntax">LocalVariables::new_other_parameter</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"c"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lv.html#SP4" class="function-link"><span class="function-syntax">LocalVariables::new_other_parameter</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"d"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lv.html#SP4" class="function-link"><span class="function-syntax">LocalVariables::new_other_parameter</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"e"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lv.html#SP4" class="function-link"><span class="function-syntax">LocalVariables::new_other_parameter</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"f"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lv.html#SP4" class="function-link"><span class="function-syntax">LocalVariables::new_other_parameter</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"g"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lv.html#SP4" class="function-link"><span class="function-syntax">LocalVariables::new_other_parameter</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"h"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">result</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">Kinds::binary_construction_material</span><span class="plain-syntax">(</span><span class="identifier-syntax">dcr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">result</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::get_construct</span><span class="plain-syntax">(</span><span class="identifier-syntax">result</span><span class="plain-syntax">) != </span><span class="identifier-syntax">CON_NIL</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">RETURN_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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Behaviour::uses_block_values</span><span class="plain-syntax">(</span><span class="identifier-syntax">result</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">iname</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">BLKVALUECREATE_HL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::call</span><span class="plain-syntax">(</span><span class="identifier-syntax">iname</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">RTKindIDs::emit_strong_ID_as_val</span><span class="plain-syntax">(</span><span class="identifier-syntax">result</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DefaultValues::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">result</span><span class="plain-syntax">, </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) != </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="3-fnc.html#SP6" class="function-link"><span class="function-syntax">Functions::end</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">save</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-cls.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_2" class="paragraph-anchor"></a><b>&#167;5.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile its closure</span><span class="named-paragraph-number">5.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">packaging_state</span><span class="plain-syntax"> </span><span class="identifier-syntax">save</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EmitArrays::begin_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">dcr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">closure_identifier</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">RTKindIDs::strong_ID_array_entry</span><span class="plain-syntax">(</span><span class="identifier-syntax">dcr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitArrays::iname_entry</span><span class="plain-syntax">(</span><span class="identifier-syntax">rname</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">DVT</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">DVT</span><span class="plain-syntax">, </span><span class="string-syntax">"default value of "</span><span class="plain-syntax">); </span><span class="identifier-syntax">Kinds::Textual::write</span><span class="plain-syntax">(</span><span class="identifier-syntax">DVT</span><span class="plain-syntax">, </span><span class="identifier-syntax">dcr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitArrays::text_entry</span><span class="plain-syntax">(</span><span class="identifier-syntax">DVT</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">DVT</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitArrays::end</span><span class="plain-syntax">(</span><span class="identifier-syntax">save</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-cls.html#SP5">&#167;5</a>.</li></ul>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="3-pr.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="progresssection"><a href="3-cb.html">cb</a></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="progresscurrent">cls</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-cid.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>