1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-06-26 04:00:43 +03:00

Fix for Jira bug I7-2118

This commit is contained in:
Graham Nelson 2022-05-18 00:45:14 +01:00
parent dbf32eb593
commit 87b3b71785
13 changed files with 122 additions and 45 deletions

View file

@ -1,6 +1,6 @@
# Inform 7
v10.1.0-beta+6V09 'Krypton' (17 May 2022)
v10.1.0-beta+6V10 'Krypton' (18 May 2022)
## About Inform 7

View file

@ -1,3 +1,3 @@
Prerelease: beta
Build Date: 17 May 2022
Build Number: 6V09
Build Date: 18 May 2022
Build Number: 6V10

View file

@ -1373,6 +1373,34 @@ but the point is that locals of that kind are automatically set to their
default values when created, so they are always typesafe anyway.
</p>
<p class="commentary">Note also that the Dash typechecker allows the creation of local variables
whose kinds are subkinds of objects which may have no instances. For example,
in this program:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> A cat is a kind of animal.</span>
<span class="plain-syntax"> To discuss the felines:</span>
<span class="plain-syntax"> let C be a cat;</span>
<span class="plain-syntax"> ...</span>
</pre>
<p class="commentary">...it is legal to construct the variable <span class="extract"><span class="extract-syntax">C</span></span> with kind <span class="extract"><span class="extract-syntax">cat</span></span>, even though there
are no cats in the world, so that a call to <span class="extract"><span class="extract-syntax">DefaultValues::val</span></span> would
generate a problem message. But we call <span class="extract"><span class="extract-syntax">DefaultValues::val_allowing_nothing</span></span>
instead, so that <span class="extract"><span class="extract-syntax">C</span></span> is created but with the value <span class="extract"><span class="extract-syntax">nothing</span></span>.
</p>
<p class="commentary">This would be easier to understand if Inform's kinds system supported "optionals".
In the Swift language, for example, there would be a clear distinction between
the types <span class="extract"><span class="extract-syntax">Cat</span></span> (runtime values must be instances of cat) and <span class="extract"><span class="extract-syntax">Cat?</span></span> (runtime
values must be instances of cat or else <span class="extract"><span class="extract-syntax">nothing</span></span>). In Inform, cat-valued global
variables and properties have the type <span class="extract"><span class="extract-syntax">Cat</span></span>, but cat-valued locals have the
type <span class="extract"><span class="extract-syntax">Cat?</span></span>. We do this to make it more convenient to write functions about
cats which will compile whether or not any cats exist; an extension might provide
such functions, for example, providing functionality which is only used if cats
do exist, but which should still compile without errors even if they do not.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Inline command "initialise"</span><span class="named-paragraph-number">6.5.3</span></span><span class="comment-syntax"> =</span>
</p>
@ -1402,9 +1430,8 @@ default values when created, so they are always typesafe anyway.
<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">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP1" class="function-link"><span class="function-syntax">LocalVariables::declare</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">lvar_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DefaultValues::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">V</span><span class="plain-syntax">), </span><span class="string-syntax">"value"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DefaultValues::val_allowing_nothing</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">V</span><span class="plain-syntax">), </span><span class="string-syntax">"value"</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rv</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>

View file

