mirror of
https://github.com/ganelson/inform.git
synced 2024-07-18 06:54:26 +03:00
296 lines
38 KiB
HTML
296 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>MStack Template</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>
|
|
MathJax = {
|
|
tex: {
|
|
inlineMath: '$', '$'], ['\\(', '\\)'
|
|
},
|
|
svg: {
|
|
fontCache: 'global'
|
|
}
|
|
};
|
|
</script>
|
|
<script type="text/javascript" id="MathJax-script" async
|
|
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
|
|
</script>
|
|
|
|
<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>
|
|
</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/docs/index.html">inweb</a></li>
|
|
<li><a href="../../../intest/docs/index.html">intest</a></li>
|
|
|
|
</ul>
|
|
</nav>
|
|
<main role="main">
|
|
<!--Weave of 'MStack Template' generated by Inweb-->
|
|
<div class="breadcrumbs">
|
|
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../extensions.html">Kits</a></li><li><a href="index.html">BasicInformKit</a></li><li><b>MStack Template</b></li></ul></div>
|
|
<p class="purpose">To allocate space on the memory stack for frames of variables to be used by rulebooks, activities and actions.</p>
|
|
|
|
<ul class="toc"><li><a href="S-mst.html#SP1">§1. The Memory Stack</a></li><li><a href="S-mst.html#SP2">§2. Create Frame</a></li><li><a href="S-mst.html#SP3">§3. Destroy Frame</a></li><li><a href="S-mst.html#SP4">§4. Seek Frame</a></li><li><a href="S-mst.html#SP5">§5. Backtrace</a></li><li><a href="S-mst.html#SP6">§6. Access to Variables</a></li><li><a href="S-mst.html#SP7">§7. Access to Nonexistent Variables</a></li><li><a href="S-mst.html#SP8">§8. Rulebook Variables</a></li><li><a href="S-mst.html#SP9">§9. Activity Variables</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§1. The Memory Stack. </b>The M-Stack, or memory stack, is a sequence of frames, piled upwards.
|
|
If we had an accessible stack in memory, we could use that, but neither
|
|
the Z-machine nor Glulx has such a stack, alas, alas, alas. The following
|
|
is not a very good solution, but it just about works.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">MAX_MSTACK_FRAME</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax"> + </span><span class="identifier-syntax">MAX_FRAME_SIZE_NEEDED</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">MSTACK_CAPACITY</span><span class="plain-syntax"> = </span><span class="constant-syntax">20</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">MSTACK_SIZE</span><span class="plain-syntax"> = </span><span class="identifier-syntax">MSTACK_CAPACITY</span><span class="plain-syntax">*</span><span class="identifier-syntax">MAX_MSTACK_FRAME</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="reserved-syntax">Array</span><span class="plain-syntax"> </span><span class="identifier-syntax">MStack</span><span class="plain-syntax"> --> </span><span class="identifier-syntax">MSTACK_SIZE</span><span class="plain-syntax">;</span>
|
|
<span class="identifier-syntax">Global</span><span class="plain-syntax"> </span><span class="identifier-syntax">MStack_Top</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax">Topmost word currently used</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>§2. Create Frame. </b>A frame is created by calling the following function with two arguments:
|
|
<span class="extract"><span class="extract-syntax">creator</span></span>, a function which initialises a block of variables, and an
|
|
ID number identifying the owner.
|
|
</p>
|
|
|
|
<p class="commentary">The <span class="extract"><span class="extract-syntax">creator</span></span> function is called with the address at which to initialise
|
|
the variables as its first argument, and the value 1 as the second
|
|
argument. (The idea is that the same function can be used later to
|
|
deallocate the variables, and then the second argument will be \(-1\).)
|
|
The <span class="extract"><span class="extract-syntax">creator</span></span> function returns the extent of the block of memory it has
|
|
used, in words. Thus is required to be strictly less than <span class="extract"><span class="extract-syntax">MAX_MSTACK_FRAME</span></span>
|
|
minus 1.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">Mstack_Create_Frame</span><span class="plain-syntax"> </span><span class="identifier-syntax">creator</span><span class="plain-syntax"> </span><span class="identifier-syntax">id</span><span class="plain-syntax"> </span><span class="identifier-syntax">extent</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">creator</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">extent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">creator</span><span class="plain-syntax">.</span><span class="identifier-syntax">call</span><span class="plain-syntax">(</span><span class="identifier-syntax">MStack_Top</span><span class="plain-syntax">+2, </span><span class="constant-syntax">1</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">extent</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">rfalse</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">MStack_Top</span><span class="plain-syntax"> + </span><span class="identifier-syntax">MAX_MSTACK_FRAME</span><span class="plain-syntax"> >= </span><span class="identifier-syntax">MSTACK_SIZE</span><span class="plain-syntax"> + </span><span class="constant-syntax">2</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">RunTimeProblem</span><span class="plain-syntax">(</span><span class="identifier-syntax">RTP_MSTACKMEMORY</span><span class="plain-syntax">, </span><span class="identifier-syntax">MSTACK_SIZE</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Mstack_Backtrace</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">MStack_Top</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">MStack</span><span class="plain-syntax">--></span><span class="identifier-syntax">MStack_Top</span><span class="plain-syntax"> = </span><span class="identifier-syntax">id</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">MStack_Top</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">MStack_Top</span><span class="plain-syntax"> = </span><span class="identifier-syntax">MStack_Top</span><span class="plain-syntax"> + </span><span class="identifier-syntax">extent</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">MStack</span><span class="plain-syntax">--></span><span class="identifier-syntax">MStack_Top</span><span class="plain-syntax"> = -(</span><span class="identifier-syntax">extent</span><span class="plain-syntax">+2);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">rtrue</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">];</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>§3. Destroy Frame. </b>As sketched above, the same creator function and ID number are passed to
|
|
the following routine to destroy the frame again. It takes the stack down
|
|
to the level of the most recently created frame with this ID number: note
|
|
that each action, for instance, has its own ID number for this purpose,
|
|
but can be taking place several times in a nested fashion — one taking
|
|
action might have caused another taking action which caused a third,
|
|
for instance, so that there are three incomplete taking actions at once.
|
|
In that case, there will be three independent sets of taking action
|
|
variables on the M-stack, all with the same ID number. We remove the
|
|
topmost one: the implication of that is that frames must always be
|
|
destroyed in reverse order of creation.
|
|
</p>
|
|
|
|
<p class="commentary">In practice, I7 uses frames such that the frame sought should always be
|
|
the topmost one in any case, and so that frames are always explicitly
|
|
destroyed, not wiped by being undercut when an earlier-created frame
|
|
is destroyed.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">Mstack_Destroy_Frame</span><span class="plain-syntax"> </span><span class="identifier-syntax">creator</span><span class="plain-syntax"> </span><span class="identifier-syntax">id</span><span class="plain-syntax"> </span><span class="identifier-syntax">pos</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Mstack_Seek_Frame</span><span class="plain-syntax">(</span><span class="identifier-syntax">id</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">pos</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">; </span><span class="comment-syntax">Not found: do nothing</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">MStack_Top</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> - </span><span class="constant-syntax">2</span><span class="plain-syntax">; </span><span class="comment-syntax">Clear mstack down to just below this frame</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">creator</span><span class="plain-syntax">) </span><span class="identifier-syntax">creator</span><span class="plain-syntax">.</span><span class="identifier-syntax">call</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, -1);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">rtrue</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. Seek Frame. </b>We return the position on the M-stack of the most recently created frame
|
|
with the given ID number (see above), or 0 if no such frame exists; the
|
|
size is stored in the global variable <span class="extract"><span class="extract-syntax">MStack_Frame_Extent</span></span>. (Because word 0
|
|
on the stack is used as a sentinel — all frames are placed above it — no frame
|
|
can actually begin at word 0 on the stack, so 0 is safe to use as an exception.)
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="identifier-syntax">Global</span><span class="plain-syntax"> </span><span class="identifier-syntax">MStack_Frame_Extent</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">Mstack_Seek_Frame</span><span class="plain-syntax"> </span><span class="identifier-syntax">id</span><span class="plain-syntax"> </span><span class="identifier-syntax">pos</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> = </span><span class="identifier-syntax">MStack_Top</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">pos</span><span class="plain-syntax"> > </span><span class="constant-syntax">0</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">MStack</span><span class="plain-syntax">--></span><span class="identifier-syntax">pos</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">MStack_Frame_Extent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">MStack</span><span class="plain-syntax">--></span><span class="identifier-syntax">pos</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> + </span><span class="identifier-syntax">MStack_Frame_Extent</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">MStack_Frame_Extent</span><span class="plain-syntax"> = (-2) - </span><span class="identifier-syntax">MStack_Frame_Extent</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">MStack</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">+1) == </span><span class="identifier-syntax">id</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">pos</span><span class="plain-syntax">+2;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">MStack_Frame_Extent</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax">Not found</span>
|
|
<span class="plain-syntax">];</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>§5. Backtrace. </b>Purely for debugging purposes, and giving feedback if the stack runs out of
|
|
memory:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">Mstack_Backtrace</span><span class="plain-syntax"> </span><span class="identifier-syntax">pos</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">print</span><span class="plain-syntax"> </span><span class="string-syntax">"Mstack backtrace: size "</span><span class="plain-syntax">, </span><span class="identifier-syntax">MStack_Top</span><span class="plain-syntax">+1, </span><span class="string-syntax">" words^"</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> = </span><span class="identifier-syntax">MStack_Top</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">MStack</span><span class="plain-syntax">--></span><span class="identifier-syntax">pos</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">MStack_Frame_Extent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">MStack</span><span class="plain-syntax">--></span><span class="identifier-syntax">pos</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> + </span><span class="identifier-syntax">MStack_Frame_Extent</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">MStack_Frame_Extent</span><span class="plain-syntax"> = (-2) - </span><span class="identifier-syntax">MStack_Frame_Extent</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"Block at "</span><span class="plain-syntax">, </span><span class="identifier-syntax">pos</span><span class="plain-syntax">+2,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">" owner ID "</span><span class="plain-syntax">, </span><span class="identifier-syntax">MStack</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">+1), </span><span class="string-syntax">" size "</span><span class="plain-syntax">, </span><span class="identifier-syntax">MStack_Frame_Extent</span><span class="plain-syntax">, </span><span class="string-syntax">"^"</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">k</span><span class="plain-syntax">=0: </span><span class="identifier-syntax">k</span><span class="plain-syntax"><</span><span class="identifier-syntax">MStack_Frame_Extent</span><span class="plain-syntax">: </span><span class="identifier-syntax">k</span><span class="plain-syntax">++) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="identifier-syntax">MStack</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">+2+</span><span class="identifier-syntax">k</span><span class="plain-syntax">), </span><span class="string-syntax">" "</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"^"</span><span class="plain-syntax">;</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. Access to Variables. </b>An M-stack variable is identified by a combination of ID number and offset:
|
|
for instance ID 20007, offset 1, is the variable "room gone to" belonging
|
|
to the going action. The following routine converts that into an address on
|
|
the M-stack, in the topmost block with the given ID number (since "room gone
|
|
to", for instance, always means its value in the most current going action
|
|
of those now under way). Typechecking in the compiler should mean that it is
|
|
impossible to produce either error message below: Inform will only compile valid
|
|
uses of <span class="extract"><span class="extract-syntax">MstVO</span></span> ("M-stack variable offset") where the seek succeeds and
|
|
the offset is within range.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">MstVO</span><span class="plain-syntax"> </span><span class="identifier-syntax">id</span><span class="plain-syntax"> </span><span class="identifier-syntax">off</span><span class="plain-syntax"> </span><span class="identifier-syntax">pos</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Mstack_Seek_Frame</span><span class="plain-syntax">(</span><span class="identifier-syntax">id</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">pos</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"Variable unavailable for this action, activity or rulebook: "</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"internal ID number "</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">id</span><span class="plain-syntax">, </span><span class="string-syntax">"/"</span><span class="plain-syntax">, </span><span class="identifier-syntax">off</span><span class="plain-syntax">, </span><span class="string-syntax">"^"</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">off</span><span class="plain-syntax"><0) || (</span><span class="identifier-syntax">off</span><span class="plain-syntax"> >= </span><span class="identifier-syntax">MStack_Frame_Extent</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"Variable stack offset wrong: "</span><span class="plain-syntax">, </span><span class="identifier-syntax">id</span><span class="plain-syntax">, </span><span class="string-syntax">"/"</span><span class="plain-syntax">, </span><span class="identifier-syntax">off</span><span class="plain-syntax">, </span><span class="string-syntax">" at "</span><span class="plain-syntax">, </span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="string-syntax">"^"</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">rfalse</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">pos</span><span class="plain-syntax">+</span><span class="identifier-syntax">off</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">];</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>§7. Access to Nonexistent Variables. </b>A long-standing point where I7 is not as strict in type-checking as it might
|
|
be occurs when checking rule preambles like "Before going to a dead end...".
|
|
Such a preamble must be checked whatever the current action is — in many
|
|
cases, it will not be a going action at all; which means that "room gone to",
|
|
a value implied by the "to" clause, will not exist. If the type-checking
|
|
were stricter, it would be a nuisance for authors, and instead we relax a
|
|
little by accessing such variables using a more forgiving routine. Here,
|
|
if a variable does not exist, we return 0 to mean that it can be read at
|
|
M-stack position 0: this is the sentinel word, which is not part of any
|
|
frame, and which contains 0. Thus the variable reads as if it is 0, the
|
|
default for the kind of value "object", which is the KOV for action
|
|
variables such as "room gone to".
|
|
</p>
|
|
|
|
<p class="commentary">The routine may only be used where the variable is being read, and never
|
|
where it is to be written, of course: that would corrupt the sentinel.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">MstVON</span><span class="plain-syntax"> </span><span class="identifier-syntax">id</span><span class="plain-syntax"> </span><span class="identifier-syntax">off</span><span class="plain-syntax"> </span><span class="identifier-syntax">pos</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Mstack_Seek_Frame</span><span class="plain-syntax">(</span><span class="identifier-syntax">id</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">pos</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax">word position 0 on the M-stack</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">off</span><span class="plain-syntax"><0) || (</span><span class="identifier-syntax">off</span><span class="plain-syntax"> >= </span><span class="identifier-syntax">MStack_Frame_Extent</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"Variable stack offset wrong: "</span><span class="plain-syntax">, </span><span class="identifier-syntax">id</span><span class="plain-syntax">, </span><span class="string-syntax">"/"</span><span class="plain-syntax">, </span><span class="identifier-syntax">off</span><span class="plain-syntax">, </span><span class="string-syntax">" at "</span><span class="plain-syntax">, </span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="string-syntax">"^"</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">rfalse</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">pos</span><span class="plain-syntax">+</span><span class="identifier-syntax">off</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. Rulebook Variables. </b>Each rulebook has a slate of variables, usually empty, with ID number the
|
|
same as the rulebook's own ID number. (Rulebook IDs number upwards from 0
|
|
in order of creation in the source text.) The associated creator functions,
|
|
usually null, are stored in an array if there is no problem about memory
|
|
usage, but with a switch statement if <span class="extract"><span class="extract-syntax">MEMORY_ECONOMY</span></span> is in force; this
|
|
costs a very small amount of time, but saves 1K of readable memory.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">MStack_CreateRBVars</span><span class="plain-syntax"> </span><span class="identifier-syntax">rb</span><span class="plain-syntax"> </span><span class="identifier-syntax">cr</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">MEMORY_ECONOMY</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">cr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">MStack_GetRBVarCreator</span><span class="plain-syntax">(</span><span class="identifier-syntax">rb</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifnot</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">cr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rulebook_var_creators</span><span class="plain-syntax">--></span><span class="identifier-syntax">rb</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</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">cr</span><span class="plain-syntax">) </span><span class="identifier-syntax">Mstack_Create_Frame</span><span class="plain-syntax">(</span><span class="identifier-syntax">cr</span><span class="plain-syntax">, </span><span class="identifier-syntax">rb</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">];</span>
|
|
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">MStack_DestroyRBVars</span><span class="plain-syntax"> </span><span class="identifier-syntax">rb</span><span class="plain-syntax"> </span><span class="identifier-syntax">cr</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">MEMORY_ECONOMY</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">cr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">MStack_GetRBVarCreator</span><span class="plain-syntax">(</span><span class="identifier-syntax">rb</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifnot</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">cr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rulebook_var_creators</span><span class="plain-syntax">--></span><span class="identifier-syntax">rb</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</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">cr</span><span class="plain-syntax">) </span><span class="identifier-syntax">Mstack_Destroy_Frame</span><span class="plain-syntax">(</span><span class="identifier-syntax">cr</span><span class="plain-syntax">, </span><span class="identifier-syntax">rb</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. Activity Variables. </b>Exactly the same goes for activity variables except that here the ID number
|
|
is \(10000+N\), where \(N\) is the allocation ID of the activity. (This would
|
|
fail if there were more than 10,000 rulebooks, but this is very difficult
|
|
to see happening.)
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">MStack_CreateAVVars</span><span class="plain-syntax"> </span><span class="identifier-syntax">av</span><span class="plain-syntax"> </span><span class="identifier-syntax">cr</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">cr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">activity_var_creators</span><span class="plain-syntax">--></span><span class="identifier-syntax">av</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">cr</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Mstack_Create_Frame</span><span class="plain-syntax">(</span><span class="identifier-syntax">cr</span><span class="plain-syntax">, </span><span class="identifier-syntax">av</span><span class="plain-syntax"> + </span><span class="constant-syntax">10000</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">];</span>
|
|
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">MStack_DestroyAVVars</span><span class="plain-syntax"> </span><span class="identifier-syntax">av</span><span class="plain-syntax"> </span><span class="identifier-syntax">cr</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">cr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">activity_var_creators</span><span class="plain-syntax">--></span><span class="identifier-syntax">av</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">cr</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Mstack_Destroy_Frame</span><span class="plain-syntax">(</span><span class="identifier-syntax">cr</span><span class="plain-syntax">, </span><span class="identifier-syntax">av</span><span class="plain-syntax"> + </span><span class="constant-syntax">10000</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="S-tbl.html">❮</a></li><li class="progresssection"><a href="S-dfn.html">dfn</a></li><li class="progresssection"><a href="S-utl.html">utl</a></li><li class="progresssection"><a href="S-gll.html">gll</a></li><li class="progresssection"><a href="S-zmc.html">zmc</a></li><li class="progresssection"><a href="S-prg.html">prg</a></li><li class="progresssection"><a href="S-mth.html">mth</a></li><li class="progresssection"><a href="S-fl.html">fl</a></li><li class="progresssection"><a href="S-srt.html">srt</a></li><li class="progresssection"><a href="S-tbl.html">tbl</a></li><li class="progresscurrent">mst</li><li class="progresssection"><a href="S-rlb.html">rlb</a></li><li class="progresssection"><a href="S-flx.html">flx</a></li><li class="progresssection"><a href="S-blc.html">blc</a></li><li class="progresssection"><a href="S-txt.html">txt</a></li><li class="progresssection"><a href="S-unc.html">unc</a></li><li class="progresssection"><a href="S-chr.html">chr</a></li><li class="progresssection"><a href="S-rgx.html">rgx</a></li><li class="progresssection"><a href="S-lst.html">lst</a></li><li class="progresssection"><a href="S-cmb.html">cmb</a></li><li class="progresssection"><a href="S-rlt.html">rlt</a></li><li class="progresssection"><a href="S-rlt2.html">rlt2</a></li><li class="progresssection"><a href="S-rtp.html">rtp</a></li><li class="progressnext"><a href="S-rlb.html">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|