mirror of
https://github.com/ganelson/inform.git
synced 2024-07-16 22:14:23 +03:00
732 lines
138 KiB
HTML
732 lines
138 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>Programs 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">
|
|
<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 'Programs 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">DialogueKit</a></li><li><b>Programs Template</b></li></ul></div>
|
|
<p class="purpose">How dialogue beat programs are stored and interpreted.</p>
|
|
|
|
<ul class="toc"><li><a href="S-prg.html#SP1">§1. D-code</a></li><li><a href="S-prg.html#SP2">§2. Containment</a></li><li><a href="S-prg.html#SP3">§3. Disassembly</a></li><li><a href="S-prg.html#SP4">§4. The D-stack</a></li><li><a href="S-prg.html#SP5">§5. Reading the current choice list</a></li><li><a href="S-prg.html#SP6">§6. Tracing the stack</a></li><li><a href="S-prg.html#SP7">§7. Pushing and popping</a></li><li><a href="S-prg.html#SP8">§8. Flow operations</a></li><li><a href="S-prg.html#SP9">§9. Main interpreter loop</a></li><li><a href="S-prg.html#SP10">§10. The line instruction</a></li><li><a href="S-prg.html#SP11">§11. The decision instruction</a></li><li><a href="S-prg.html#SP12">§12. Listing choices for a decision</a></li><li><a href="S-prg.html#SP13">§13. Dealing with action choices</a></li><li><a href="S-prg.html#SP14">§14. Exercising a choice</a></li><li><a href="S-prg.html#SP15">§15. Numerical choice at the keyboard</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§1. D-code. </b>Each dialogue beat contains a program which lays out the structure of its lines
|
|
and choices. This program is stored in a simple bytecode which we'll call "D-code",
|
|
for the sake of giving it a name, though it is very rudimentary and would not
|
|
even be Turing-complete except for the ability to apply conditions and state
|
|
changes by "now" and "if" side-effects.
|
|
</p>
|
|
|
|
<p class="commentary">A program consists of a sequence of 0 or more two-word instructions terminated
|
|
by the word 0. Each instruction has an opcode word followed by an operand word.
|
|
The opcode word is encoded as <span class="extract"><span class="extract-syntax">100*I + D</span></span>, where <span class="extract"><span class="extract-syntax">I</span></span> is an instruction code
|
|
ranging from 1 upwards, and <span class="extract"><span class="extract-syntax">D</span></span> is the depth within the dialogue tree, ranging
|
|
from 0 upwards. Finding 0 in the opcode word position therefore unambiguously
|
|
marks the end, since <span class="extract"><span class="extract-syntax">I</span></span> cannot be 0 even though <span class="extract"><span class="extract-syntax">D</span></span> can.
|
|
</p>
|
|
|
|
<p class="commentary">Depth levels correspond to the tree structure in the original dialogue. This
|
|
is not quite the same as the number of tab stops in the source code because
|
|
Inform regroups choice nodes under decision nodes (one for each decision to
|
|
be taken), which are implicit in the source text, and therefore don't appear
|
|
in the tab indentation. This effectively pushes all choice nodes out by 1
|
|
in depth, compared to the tab indentation level, each time a nested decision
|
|
is reached.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="extract"><span class="extract-syntax">D</span></span> begins at 0, is never negative, and is never more than 1 greater than the
|
|
previous instruction. The Inform compiler never generates <span class="extract"><span class="extract-syntax">D</span></span> values greater
|
|
than about 25 (see <a href="../if-module/6-dn.html" class="internal">Dialogue Nodes (in if)</a>), so there is no danger of <span class="extract"><span class="extract-syntax">D</span></span>
|
|
reaching 100 and corrupting the <span class="extract"><span class="extract-syntax">I</span></span> value.
|
|
</p>
|
|
|
|
<p class="commentary">There are only three instruction codes:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="extract"><span class="extract-syntax">LINE_DCODEI</span></span> means a dialogue line, and the operand then represents the
|
|
enumerated value for the dialogue line.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="extract"><span class="extract-syntax">CHOICE_DCODEI</span></span> similarly represents a choice. All such instructions are
|
|
immediate children of a <span class="extract"><span class="extract-syntax">DECISION_DCODEI</span></span> instruction.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="extract"><span class="extract-syntax">DECISION_DCODEI</span></span> is a decision point, and the operand is the "decision type",
|
|
one of the <span class="extract"><span class="extract-syntax">*_DCODEDT</span></span> values. All immediate children of a <span class="extract"><span class="extract-syntax">DECISION_DCODEI</span></span>
|
|
instruction are <span class="extract"><span class="extract-syntax">CHOICE_DCODEI</span></span>s.
|
|
</p>
|
|
|
|
<ul class="items"><li>● <span class="extract"><span class="extract-syntax">BLANK_DCODEDT</span></span> should never appear in compiled D-code, and is only used
|
|
in the Inform compiler.
|
|
</li><li>● <span class="extract"><span class="extract-syntax">TEXTUAL_DCODEDT</span></span> is a decision point offering textual choices for the
|
|
player to pick.
|
|
</li><li>● <span class="extract"><span class="extract-syntax">PARSED_COMMAND_DCODEDT</span></span> is a decision point requiring us to wait for the
|
|
next typed command and see what action it produced.
|
|
</li><li>● <span class="extract"><span class="extract-syntax">FLOW_DCODEDT</span></span> is a flow control choice, <span class="extract"><span class="extract-syntax">-></span></span> or <span class="extract"><span class="extract-syntax"><-</span></span>.
|
|
</li></ul>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">LINE_DCODEI</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">CHOICE_DCODEI</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">DECISION_DCODEI</span><span class="plain-syntax"> = </span><span class="constant-syntax">3</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">BLANK_DCODEDT</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">TEXTUAL_DCODEDT</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">PARSED_COMMAND_DCODEDT</span><span class="plain-syntax"> = </span><span class="constant-syntax">3</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">FLOW_DCODEDT</span><span class="plain-syntax"> = </span><span class="constant-syntax">4</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>§2. Containment. </b>This enables us to implement the test for whether a given line or choice
|
|
occurs in a beat, because we need only look to see whether it occurs as
|
|
operand in the instructions for the beat's program.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorTestContainment(dl, db, DIALOGUE_LINE_TY, DIALOGUE_BEAT_TY)</span></span> tests
|
|
whether the line <span class="extract"><span class="extract-syntax">dl</span></span> occurs in the beat <span class="extract"><span class="extract-syntax">db</span></span>, returning <span class="extract"><span class="extract-syntax">true</span></span> or <span class="extract"><span class="extract-syntax">false</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorTestContainment(dc, db, DIALOGUE_CHOICE_TY, DIALOGUE_BEAT_TY)</span></span> tests
|
|
whether the choice <span class="extract"><span class="extract-syntax">dc</span></span> occurs in the beat <span class="extract"><span class="extract-syntax">db</span></span>, returning <span class="extract"><span class="extract-syntax">true</span></span> or <span class="extract"><span class="extract-syntax">false</span></span>.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorTestContainment</span><span class="plain-syntax"> </span><span class="identifier-syntax">X</span><span class="plain-syntax"> </span><span class="identifier-syntax">db</span><span class="plain-syntax"> </span><span class="identifier-syntax">tX</span><span class="plain-syntax"> </span><span class="identifier-syntax">tb</span><span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> </span><span class="identifier-syntax">instruction</span><span class="plain-syntax"> </span><span class="identifier-syntax">wanted</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">tb</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">DIALOGUE_BEAT_TY</span><span class="plain-syntax">) { </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"*** Not a db ***"</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">tX</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">DIALOGUE_LINE_TY</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="identifier-syntax">DIALOGUE_CHOICE_TY</span><span class="plain-syntax">) { </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"*** Not a dl/dc ***"</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">db</span><span class="plain-syntax"> < </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">db</span><span class="plain-syntax"> > </span><span class="identifier-syntax">NO_DIALOGUE_BEATS</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">tX</span><span class="plain-syntax"> == </span><span class="identifier-syntax">DIALOGUE_LINE_TY</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">X</span><span class="plain-syntax"> < </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">X</span><span class="plain-syntax"> > </span><span class="identifier-syntax">NO_DIALOGUE_LINES</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">wanted</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LINE_DCODEI</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">X</span><span class="plain-syntax"> < </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">X</span><span class="plain-syntax"> > </span><span class="identifier-syntax">NO_DIALOGUE_CHOICES</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">wanted</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CHOICE_DCODEI</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorBeatGetProgram</span><span class="plain-syntax">(</span><span class="identifier-syntax">db</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pc</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">instruction</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--></span><span class="identifier-syntax">pc</span><span class="plain-syntax">)/100;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">instruction</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">instruction</span><span class="plain-syntax"> == </span><span class="identifier-syntax">wanted</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">program</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">pc</span><span class="plain-syntax">+1) == </span><span class="identifier-syntax">X</span><span class="plain-syntax">)) </span><span class="reserved-syntax">rtrue</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</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">instruction</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--></span><span class="identifier-syntax">pc</span><span class="plain-syntax">)/100;</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">DirectorBeatOpeningLine</span><span class="plain-syntax"> </span><span class="identifier-syntax">db</span><span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> </span><span class="identifier-syntax">instruction</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">db</span><span class="plain-syntax"> <= </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">db</span><span class="plain-syntax"> > </span><span class="identifier-syntax">NO_DIALOGUE_BEATS</span><span class="plain-syntax">)) </span><span class="string-syntax">"*** no beat ***"</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorBeatGetProgram</span><span class="plain-syntax">(</span><span class="identifier-syntax">db</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pc</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">instruction</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--></span><span class="identifier-syntax">pc</span><span class="plain-syntax">)/100;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">instruction</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">instruction</span><span class="plain-syntax"> == </span><span class="identifier-syntax">LINE_DCODEI</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">pc</span><span class="plain-syntax">+1);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</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">instruction</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--></span><span class="identifier-syntax">pc</span><span class="plain-syntax">)/100;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"*** no line ***"</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. Disassembly. </b>Purely for debugging purposes:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorDisassemble</span><span class="plain-syntax"> </span><span class="identifier-syntax">db</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> </span><span class="identifier-syntax">which</span><span class="plain-syntax"> </span><span class="identifier-syntax">depth</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax"> </span><span class="identifier-syntax">operand</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">db</span><span class="plain-syntax"> <= </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">db</span><span class="plain-syntax"> > </span><span class="identifier-syntax">NO_DIALOGUE_BEATS</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PrintDialogueBeatName</span><span class="plain-syntax">) </span><span class="identifier-syntax">db</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DirectorBeatAvailable</span><span class="plain-syntax">(</span><span class="identifier-syntax">db</span><span class="plain-syntax">)) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"available"</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"unavailable"</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DirectorBeatRelevant</span><span class="plain-syntax">(</span><span class="identifier-syntax">db</span><span class="plain-syntax">)) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"relevant"</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"irrelevant"</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DirectorBeatAccessible</span><span class="plain-syntax">(</span><span class="identifier-syntax">db</span><span class="plain-syntax">, </span><span class="identifier-syntax">player</span><span class="plain-syntax">)) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"accessible"</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"inaccessible"</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">GProperty</span><span class="plain-syntax">(</span><span class="identifier-syntax">DIALOGUE_BEAT_TY</span><span class="plain-syntax">, </span><span class="identifier-syntax">db</span><span class="plain-syntax">, </span><span class="identifier-syntax">performed</span><span class="plain-syntax">)) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"performed"</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"unperformed"</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">GProperty</span><span class="plain-syntax">(</span><span class="identifier-syntax">DIALOGUE_BEAT_TY</span><span class="plain-syntax">, </span><span class="identifier-syntax">db</span><span class="plain-syntax">, </span><span class="identifier-syntax">recurring</span><span class="plain-syntax">)) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"recurring"</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"non-recurring"</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">GProperty</span><span class="plain-syntax">(</span><span class="identifier-syntax">DIALOGUE_BEAT_TY</span><span class="plain-syntax">, </span><span class="identifier-syntax">db</span><span class="plain-syntax">, </span><span class="identifier-syntax">spontaneous</span><span class="plain-syntax">)) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"spontaneous"</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"unspontaneous"</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="identifier-syntax">program</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorBeatGetProgram</span><span class="plain-syntax">(</span><span class="identifier-syntax">db</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">program</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pc</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">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--></span><span class="identifier-syntax">pc</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">which</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--></span><span class="identifier-syntax">pc</span><span class="plain-syntax">)/100;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">depth</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--></span><span class="identifier-syntax">pc</span><span class="plain-syntax">)%100;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">operand</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">pc</span><span class="plain-syntax">+1));</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0: </span><span class="identifier-syntax">i</span><span class="plain-syntax"><</span><span class="identifier-syntax">depth</span><span class="plain-syntax">: </span><span class="identifier-syntax">i</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="identifier-syntax">DirectorDisassembleInstruction</span><span class="plain-syntax">(</span><span class="identifier-syntax">which</span><span class="plain-syntax">, </span><span class="identifier-syntax">operand</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> + </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">];</span>
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorDisassembleInstruction</span><span class="plain-syntax"> </span><span class="identifier-syntax">which</span><span class="plain-syntax"> </span><span class="identifier-syntax">operand</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">which</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LINE_DCODEI</span><span class="plain-syntax">: </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"LINE "</span><span class="plain-syntax">, (</span><span class="identifier-syntax">PrintDialogueLineName</span><span class="plain-syntax">) </span><span class="identifier-syntax">operand</span><span class="plain-syntax">, </span><span class="string-syntax">"^"</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">CHOICE_DCODEI</span><span class="plain-syntax">: </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"CHOICE "</span><span class="plain-syntax">, (</span><span class="identifier-syntax">PrintDialogueChoiceName</span><span class="plain-syntax">) </span><span class="identifier-syntax">operand</span><span class="plain-syntax">, </span><span class="string-syntax">"^"</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DECISION_DCODEI</span><span class="plain-syntax">: </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"DECISION of type "</span><span class="plain-syntax">, </span><span class="identifier-syntax">operand</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">default</span><span class="plain-syntax">: </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"*** Unimplemented ***^"</span><span class="plain-syntax">;</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. The D-stack. </b>The interpreter for D-code has to perform beats (and therefore their programs)
|
|
in a way which can easily nest, since one beat can call for another to be
|
|
performed and then continue. Moreover, it also sometimes calls itself to
|
|
interpret just a subtree from a full program. Either way, it needs to keep
|
|
its state on a stack so that it can safely interrupt what it's doing, call
|
|
itself, and then resume where it left off. The stack consists of a suite of
|
|
arrays, as follows:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorStackBeat</span></span> holds the beat whose program is being interpreted.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorStackPC</span></span> holds the current PC ("program counter"), which counts in
|
|
words from the start of the program, which is position 0. It therefore
|
|
increases by 2 to advance by one instruction.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorStackMin</span></span> holds the minimum instruction level for the subtree
|
|
being interpreted. If the whole tree is being interpreted, this is 0.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorStackStart</span></span> is a flag which is true if and only if the current
|
|
subtree was the entire tree, so that execution began from PC 0.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorStackDecisionPC</span></span> holds the PC position of the last instruction
|
|
node of <span class="extract"><span class="extract-syntax">DECISION_DCODEI</span></span> type, that is, the last decision; or -1 if no
|
|
decision node has been reached in this subtree yet.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorStackLastPC</span></span> holds the PC position before the most recent
|
|
instruction was executed, or 0 if none has yet been executed.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorStackChoices</span></span> holds a valid Inform list, which in turn holds the
|
|
set of choices in the current decision. If no decision has been reached in
|
|
the execution of the subtree, the list is empty.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorStackLastSpeaker</span></span> holds the identity of the last person/object to
|
|
be the speaker in a line which was actually performed (and note that not
|
|
all <span class="extract"><span class="extract-syntax">LINE_DCODEI</span></span> instructions result in a performance). It is <span class="extract"><span class="extract-syntax">nothing</span></span>
|
|
if no line has been performed in (this performance of) the current beat,
|
|
except perhaps for narration.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorStackLastInterlocutor</span></span> similarly holds the identity of the interlocutor
|
|
for that line. It is <span class="extract"><span class="extract-syntax">nothing</span></span> if no line has been performed in (this performance
|
|
of) the current beat, except perhaps for narration, or if the most recently
|
|
performed line had no interlocutor.
|
|
</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_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax"> = </span><span class="constant-syntax">20</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="identifier-syntax">Global</span><span class="plain-syntax"> </span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">Array</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax"> --> </span><span class="identifier-syntax">MAX_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">Array</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackPC</span><span class="plain-syntax"> --> </span><span class="identifier-syntax">MAX_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">Array</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackMin</span><span class="plain-syntax"> --> </span><span class="identifier-syntax">MAX_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">Array</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackStart</span><span class="plain-syntax"> --> </span><span class="identifier-syntax">MAX_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">Array</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackDecisionPC</span><span class="plain-syntax"> --> </span><span class="identifier-syntax">MAX_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">Array</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackLastPC</span><span class="plain-syntax"> --> </span><span class="identifier-syntax">MAX_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">Array</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax"> --> </span><span class="identifier-syntax">MAX_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">Array</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackLastSpeaker</span><span class="plain-syntax"> --> </span><span class="identifier-syntax">MAX_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">Array</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackLastInterlocutor</span><span class="plain-syntax"> --> </span><span class="identifier-syntax">MAX_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>§5. Reading the current choice list. </b>The stack begins empty, except that we arrange for there always to be a
|
|
valid Inform list in <span class="extract"><span class="extract-syntax">DirectorStackChoices-->0</span></span>, so that if the phrase
|
|
"current choice list" is used at a time when no dialogue has ever run, it will
|
|
still produce an empty list in a typesafe way.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorCurrentChoiceList</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</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">director_sp</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">-->0 == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">-->0 = </span><span class="identifier-syntax">BlkValueCreate</span><span class="plain-syntax">(</span><span class="identifier-syntax">LIST_OF_TY</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">BlkValueWrite</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">-->0, </span><span class="identifier-syntax">LIST_ITEM_KOV_F</span><span class="plain-syntax">, </span><span class="identifier-syntax">DIALOGUE_CHOICE_TY</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">DirectorStackChoices</span><span class="plain-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="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1);</span>
|
|
<span class="plain-syntax">];</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>§6. Tracing the stack. </b>For debugging only, of course.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorTraceStack</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> </span><span class="identifier-syntax">instruction</span><span class="plain-syntax"> </span><span class="identifier-syntax">depth</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">director_sp</span><span class="plain-syntax"> > </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="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="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax">=0: </span><span class="identifier-syntax">j</span><span class="plain-syntax"><</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">: </span><span class="identifier-syntax">j</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">j</span><span class="plain-syntax"> > </span><span class="constant-syntax">0</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DirectorStackStart</span><span class="plain-syntax">--></span><span class="identifier-syntax">j</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="reserved-syntax">print</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PrintDialogueBeatName</span><span class="plain-syntax">) </span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">--></span><span class="identifier-syntax">j</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorStackPC</span><span class="plain-syntax">--></span><span class="identifier-syntax">j</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">pc</span><span class="plain-syntax"> == -1) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"+return"</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="identifier-syntax">program</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorBeatGetProgram</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">--></span><span class="identifier-syntax">j</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">instruction</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--></span><span class="identifier-syntax">pc</span><span class="plain-syntax">)/100;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">depth</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--></span><span class="identifier-syntax">pc</span><span class="plain-syntax">)%100;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DirectorStackDecisionPC</span><span class="plain-syntax">--></span><span class="identifier-syntax">j</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">"[*"</span><span class="plain-syntax">, </span><span class="identifier-syntax">DirectorStackDecisionPC</span><span class="plain-syntax">--></span><span class="identifier-syntax">j</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="identifier-syntax">pc</span><span class="plain-syntax">, </span><span class="string-syntax">" "</span><span class="plain-syntax">, </span><span class="string-syntax">"L"</span><span class="plain-syntax">, </span><span class="identifier-syntax">depth</span><span class="plain-syntax">, </span><span class="string-syntax">"/"</span><span class="plain-syntax">, </span><span class="identifier-syntax">DirectorStackMin</span><span class="plain-syntax">--></span><span class="identifier-syntax">j</span><span class="plain-syntax">, </span><span class="string-syntax">" "</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorDisassembleInstruction</span><span class="plain-syntax">(</span><span class="identifier-syntax">instruction</span><span class="plain-syntax">, </span><span class="identifier-syntax">program</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">pc</span><span class="plain-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">LIST_OF_TY_GetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">--></span><span class="identifier-syntax">j</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">" {"</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LIST_OF_TY_Say</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">--></span><span class="identifier-syntax">j</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>
|
|
<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="reserved-syntax">else</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">"[Director stack empty]^"</span><span class="plain-syntax">;</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. Pushing and popping. </b>Two functions exist to create a new "subtree stack frame", pushing, or to destroy
|
|
an existing one, popping the stack.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorPush</span></span> must specify the beat, the minimum instruction level to
|
|
execute (by default 0), and the initial pc (position in the program) to execute
|
|
from (by default 0). Within such a subtree, the D-code interpreter will run
|
|
from the PC position until it hits an instruction of too low a level, or until
|
|
it hits the end of the program. Thus, it can execute either the entire
|
|
dialogue tree, or any well-formed subtree of it.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorPush</span><span class="plain-syntax"> </span><span class="identifier-syntax">db</span><span class="plain-syntax"> </span><span class="identifier-syntax">min</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> </span><span class="identifier-syntax">start_flag</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">director_sp</span><span class="plain-syntax"> >= </span><span class="identifier-syntax">MAX_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"*** Director stack overflow: too many open beats ***"</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">--></span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">db</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackDecisionPC</span><span class="plain-syntax">--></span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = -1;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackLastPC</span><span class="plain-syntax">--></span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackPC</span><span class="plain-syntax">--></span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackMin</span><span class="plain-syntax">--></span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">min</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">pc</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">DirectorStackStart</span><span class="plain-syntax">--></span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = </span><span class="reserved-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="identifier-syntax">DirectorStackStart</span><span class="plain-syntax">--></span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = </span><span class="reserved-syntax">false</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackLastSpeaker</span><span class="plain-syntax">--></span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = </span><span class="reserved-syntax">nothing</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackLastInterlocutor</span><span class="plain-syntax">--></span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = </span><span class="reserved-syntax">nothing</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">DirectorStackChoices</span><span class="plain-syntax">--></span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">--></span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BlkValueCreate</span><span class="plain-syntax">(</span><span class="identifier-syntax">LIST_OF_TY</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">BlkValueWrite</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">--></span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">, </span><span class="identifier-syntax">LIST_ITEM_KOV_F</span><span class="plain-syntax">, </span><span class="identifier-syntax">DIALOGUE_CHOICE_TY</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="identifier-syntax">LIST_OF_TY_SetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">--></span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">debug_dialogue</span><span class="plain-syntax"> >= </span><span class="constant-syntax">2</span><span class="plain-syntax">) { </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"-- Push to: "</span><span class="plain-syntax">; </span><span class="identifier-syntax">DirectorTraceStack</span><span class="plain-syntax">(); }</span>
|
|
<span class="plain-syntax">];</span>
|
|
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorPop</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">--;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">debug_dialogue</span><span class="plain-syntax"> >= </span><span class="constant-syntax">2</span><span class="plain-syntax">) { </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"-- Pop to: "</span><span class="plain-syntax">; </span><span class="identifier-syntax">DirectorTraceStack</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. Flow operations. </b><span class="extract"><span class="extract-syntax">DirectorAgain</span></span> implements the flow marker <span class="extract"><span class="extract-syntax"><-</span></span>; <span class="extract"><span class="extract-syntax">DirectorStop</span></span> implements <span class="extract"><span class="extract-syntax">-> stop</span></span>.
|
|
Both involve popping, either back to the last decision point (which means adjusting
|
|
the PC as well) or to the last time a new beat began.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorAgain</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">director_sp</span><span class="plain-syntax"> > </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">debug_dialogue</span><span class="plain-syntax"> >= </span><span class="constant-syntax">2</span><span class="plain-syntax">) { </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"-- again at: "</span><span class="plain-syntax">; </span><span class="identifier-syntax">DirectorTraceStack</span><span class="plain-syntax">(); }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorPop</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">DirectorStackDecisionPC</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1) >= </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackPC</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1) = </span><span class="identifier-syntax">DirectorStackDecisionPC</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">];</span>
|
|
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorStop</span><span class="plain-syntax"> </span><span class="identifier-syntax">enough</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">director_sp</span><span class="plain-syntax"> > </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">enough</span><span class="plain-syntax"> = </span><span class="reserved-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">DirectorStackStart</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1)) </span><span class="identifier-syntax">enough</span><span class="plain-syntax"> = </span><span class="reserved-syntax">true</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorPop</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">enough</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</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. Main interpreter loop. </b>Calling <span class="extract"><span class="extract-syntax">DirectorRun()</span></span> lets the interpreter rip, running until the end of the
|
|
current subtree, or some catastrophe happened, or we need to wait for the player
|
|
to enter a command into the command parser. (In the latter case we can resume
|
|
where we left off with just by calling <span class="extract"><span class="extract-syntax">DirectorRun()</span></span> again.)
|
|
</p>
|
|
|
|
<p class="commentary">Note that this loop should never hit a <span class="extract"><span class="extract-syntax">CHOICE_DCODEI</span></span> instruction, because
|
|
those are always underneath <span class="extract"><span class="extract-syntax">DECISION_DCODEI</span></span> instructions — which it does hit.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorRun</span><span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> </span><span class="identifier-syntax">last_pc</span><span class="plain-syntax"> </span><span class="identifier-syntax">instruction</span><span class="plain-syntax"> </span><span class="identifier-syntax">operand</span><span class="plain-syntax"> </span><span class="identifier-syntax">depth</span><span class="plain-syntax"> </span><span class="identifier-syntax">next_instruction</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="reserved-syntax">true</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax">There must be a program</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">director_sp</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="comment-syntax">The story must not have finished</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">deadflag</span><span class="plain-syntax">) { </span><span class="identifier-syntax">director_sp</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="comment-syntax">If there are choices to be made, we have to wait for the command</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax">input loop and some sort of action to be generated, so return for now</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">LIST_OF_TY_GetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1)) > </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="comment-syntax">If the beat is tied to a scene and the scene has itself finished for</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax">unrelated reasons, end the beat now</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorBeatGetScene</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1));</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">sc</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">scene_status</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">sc</span><span class="plain-syntax"> - </span><span class="constant-syntax">1</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">)) { </span><span class="identifier-syntax">DirectorStop</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">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorStackPC</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pc</span><span class="plain-syntax"> == -1) { </span><span class="identifier-syntax">DirectorPop</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">last_pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackLastPC</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1) = </span><span class="identifier-syntax">last_pc</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="comment-syntax">Fetch and decode the next instruction</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorBeatGetProgram</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">instruction</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--></span><span class="identifier-syntax">pc</span><span class="plain-syntax">)/100;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">depth</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--></span><span class="identifier-syntax">pc</span><span class="plain-syntax">)%100;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">operand</span><span class="plain-syntax"> = </span><span class="identifier-syntax">program</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">pc</span><span class="plain-syntax">+1);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">instruction</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">DirectorPop</span><span class="plain-syntax">(); </span><span class="reserved-syntax">return</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">depth</span><span class="plain-syntax"> < </span><span class="identifier-syntax">DirectorStackMin</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1)) { </span><span class="identifier-syntax">DirectorPop</span><span class="plain-syntax">(); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="comment-syntax">Advance the PC to the next instruction to be read after this one, or</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax">to -1 if there is no next instruction in the current subtree</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> + </span><span class="constant-syntax">2</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">program</span><span class="plain-syntax">--></span><span class="identifier-syntax">pc</span><span class="plain-syntax">)%100 > </span><span class="identifier-syntax">depth</span><span class="plain-syntax">) </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> + </span><span class="constant-syntax">2</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">program</span><span class="plain-syntax">--></span><span class="identifier-syntax">pc</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = -1;</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">program</span><span class="plain-syntax">--></span><span class="identifier-syntax">pc</span><span class="plain-syntax">)%100) < </span><span class="identifier-syntax">DirectorStackMin</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1)) </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = -1;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">debug_dialogue</span><span class="plain-syntax"> >= </span><span class="constant-syntax">2</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">"-- Instruction ("</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">pc</span><span class="plain-syntax"> >= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"next is "</span><span class="plain-syntax">, </span><span class="identifier-syntax">pc</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"last"</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="identifier-syntax">DirectorTraceStack</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> }</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="comment-syntax">Store the next PC position</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackPC</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1) = </span><span class="identifier-syntax">pc</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">instruction</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LINE_DCODEI</span><span class="plain-syntax">:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">line_performance_count</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorExecuteLine</span><span class="plain-syntax">(</span><span class="identifier-syntax">operand</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DECISION_DCODEI</span><span class="plain-syntax">:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackDecisionPC</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1) = </span><span class="identifier-syntax">last_pc</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorExecuteDecision</span><span class="plain-syntax">(</span><span class="identifier-syntax">operand</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">CHOICE_DCODEI</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">"*** Encountered CHOICE_DCODEI ***^"</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">default</span><span class="plain-syntax">: </span><span class="string-syntax">"*** Bad D-code instruction ***"</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">];</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>§10. The line instruction. </b>This tries to perform the given line, and if it succeeds, then executes the
|
|
subtree beneath it; the first node of which will be the next instruction in
|
|
the program if and only if that has depth greater by 1 than the current node.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorExecuteLine</span><span class="plain-syntax"> </span><span class="identifier-syntax">dl</span><span class="plain-syntax"> </span><span class="identifier-syntax">last_pc</span><span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax"> </span><span class="identifier-syntax">depth</span><span class="plain-syntax"> </span><span class="identifier-syntax">next_instruction</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">director_sp</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">last_pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorStackLastPC</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorBeatGetProgram</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">depth</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--></span><span class="identifier-syntax">last_pc</span><span class="plain-syntax">)%100;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DirectorPerformLine</span><span class="plain-syntax">(</span><span class="identifier-syntax">dl</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">next_instruction</span><span class="plain-syntax"> = </span><span class="identifier-syntax">program</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">last_pc</span><span class="plain-syntax">+2);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">next_instruction</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">next_instruction</span><span class="plain-syntax"> % </span><span class="constant-syntax">100</span><span class="plain-syntax"> == </span><span class="identifier-syntax">depth</span><span class="plain-syntax">+1)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorPush</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1), </span><span class="identifier-syntax">depth</span><span class="plain-syntax">+1, </span><span class="identifier-syntax">last_pc</span><span class="plain-syntax">+2);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorRun</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">rtrue</span><span class="plain-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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>§11. The decision instruction. </b>The immediate children of the instruction will all be choice instructions, and
|
|
the first task is to obtain them. If there are none, there's nothing to decide
|
|
and we silently return.
|
|
</p>
|
|
|
|
<p class="commentary">We deal with <span class="extract"><span class="extract-syntax">TEXTUAL_DCODEDT</span></span> and <span class="extract"><span class="extract-syntax">FLOW_DCODEDT</span></span> decisions immediately, and
|
|
empty the choices list as soon as we can. Perhaps surprisingly, we do nothing
|
|
at all about a <span class="extract"><span class="extract-syntax">PARSED_COMMAND_DCODEDT</span></span>. This function call nevertheless has
|
|
an effect because it leaves the choices list on the stack, where it will cause
|
|
the D-code interpreter to halt waiting for a command, to be re-entered later
|
|
on when actions are processed.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorExecuteDecision</span><span class="plain-syntax"> </span><span class="identifier-syntax">decision</span><span class="plain-syntax"> </span><span class="identifier-syntax">dc</span><span class="plain-syntax"> </span><span class="identifier-syntax">count</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax"> </span><span class="identifier-syntax">spc</span><span class="plain-syntax"> </span><span class="identifier-syntax">list</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">director_sp</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">list</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorListChoices</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">count</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LIST_OF_TY_GetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</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">debug_dialogue</span><span class="plain-syntax"> >= </span><span class="constant-syntax">2</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">count</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">"-- no available options^"</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">decision</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="constant-syntax">3</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">"-- available options: "</span><span class="plain-syntax">; </span><span class="identifier-syntax">LIST_OF_TY_Say</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</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>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">count</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="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">decision</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEXTUAL_DCODEDT</span><span class="plain-syntax">:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DivideParagraphPoint</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">OFFERING_A_DIALOGUE_CHOICE</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="string-syntax">"*** no activity ***"</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="identifier-syntax">BeginActivity</span><span class="plain-syntax">(</span><span class="identifier-syntax">OFFERING_A_DIALOGUE_CHOICE</span><span class="plain-syntax">, </span><span class="identifier-syntax">list</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">ForActivity</span><span class="plain-syntax">(</span><span class="identifier-syntax">OFFERING_A_DIALOGUE_CHOICE</span><span class="plain-syntax">, </span><span class="identifier-syntax">list</span><span class="plain-syntax">)) &&</span>
|
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">RulebookFailed</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">EndActivity</span><span class="plain-syntax">(</span><span class="identifier-syntax">OFFERING_A_DIALOGUE_CHOICE</span><span class="plain-syntax">, </span><span class="identifier-syntax">list</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DivideParagraphPoint</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorPickANumber</span><span class="plain-syntax">(</span><span class="identifier-syntax">count</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">dc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LIST_OF_TY_GetItem</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="identifier-syntax">n</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LIST_OF_TY_SetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</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">style</span><span class="plain-syntax"> </span><span class="identifier-syntax">bold</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEXT_TY_Say</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorChoiceRawContent</span><span class="plain-syntax">(</span><span class="identifier-syntax">dc</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">style</span><span class="plain-syntax"> </span><span class="identifier-syntax">roman</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="identifier-syntax">say__p</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DivideParagraphPoint</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorExerciseChoice</span><span class="plain-syntax">(</span><span class="identifier-syntax">dc</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PARSED_COMMAND_DCODEDT</span><span class="plain-syntax">:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">FLOW_DCODEDT</span><span class="plain-syntax">:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">dc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LIST_OF_TY_GetItem</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LIST_OF_TY_SetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</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">DirectorFollowFlowMarker</span><span class="plain-syntax">(</span><span class="identifier-syntax">dc</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">default</span><span class="plain-syntax">: </span><span class="string-syntax">"*** unimplemented dtd ***"</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">];</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>§12. Listing choices for a decision. </b>This finds all of the unperformed or recurring choices which are currently
|
|
available to a given decision node, making them the content of an Inform list.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorListChoices</span><span class="plain-syntax"> </span><span class="identifier-syntax">list</span><span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax"> </span><span class="identifier-syntax">depth</span><span class="plain-syntax"> </span><span class="identifier-syntax">dc</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> </span><span class="identifier-syntax">fn</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LIST_OF_TY_SetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</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">program</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorBeatGetProgram</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorStackLastPC</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">depth</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--></span><span class="identifier-syntax">pc</span><span class="plain-syntax">)%100;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> + </span><span class="constant-syntax">2</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">program</span><span class="plain-syntax">--></span><span class="identifier-syntax">pc</span><span class="plain-syntax">)%100 > </span><span class="identifier-syntax">depth</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">program</span><span class="plain-syntax">--></span><span class="identifier-syntax">pc</span><span class="plain-syntax">)%100 == </span><span class="identifier-syntax">depth</span><span class="plain-syntax">+1) && ((</span><span class="identifier-syntax">program</span><span class="plain-syntax">--></span><span class="identifier-syntax">pc</span><span class="plain-syntax">)/100 == </span><span class="identifier-syntax">CHOICE_DCODEI</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">dc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">program</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">pc</span><span class="plain-syntax">+1);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">GProperty</span><span class="plain-syntax">(</span><span class="identifier-syntax">DIALOGUE_CHOICE_TY</span><span class="plain-syntax">, </span><span class="identifier-syntax">dc</span><span class="plain-syntax">, </span><span class="identifier-syntax">performed</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">GProperty</span><span class="plain-syntax">(</span><span class="identifier-syntax">DIALOGUE_CHOICE_TY</span><span class="plain-syntax">, </span><span class="identifier-syntax">dc</span><span class="plain-syntax">, </span><span class="identifier-syntax">recurring</span><span class="plain-syntax">))) &&</span>
|
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">DirectorChoiceAvailable</span><span class="plain-syntax">(</span><span class="identifier-syntax">dc</span><span class="plain-syntax">)))</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LIST_OF_TY_InsertItem</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="identifier-syntax">dc</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> + </span><span class="constant-syntax">2</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">list</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">];</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>§13. Dealing with action choices. </b>At various stages in action processing, the main story loop calls the following
|
|
three functions, which in turn call <span class="extract"><span class="extract-syntax">DirectorDetectActionChoice</span></span>. That looks
|
|
for a match of the current action against one of the choices in the list on
|
|
the stack: it then re-enters the D-code interpreter if it makes a match, and
|
|
eventually comes back with <span class="extract"><span class="extract-syntax">true</span></span> to halt action processing. If it makes no
|
|
match, it returns <span class="extract"><span class="extract-syntax">false</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary">Note that if we do make a match, and try to resume dialogue, we may still not
|
|
be able to complete it and empty the D-stack, because it may pause again for
|
|
a further action choice. But that's okay, because action processing is nested
|
|
too, even if the VM stack does for a while have a surprising state.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorBeforeAction</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorDetectActionChoice</span><span class="plain-syntax">(</span><span class="identifier-syntax">BEFORE_DSEL</span><span class="plain-syntax">); ];</span>
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorInsteadAction</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorDetectActionChoice</span><span class="plain-syntax">(</span><span class="identifier-syntax">INSTEAD_OF_DSEL</span><span class="plain-syntax">); ];</span>
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorAfterAction</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorDetectActionChoice</span><span class="plain-syntax">(</span><span class="identifier-syntax">AFTER_DSEL</span><span class="plain-syntax">); ];</span>
|
|
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorDetectActionChoice</span><span class="plain-syntax"> </span><span class="identifier-syntax">stage</span><span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax"> </span><span class="identifier-syntax">list</span><span class="plain-syntax"> </span><span class="identifier-syntax">was</span><span class="plain-syntax"> </span><span class="identifier-syntax">dc</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> </span><span class="identifier-syntax">fn</span><span class="plain-syntax"> </span><span class="identifier-syntax">chose</span><span class="plain-syntax"> </span><span class="identifier-syntax">suppress_otherwise</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">director_sp</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">list</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LIST_OF_TY_GetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</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">N</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">debug_dialogue</span><span class="plain-syntax"> >= </span><span class="constant-syntax">2</span><span class="plain-syntax">) { </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"-- found: "</span><span class="plain-syntax">; </span><span class="identifier-syntax">DirectorTraceStack</span><span class="plain-syntax">(); }</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=1: </span><span class="identifier-syntax">i</span><span class="plain-syntax"><=</span><span class="identifier-syntax">N</span><span class="plain-syntax">: </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">dc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LIST_OF_TY_GetItem</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">DirectorChoiceType</span><span class="plain-syntax">(</span><span class="identifier-syntax">dc</span><span class="plain-syntax">) == </span><span class="identifier-syntax">OTHERWISE_DSEL</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">suppress_otherwise</span><span class="plain-syntax"> == </span><span class="reserved-syntax">false</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">chose</span><span class="plain-syntax"> = </span><span class="identifier-syntax">dc</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</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="identifier-syntax">fn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorChoiceRawContent</span><span class="plain-syntax">(</span><span class="identifier-syntax">dc</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">fn</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">fn</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">DirectorChoiceType</span><span class="plain-syntax">(</span><span class="identifier-syntax">dc</span><span class="plain-syntax">) == </span><span class="identifier-syntax">stage</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">chose</span><span class="plain-syntax"> = </span><span class="identifier-syntax">dc</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</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="identifier-syntax">suppress_otherwise</span><span class="plain-syntax"> = </span><span class="reserved-syntax">true</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</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">debug_dialogue</span><span class="plain-syntax"> >= </span><span class="constant-syntax">2</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">chose</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">"-- selected "</span><span class="plain-syntax">, (</span><span class="identifier-syntax">PrintDialogueChoiceName</span><span class="plain-syntax">) </span><span class="identifier-syntax">chose</span><span class="plain-syntax">, </span><span class="string-syntax">" at stage "</span><span class="plain-syntax">, </span><span class="identifier-syntax">stage</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">else</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">"-- no selection at stage "</span><span class="plain-syntax">, </span><span class="identifier-syntax">stage</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>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">chose</span><span class="plain-syntax"> == </span><span class="reserved-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">debug_dialogue</span><span class="plain-syntax"> >= </span><span class="constant-syntax">2</span><span class="plain-syntax">) { </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"-- gave up: "</span><span class="plain-syntax">; </span><span class="identifier-syntax">DirectorTraceStack</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">LIST_OF_TY_SetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</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">DirectorExerciseChoice</span><span class="plain-syntax">(</span><span class="identifier-syntax">chose</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">director_sp</span><span class="plain-syntax"> > </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">was</span><span class="plain-syntax"> = </span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">debug_dialogue</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">"-- Resuming "</span><span class="plain-syntax">, (</span><span class="identifier-syntax">PrintDialogueBeatName</span><span class="plain-syntax">) </span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1), </span><span class="string-syntax">"^"</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorRun</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">was</span><span class="plain-syntax"> == </span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</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="SP14" class="paragraph-anchor"></a><b>§14. Exercising a choice. </b>By whatever means, then, a choice <span class="extract"><span class="extract-syntax">dc</span></span> has been made in either the textual or
|
|
action-based sense, and the following function runs the D-code interpreter
|
|
on the subtree underneath it:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorExerciseChoice</span><span class="plain-syntax"> </span><span class="identifier-syntax">dc</span><span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> </span><span class="identifier-syntax">spc</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WriteGProperty</span><span class="plain-syntax">(</span><span class="identifier-syntax">DIALOGUE_CHOICE_TY</span><span class="plain-syntax">, </span><span class="identifier-syntax">dc</span><span class="plain-syntax">, </span><span class="identifier-syntax">performed</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorBeatGetProgram</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorStackLastPC</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">spc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> + </span><span class="constant-syntax">2</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">program</span><span class="plain-syntax">--></span><span class="identifier-syntax">spc</span><span class="plain-syntax">)/100 ~= </span><span class="identifier-syntax">CHOICE_DCODEI</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">program</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">spc</span><span class="plain-syntax">+1) ~= </span><span class="identifier-syntax">dc</span><span class="plain-syntax">)) </span><span class="identifier-syntax">spc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">spc</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">spc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">spc</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">DirectorPush</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">-->(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1), (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--></span><span class="identifier-syntax">pc</span><span class="plain-syntax">) % </span><span class="constant-syntax">100</span><span class="plain-syntax"> + </span><span class="constant-syntax">2</span><span class="plain-syntax">, </span><span class="identifier-syntax">spc</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DirectorRun</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax">];</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>§15. Numerical choice at the keyboard. </b>This crude function prompts the player for a number from 1 to <span class="extract"><span class="extract-syntax">max</span></span>, waits for
|
|
this to be typed at the keyboard, then returns the choice made.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorPickANumber</span><span class="plain-syntax"> </span><span class="identifier-syntax">max</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax"> </span><span class="identifier-syntax">wa</span><span class="plain-syntax"> </span><span class="identifier-syntax">wl</span><span class="plain-syntax"> </span><span class="identifier-syntax">sign</span><span class="plain-syntax"> </span><span class="identifier-syntax">base</span><span class="plain-syntax"> </span><span class="identifier-syntax">digit_count</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax"> </span><span class="identifier-syntax">digit</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">location</span><span class="plain-syntax"> == </span><span class="reserved-syntax">nothing</span><span class="plain-syntax"> || </span><span class="reserved-syntax">parent</span><span class="plain-syntax">(</span><span class="identifier-syntax">player</span><span class="plain-syntax">) == </span><span class="reserved-syntax">nothing</span><span class="plain-syntax">) </span><span class="identifier-syntax">KeyboardPrimitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">buffer2</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse2</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">KeyboardPrimitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">buffer2</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse2</span><span class="plain-syntax">, </span><span class="identifier-syntax">DrawStatusLine</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">Iftrue</span><span class="plain-syntax"> </span><span class="identifier-syntax">CHARSIZE</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parse2</span><span class="plain-syntax">->1;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wa</span><span class="plain-syntax"> = </span><span class="identifier-syntax">buffer2</span><span class="plain-syntax"> + </span><span class="identifier-syntax">parse2</span><span class="plain-syntax">->5;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parse2</span><span class="plain-syntax">->4;</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">j</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parse2</span><span class="plain-syntax">-->0;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wa</span><span class="plain-syntax"> = </span><span class="identifier-syntax">buffer2</span><span class="plain-syntax"> + </span><span class="identifier-syntax">parse2</span><span class="plain-syntax">-->3;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parse2</span><span class="plain-syntax">-->2;</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">j</span><span class="plain-syntax">) { </span><span class="comment-syntax">at least one word entered</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">sign</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="identifier-syntax">base</span><span class="plain-syntax"> = </span><span class="constant-syntax">10</span><span class="plain-syntax">; </span><span class="identifier-syntax">digit_count</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wa</span><span class="plain-syntax">->0 ~= </span><span class="character-syntax">'-'</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="character-syntax">'$'</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="character-syntax">'0'</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="character-syntax">'1'</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="character-syntax">'2'</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="character-syntax">'3'</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="character-syntax">'4'</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="character-syntax">'5'</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="character-syntax">'6'</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="character-syntax">'7'</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="character-syntax">'8'</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="character-syntax">'9'</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">Retry</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">wa</span><span class="plain-syntax">->0 == </span><span class="character-syntax">'-'</span><span class="plain-syntax">) { </span><span class="identifier-syntax">sign</span><span class="plain-syntax"> = -1; </span><span class="identifier-syntax">wl</span><span class="plain-syntax">--; </span><span class="identifier-syntax">wa</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">wl</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">Retry</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">n</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">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wl</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wa</span><span class="plain-syntax">->0 >= </span><span class="character-syntax">'a'</span><span class="plain-syntax">) </span><span class="identifier-syntax">digit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wa</span><span class="plain-syntax">->0 - </span><span class="character-syntax">'a'</span><span class="plain-syntax"> + </span><span class="constant-syntax">10</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">digit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wa</span><span class="plain-syntax">->0 - </span><span class="character-syntax">'0'</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">digit_count</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">base</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">: </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">digit_count</span><span class="plain-syntax"> == </span><span class="constant-syntax">17</span><span class="plain-syntax">) </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">Retry</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="constant-syntax">10</span><span class="plain-syntax">:</span>
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">Iftrue</span><span class="plain-syntax"> </span><span class="identifier-syntax">WORDSIZE</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</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">digit_count</span><span class="plain-syntax"> == </span><span class="constant-syntax">6</span><span class="plain-syntax">) </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">Retry</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">digit_count</span><span class="plain-syntax"> == </span><span class="constant-syntax">5</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">n</span><span class="plain-syntax"> > </span><span class="constant-syntax">3276</span><span class="plain-syntax">) </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">Retry</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">n</span><span class="plain-syntax"> == </span><span class="constant-syntax">3276</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">sign</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax"> && </span><span class="identifier-syntax">digit</span><span class="plain-syntax"> > </span><span class="constant-syntax">7</span><span class="plain-syntax">) </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">Retry</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">sign</span><span class="plain-syntax"> == -1 && </span><span class="identifier-syntax">digit</span><span class="plain-syntax"> > </span><span class="constant-syntax">8</span><span class="plain-syntax">) </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">Retry</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">Ifnot</span><span class="plain-syntax">; </span><span class="comment-syntax">i.e., if (WORDSIZE == 4)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">digit_count</span><span class="plain-syntax"> == </span><span class="constant-syntax">11</span><span class="plain-syntax">) </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">Retry</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">digit_count</span><span class="plain-syntax"> == </span><span class="constant-syntax">10</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">n</span><span class="plain-syntax"> > </span><span class="constant-syntax">214748364</span><span class="plain-syntax">) </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">Retry</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">n</span><span class="plain-syntax"> == </span><span class="constant-syntax">214748364</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">sign</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax"> && </span><span class="identifier-syntax">digit</span><span class="plain-syntax"> > </span><span class="constant-syntax">7</span><span class="plain-syntax">) </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">Retry</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">sign</span><span class="plain-syntax"> == -1 && </span><span class="identifier-syntax">digit</span><span class="plain-syntax"> > </span><span class="constant-syntax">8</span><span class="plain-syntax">) </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">Retry</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</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="constant-syntax">16</span><span class="plain-syntax">: </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">digit_count</span><span class="plain-syntax"> == </span><span class="constant-syntax">5</span><span class="plain-syntax">) </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">Retry</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">digit</span><span class="plain-syntax"> >= </span><span class="constant-syntax">0</span><span class="plain-syntax"> && </span><span class="identifier-syntax">digit</span><span class="plain-syntax"> < </span><span class="identifier-syntax">base</span><span class="plain-syntax">) </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="identifier-syntax">base</span><span class="plain-syntax">*</span><span class="identifier-syntax">n</span><span class="plain-syntax"> + </span><span class="identifier-syntax">digit</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">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">Retry</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wl</span><span class="plain-syntax">--; </span><span class="identifier-syntax">wa</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> }</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">sign</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">n</span><span class="plain-syntax"> < </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">n</span><span class="plain-syntax"> > </span><span class="identifier-syntax">max</span><span class="plain-syntax">)) </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">Retry</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">n</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> .</span><span class="identifier-syntax">Retry</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">"(Please type an option in the range 1 to "</span><span class="plain-syntax">, </span><span class="identifier-syntax">max</span><span class="plain-syntax">, </span><span class="string-syntax">" and press return.)^^"</span><span class="plain-syntax">;</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-chc.html">❮</a></li><li class="progresssection"><a href="S-drc.html">drc</a></li><li class="progresssection"><a href="S-bts.html">bts</a></li><li class="progresssection"><a href="S-lns.html">lns</a></li><li class="progresssection"><a href="S-chc.html">chc</a></li><li class="progresscurrent">prg</li><li class="progressnextoff">❯</li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|