@ -88,19 +88,25 @@ messages.
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">DefaultValues::array_entry</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">DefaultValues::array_entry</span></span>:<br/>Tables - <a href="5-tbl.html#SP2_1_1_1_5">&#167;2.1.1.1.5</a></span></button><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="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">storage_name</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">value_holster</span><span class="plain-syntax"> </span><span class="identifier-syntax">VH</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Holsters::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">INTER_DATA_VHMODE</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">rv</span><span class="plain-syntax"> = </span><a href="2-dv.html#SP1" class="function-link"><span class="function-syntax">DefaultValues::to_holster</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">VH</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">storage_name</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">rv</span><span class="plain-syntax"> = </span><a href="2-dv.html#SP1" class="function-link"><span class="function-syntax">DefaultValues::to_holster</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">VH</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">storage_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_pair</span><span class="plain-syntax"> </span><span class="identifier-syntax">val</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Holsters::unholster_to_pair</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">VH</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-ea.html#SP4" class="function-link"><span class="function-syntax">EmitArrays::generic_entry</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">val</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">rv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">DefaultValues::val</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">DefaultValues::val</span></span>:<br/>Kind Constructors - <a href="5-kc.html#SP10">&#167;10</a></span></button><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="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">storage_name</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">value_holster</span><span class="plain-syntax"> </span><span class="identifier-syntax">VH</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Holsters::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">INTER_DATA_VHMODE</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">rv</span><span class="plain-syntax"> = </span><a href="2-dv.html#SP1" class="function-link"><span class="function-syntax">DefaultValues::to_holster</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">VH</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">storage_name</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">rv</span><span class="plain-syntax"> = </span><a href="2-dv.html#SP1" class="function-link"><span class="function-syntax">DefaultValues::to_holster</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">VH</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">storage_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Holsters::unholster_to_code_val</span><span class="plain-syntax">(</span><a href="2-emt.html#SP1" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), &amp;</span><span class="identifier-syntax">VH</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">rv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">DefaultValues::val_allowing_nothing</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="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">storage_name</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">value_holster</span><span class="plain-syntax"> </span><span class="identifier-syntax">VH</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Holsters::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">INTER_DATA_VHMODE</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">rv</span><span class="plain-syntax"> = </span><a href="2-dv.html#SP1" class="function-link"><span class="function-syntax">DefaultValues::to_holster</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">VH</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">storage_name</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">Holsters::unholster_to_code_val</span><span class="plain-syntax">(</span><a href="2-emt.html#SP1" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), &amp;</span><span class="identifier-syntax">VH</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">rv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">DefaultValues::to_holster</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">DefaultValues::to_holster</span></span>:<br/>Variables - <a href="5-vrb.html#SP16_1">&#167;16.1</a><br/>Properties - <a href="5-prp.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">value_holster</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VH</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">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">storage_name</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">storage_name</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">allow_nothing_object_as_default</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-dv.html#SP1_3" class="named-paragraph-link"><span class="named-paragraph">"Value" is too vague to be the kind of a variable</span><span class="named-paragraph-number">1.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Behaviour::definite</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
@ -122,7 +128,10 @@ messages.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</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">allow_nothing_object_as_default</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Holsters::holster_pair</span><span class="plain-syntax">(</span><span class="identifier-syntax">VH</span><span class="plain-syntax">, </span><a href="2-dv.html#SP2" class="function-link"><span class="function-syntax">DefaultValues::to_value_pair</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</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">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording_as_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">storage_name</span><span class="plain-syntax">);</span>
@ -199,7 +208,7 @@ for example, the default value of <span class="extract"><span class="extract-syn
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">inter_pair</span><span class="plain-syntax"> </span><span class="function-syntax">DefaultValues::to_value_pair</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">DefaultValues::to_value_pair</span></span>:<br/><a href="2-dv.html#SP1">&#167;1</a></span></button><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="identifier-syntax">inter_pair</span><span class="plain-syntax"> </span><span class="function-syntax">DefaultValues::to_value_pair</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">DefaultValues::to_value_pair</span></span>:<br/><a href="2-dv.html#SP1">&#167;1</a>, <a href="2-dv.html#SP1_1">&#167;1.1</a></span></button><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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</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">InterValuePairs::undef</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-dv.html#SP2_1" class="named-paragraph-link"><span class="named-paragraph">Constructed kinds stored as block values</span><span class="named-paragraph-number">2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-dv.html#SP2_2" class="named-paragraph-link"><span class="named-paragraph">Base kinds stored as block values</span><span class="named-paragraph-number">2.2</span></a></span><span class="plain-syntax">;</span>

View file

@ -315,7 +315,7 @@ typesafe for those.
<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="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ValueProperties::kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">prn</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-dv.html#SP1" class="function-link"><span class="function-syntax">DefaultValues::to_holster</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">VH</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">prn</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="string-syntax">"property"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-dv.html#SP1" class="function-link"><span class="function-syntax">DefaultValues::to_holster</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">VH</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">prn</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="string-syntax">"property"</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="SP9" class="paragraph-anchor"></a><b>&#167;9. Schemas. </b>"Value" properties (those which are not either-or) can be tested or set with

View file

@ -522,7 +522,8 @@ which makes its kind safe.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-dv.html#SP1" class="function-link"><span class="function-syntax">DefaultValues::to_holster</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">VH</span><span class="plain-syntax">, </span><span class="identifier-syntax">nlv</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">nlv_kind</span><span class="plain-syntax">, </span><span class="identifier-syntax">nlv</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="string-syntax">"variable"</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-dv.html#SP1" class="function-link"><span class="function-syntax">DefaultValues::to_holster</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">VH</span><span class="plain-syntax">, </span><span class="identifier-syntax">nlv</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">nlv_kind</span><span class="plain-syntax">, </span><span class="identifier-syntax">nlv</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="string-syntax">"variable"</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nlv</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">var_is_allowed_to_be_zero</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Holsters::holster_pair</span><span class="plain-syntax">(</span><span class="identifier-syntax">VH</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterValuePairs::number</span><span class="plain-syntax">(0));</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>

View file

@ -2744,9 +2744,10 @@ kind, which is good enough.
</p>
<p class="commentary">Otherwise, we either know the kind already from polymorphism calculations, or
we can work it out by seeing what the initial value evaluates to. As usual,
we "round up to objects"; if the let-value is a kind of object, we make
the variable have kind "object", rather than some subkind.
we can work it out by seeing what the initial value evaluates to. Note that
with values which are objects, we guess the kind as the broadest subkind of
"object" to which the value belongs: in practice that means usually a thing,
a room or a region.
</p>
<p class="commentary">We make one exception to allow lines like &mdash;
@ -2784,12 +2785,14 @@ of a relation.
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP13_1_1_2" class="named-paragraph-link"><span class="named-paragraph">Fail: the initial value of the local is the empty list</span><span class="named-paragraph-number">13.1.1.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Behaviour::definite</span><span class="plain-syntax">(</span><span class="identifier-syntax">seems_to_be</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP13_1_1_3" class="named-paragraph-link"><span class="named-paragraph">Fail: the initial value can't be stored</span><span class="named-paragraph-number">13.1.1.3</span></a></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">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(4A.c.1) Local variable seems to have kind: %u\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">seems_to_be</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">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(4A.c.1) Local variable seems to have kind: %u (kind-like: %d)\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">seems_to_be</span><span class="plain-syntax">, </span><a href="2-spc.html#SP2" class="function-link"><span class="function-syntax">Specifications::is_kind_like</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">initial_value</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">seems_to_be</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::is_subkind_of_object</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">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">Latticework::super</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">), </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Latticework::super</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">if</span><span class="plain-syntax"> (</span><a href="2-spc.html#SP2" class="function-link"><span class="function-syntax">Specifications::is_kind_like</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">initial_value</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Behaviour::is_subkind_of_object</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">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">Latticework::super</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">), </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Latticework::super</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">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(4A.c.1) Local variable inferred to have kind: %u\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP13_1">&#167;13.1</a>.</li></ul>

View file

@ -1,32 +1,33 @@
100.0% in inform7 run
71.1% in compilation to Inter
50.4% in //Sequence::undertake_queued_tasks//
4.7% in //MajorNodes::pre_pass//
71.4% in compilation to Inter
51.0% in //Sequence::undertake_queued_tasks//
4.6% in //MajorNodes::pre_pass//
3.4% in //MajorNodes::pass_1//
1.8% in //ImperativeDefinitions::assess_all//
1.8% in //RTPhrasebook::compile_entries//
1.4% in //RTKindConstructors::compile//
1.0% in //Sequence::lint_inter//
0.6% in //MajorNodes::pass_2//
0.6% in //Sequence::undertake_queued_tasks//
0.6% in //World::stage_V//
0.4% in //ImperativeDefinitions::compile_first_block//
0.4% in //MajorNodes::pass_2//
0.4% in //Sequence::undertake_queued_tasks//
0.2% in //CompletionModule::compile//
0.2% in //InferenceSubjects::emit_all//
0.2% in //RTKindConstructors::compile_permissions//
0.2% in //Task::make_built_in_kind_constructors//
3.1% not specifically accounted for
26.2% in running Inter pipeline
10.2% in step 14/15: generate inform6 -> auto.inf
5.7% in step 5/15: load-binary-kits
5.5% in step 6/15: make-synoptic-module
0.2% in //World::stages_II_and_III//
2.8% not specifically accounted for
25.7% in running Inter pipeline
10.4% in step 14/15: generate inform6 -> auto.inf
5.6% in step 5/15: load-binary-kits
5.2% in step 6/15: make-synoptic-module
1.4% in step 9/15: make-identifiers-unique
0.4% in step 12/15: eliminate-redundant-operations
0.4% in step 4/15: compile-splats
0.4% in step 7/15: shorten-wiring
0.4% in step 8/15: detect-indirect-calls
0.2% in step 11/15: eliminate-redundant-labels
1.5% not specifically accounted for
2.2% in supervisor
1.3% not specifically accounted for
2.4% in supervisor
0.5% not specifically accounted for

View file

@ -1011,6 +1011,30 @@ of block value, like "list of numbers", it does nothing. This may seem odd,
but the point is that locals of that kind are automatically set to their
default values when created, so they are always typesafe anyway.
Note also that the Dash typechecker allows the creation of local variables
whose kinds are subkinds of objects which may have no instances. For example,
in this program:
= (text)
A cat is a kind of animal.
To discuss the felines:
let C be a cat;
...
=
...it is legal to construct the variable |C| with kind |cat|, even though there
are no cats in the world, so that a call to |DefaultValues::val| would
generate a problem message. But we call |DefaultValues::val_allowing_nothing|
instead, so that |C| is created but with the value |nothing|.
This would be easier to understand if Inform's kinds system supported "optionals".
In the Swift language, for example, there would be a clear distinction between
the types |Cat| (runtime values must be instances of cat) and |Cat?| (runtime
values must be instances of cat or else |nothing|). In Inform, cat-valued global
variables and properties have the type |Cat|, but cat-valued locals have the
type |Cat?|. We do this to make it more convenient to write functions about
cats which will compile whether or not any cats exist; an extension might provide
such functions, for example, providing functionality which is only used if cats
do exist, but which should still compile without errors even if they do not.
@<Inline command "initialise"@> =
parse_node *V = CSIInline::parse_bracing_operand_as_identifier(ist->operand,
idb, tokens, my_vars);
@ -1037,9 +1061,8 @@ default values when created, so they are always typesafe anyway.
EmitCode::down();
inter_symbol *lvar_s = LocalVariables::declare(lvar);
EmitCode::ref_symbol(K_value, lvar_s);
rv = DefaultValues::val(K, Node::get_text(V), "value");
rv = DefaultValues::val_allowing_nothing(K, Node::get_text(V), "value");
EmitCode::up();
if (rv == FALSE) {
Problems::quote_source(1, current_sentence);
Problems::quote_kind(2, K);

View file

@ -16,19 +16,25 @@ messages.
=
int DefaultValues::array_entry(kind *K, wording W, char *storage_name) {
value_holster VH = Holsters::new(INTER_DATA_VHMODE);
int rv = DefaultValues::to_holster(&VH, K, W, storage_name);
int rv = DefaultValues::to_holster(&VH, K, W, storage_name, FALSE);
inter_pair val = Holsters::unholster_to_pair(&VH);
EmitArrays::generic_entry(val);
return rv;
}
int DefaultValues::val(kind *K, wording W, char *storage_name) {
value_holster VH = Holsters::new(INTER_DATA_VHMODE);
int rv = DefaultValues::to_holster(&VH, K, W, storage_name);
int rv = DefaultValues::to_holster(&VH, K, W, storage_name, FALSE);
Holsters::unholster_to_code_val(Emit::tree(), &VH);
return rv;
}
int DefaultValues::val_allowing_nothing(kind *K, wording W, char *storage_name) {
value_holster VH = Holsters::new(INTER_DATA_VHMODE);
int rv = DefaultValues::to_holster(&VH, K, W, storage_name, TRUE);
Holsters::unholster_to_code_val(Emit::tree(), &VH);
return rv;
}
int DefaultValues::to_holster(value_holster *VH, kind *K,
wording W, char *storage_name) {
wording W, char *storage_name, int allow_nothing_object_as_default) {
if (Kinds::eq(K, K_value))
@<"Value" is too vague to be the kind of a variable@>;
if (Kinds::Behaviour::definite(K) == FALSE)
@ -47,7 +53,10 @@ int DefaultValues::to_holster(value_holster *VH, kind *K,
}
@<The kind must have no instances, or it would have worked@> =
if (Wordings::nonempty(W)) {
if (allow_nothing_object_as_default) {
Holsters::holster_pair(VH, DefaultValues::to_value_pair(K_object));
return TRUE;
} else if (Wordings::nonempty(W)) {
Problems::quote_wording_as_source(1, W);
Problems::quote_kind(2, K);
Problems::quote_text(3, storage_name);

View file

@ -235,7 +235,7 @@ int RTProperties::compile_vp_default_value(value_holster *VH, property *prn) {
return TRUE;
}
kind *K = ValueProperties::kind(prn);
return DefaultValues::to_holster(VH, K, prn->name, "property");
return DefaultValues::to_holster(VH, K, prn->name, "property", FALSE);
}
@h Schemas.

View file

@ -431,7 +431,8 @@ void RTVariables::holster_initial_value(value_holster *VH, nonlocal_variable *nl
}
@<Initialise with the default value of its kind@> =
if (DefaultValues::to_holster(VH, nlv->nlv_kind, nlv->name, "variable") == FALSE) {
if (DefaultValues::to_holster(VH, nlv->nlv_kind, nlv->name, "variable", FALSE)
== FALSE) {
if (nlv->var_is_allowed_to_be_zero) {
Holsters::holster_pair(VH, InterValuePairs::number(0));
} else {

View file

@ -2181,9 +2181,10 @@ This doesn't give us an initial value as such, but it explicitly tells us the
kind, which is good enough.
Otherwise, we either know the kind already from polymorphism calculations, or
we can work it out by seeing what the initial value evaluates to. As usual,
we "round up to objects"; if the let-value is a kind of object, we make
the variable have kind "object", rather than some subkind.
we can work it out by seeing what the initial value evaluates to. Note that
with values which are objects, we guess the kind as the broadest subkind of
"object" to which the value belongs: in practice that means usually a thing,
a room or a region.
We make one exception to allow lines like --
@ -2213,12 +2214,14 @@ of a relation.
@<Fail: the initial value of the local is the empty list@>;
if (Kinds::Behaviour::definite(seems_to_be) == FALSE)
@<Fail: the initial value can't be stored@>;
LOGIF(MATCHING, "(4A.c.1) Local variable seems to have kind: %u\n", seems_to_be);
LOGIF(MATCHING, "(4A.c.1) Local variable seems to have kind: %u (kind-like: %d)\n",
seems_to_be, Specifications::is_kind_like(initial_value));
K = seems_to_be;
if (Kinds::Behaviour::is_subkind_of_object(K))
while (Kinds::eq(Latticework::super(K), K_object) == FALSE)
K = Latticework::super(K);
if (Specifications::is_kind_like(initial_value) == FALSE)
if (Kinds::Behaviour::is_subkind_of_object(K))
while (Kinds::eq(Latticework::super(K), K_object) == FALSE)
K = Latticework::super(K);
LOGIF(MATCHING, "(4A.c.1) Local variable inferred to have kind: %u\n", K);
@<Fail: the initial value of the local is unknown@> =