Skip to content

Commit 39131e1

Browse files
document GOSUB/ENDPROC behaviour when loops are unterminated
1 parent ecc3ea7 commit 39131e1

86 files changed

Lines changed: 723 additions & 604 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docpages/basic-language-reference/keywords/ENDPROC.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ PROCprint_if_positive(0)
4242
- Using `ENDPROC` outside a procedure is an error.
4343
- Functions (`DEF FNname`) do **not** use `ENDPROC`; a function returns with a final line that **begins with `=`**.
4444

45+
##### Loop scope
46+
47+
Loops (`FOR`, `WHILE`, `REPEAT`) are scoped to the current procedure.
48+
49+
Any active loops created inside a `PROC` are discarded when `ENDPROC` is reached unless they have already been exited normally.
50+
51+
If execution continues and a loop-closing statement is encountered with no matching loop, a runtime error is raised (e.g. `NEXT without FOR`).
52+
4553
**See also:**
4654
\ref DEF "DEF" ·
4755
\ref PROC "PROC" ·

docpages/basic-language-reference/keywords/GOTO.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,23 @@ Transfers control unconditionally to the line with the given **constant line num
4040

4141
---
4242

43+
##### Control-flow behaviour
44+
45+
`GOTO` performs a direct jump and does **not** unwind or restore any control structures.
46+
47+
This means you may jump:
48+
49+
* out of a loop (`FOR`, `WHILE`, `REPEAT`)
50+
* into the body of a loop
51+
* out of a `GOSUB` or `PROC`
52+
53+
Retro Rocket BASIC does not crash in these cases, but the program may later raise a runtime error if
54+
control structures no longer match the current execution state (for example, `NEXT without FOR` or `RETURN without GOSUB`).
55+
56+
This behaviour is defined.
57+
58+
---
59+
4360
##### Notes
4461
- Jumping to a non-existent line raises a runtime error.
4562
- Heavy use of `GOTO` quickly reduces readability; use it only for compatibility with legacy code.

docpages/basic-language-reference/keywords/RETURN.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Execution resumes at the **statement after** the `GOSUB` call.
2626

2727
---
2828

29-
### Examples (line numbers permitted)
29+
### Examples
3030

3131
**Simple subroutine**
3232
```basic
@@ -60,6 +60,19 @@ Execution resumes at the **statement after** the `GOSUB` call.
6060
10 RETURN
6161
```
6262

63+
Here’s a concise section matching your style:
64+
65+
### Loop scope
66+
67+
Loops (`FOR`, `WHILE`, `REPEAT`) are scoped to the current `GOSUB`.
68+
69+
Any active loops created inside a `GOSUB` are discarded when `RETURN` is executed unless they have already been exited normally.
70+
71+
If execution continues and a loop-closing statement is encountered with no matching loop, a runtime error is raised (e.g. `NEXT without FOR`).
72+
73+
This differs from BBC BASIC, where loops created inside a `GOSUB` could leak into the caller and corrupt the loop stack.
74+
75+
6376
---
6477

6578
### See also

docs/ANIMATE.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ <h3 class="doxsection"><a class="anchor" id="example"></a>
125125
<div class="line"> FLIP</div>
126126
<div class="line"> SLEEP 66</div>
127127
<div class="line"> ANIMATE NEXT bad_apple</div>
128-
<div class="line">UNTIL INKEY$ &lt;&gt; &quot;&quot;</div>
128+
<div class="line">UNTIL INKEY$(&quot;&quot;) &lt;&gt; &quot;&quot;</div>
129129
<div class="line"> </div>
130130
<div class="line">AUTOFLIP TRUE</div>
131131
<div class="line">CLS</div>

docs/ASC.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ <h3 class="doxsection"><a class="anchor" id="examples-2"></a>
106106
<div class="line">PRINT ASC(C$)</div>
107107
</div><!-- fragment --><p>This example produces <span class="tt">82</span>, the ASCII code for <span class="tt">"R"</span>.</p>
108108
<div class="fragment"><div class="line">REM Using ASC to check a keypress</div>
109-
<div class="line">key$ = INKEY$</div>
109+
<div class="line">key$ = INKEY$(&quot;&quot;)</div>
110110
<div class="line">IF key$ &gt; &quot;&quot; THEN</div>
111111
<div class="line"> code = ASC(key$)</div>
112112
<div class="line"> PRINT &quot;You pressed: &quot;; code</div>

docs/ENDPROC.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,11 @@ <h5 class="doxsection"><a class="anchor" id="rules--behaviour-1"></a>
127127
<li>Using <span class="tt">ENDPROC</span> outside a procedure is an error.</li>
128128
<li>Functions (<span class="tt">DEF FNname</span>) do <b>not</b> use <span class="tt">ENDPROC</span>; a function returns with a final line that <b>begins with <span class="tt">=</span></b>.</li>
129129
</ul>
130+
<h5 class="doxsection"><a class="anchor" id="loop-scope"></a>
131+
Loop scope</h5>
132+
<p>Loops (<span class="tt">FOR</span>, <span class="tt">WHILE</span>, <span class="tt">REPEAT</span>) are scoped to the current procedure.</p>
133+
<p>Any active loops created inside a <span class="tt">PROC</span> are discarded when <span class="tt">ENDPROC</span> is reached unless they have already been exited normally.</p>
134+
<p>If execution continues and a loop-closing statement is encountered with no matching loop, a runtime error is raised (e.g. <span class="tt">NEXT without FOR</span>).</p>
130135
<p><b>See also:</b> <br />
131136
<a class="el" href="DEF.html">DEF</a> · <a class="el" href="PROC.html">PROC</a> · <a class="el" href="FN.html">FN</a> </p>
132137
</div></div><!-- contents -->

docs/GOTO.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,18 @@ <h5 class="doxsection"><a class="anchor" id="examples-133"></a>
127127
<div class="line">40 IF I &lt;= 5 THEN GOTO 20</div>
128128
<div class="line">50 PRINT &quot;Done&quot;</div>
129129
</div><!-- fragment --><hr />
130+
<h5 class="doxsection"><a class="anchor" id="control-flow-behaviour"></a>
131+
Control-flow behaviour</h5>
132+
<p><span class="tt">GOTO</span> performs a direct jump and does <b>not</b> unwind or restore any control structures.</p>
133+
<p>This means you may jump:</p>
134+
<ul>
135+
<li>out of a loop (<span class="tt">FOR</span>, <span class="tt">WHILE</span>, <span class="tt">REPEAT</span>)</li>
136+
<li>into the body of a loop</li>
137+
<li>out of a <span class="tt">GOSUB</span> or <span class="tt">PROC</span></li>
138+
</ul>
139+
<p>Retro Rocket BASIC does not crash in these cases, but the program may later raise a runtime error if control structures no longer match the current execution state (for example, <span class="tt">NEXT without FOR</span> or <span class="tt">RETURN without GOSUB</span>).</p>
140+
<p>This behaviour is defined.</p>
141+
<hr />
130142
<h5 class="doxsection"><a class="anchor" id="notes-144"></a>
131143
Notes</h5>
132144
<ul>

docs/INKEY.html

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,16 +95,20 @@
9595
<div class="headertitle"><div class="title">INKEY$ Function </div></div>
9696
</div><!--header-->
9797
<div class="contents">
98-
<div class="textblock"><div class="fragment"><div class="line">A$= INKEY$</div>
99-
</div><!-- fragment --><p>Returns the <b>key that has been pressed</b> as a string. If no key has been pressed since the last call, it returns an <b>empty string</b>.</p>
100-
<p><span class="tt">INKEY$</span> consumes input from the <b>keyboard buffer</b>. If multiple keys have been pressed between this call and the last call to <span class="tt">INKEY$</span> (or an <span class="tt">INPUT</span> statement), it will take multiple calls to retrieve them all.</p>
98+
<div class="textblock"><div class="fragment"><div class="line">A$= INKEY$(STRING)</div>
99+
</div><!-- fragment --><p>INKEY$ checks for key state on the keyboard. It has two modes of operation:</p>
100+
<ul>
101+
<li>If the string parameter passed is an empty string, it will check if any key is waiting in the keyboard buffer, consuming it from the buffer and returning it, or returning an empty string if no key is available.</li>
102+
<li>If the string parameter passed in is a non-empty single-character string, it will check if that key is currently held, and will not consume it from the buffer. Because this form of the function is not consuming from the buffer you may use this form to concurrently check for multiple depressed keys at the same time. Note that you must still drain the buffer. Use a separate INKEY$("") call to drain any pending key presses so the buffer does not fill. <b>US-ASCII values (A-Z) are considered case-insensitive</b> in the parameter when using this form of <span class="tt">INKEY$</span>.</li>
103+
<li>When <span class="tt">INKEY$</span> consumes input from the <b>keyboard buffer</b> by using an empty parameter, if multiple keys have been pressed between this call and the last call to <span class="tt">INKEY$</span> (or an <span class="tt">INPUT</span> statement), it will take multiple calls to retrieve them all.</li>
104+
</ul>
101105
<hr />
102106
<h3 class="doxsection"><a class="anchor" id="extended-keys"></a>
103107
Extended keys</h3>
104108
<p>Some non-printing keys return special character codes rather than ASCII. These values can be retrieved by wrapping <span class="tt">INKEY$</span> with <span class="tt">ASC()</span>.</p>
105109
<table class="markdownTable">
106110
<tr class="markdownTableHead">
107-
<th class="markdownTableHeadNone">Key </th><th class="markdownTableHeadNone"><span class="tt">ASC(INKEY$)</span> value </th></tr>
111+
<th class="markdownTableHeadNone">Key </th><th class="markdownTableHeadNone"><span class="tt">ASC(INKEY$(""))</span> value </th></tr>
108112
<tr class="markdownTableRowOdd">
109113
<td class="markdownTableBodyNone">PAGEUP </td><td class="markdownTableBodyNone">245 </td></tr>
110114
<tr class="markdownTableRowEven">
@@ -132,23 +136,29 @@ <h3 class="doxsection"><a class="anchor" id="examples-100"></a>
132136
<div class="fragment"><div class="line">REM Wait for a keypress</div>
133137
<div class="line">PRINT &quot;Press a key...&quot;</div>
134138
<div class="line">REPEAT</div>
135-
<div class="line"> k$ = INKEY$</div>
139+
<div class="line"> k$ = INKEY$(&quot;&quot;)</div>
136140
<div class="line">UNTIL k$ &gt; &quot;&quot;</div>
137141
<div class="line">PRINT &quot;You pressed: &quot;; k$</div>
138142
</div><!-- fragment --><div class="fragment"><div class="line">REM Handle arrow keys</div>
139-
<div class="line">k$ = INKEY$</div>
143+
<div class="line">k$ = INKEY$(&quot;&quot;)</div>
140144
<div class="line">IF k$ &gt; &quot;&quot; THEN</div>
141145
<div class="line"> code = ASC(k$)</div>
142146
<div class="line"> IF code = 250 THEN PRINT &quot;Up arrow pressed&quot;</div>
143147
<div class="line"> IF code = 251 THEN PRINT &quot;Down arrow pressed&quot;</div>
144148
<div class="line">ENDIF</div>
149+
</div><!-- fragment --><div class="fragment"><div class="line">REM multiple key example</div>
150+
<div class="line">PRINT &quot;Press both A and Z together to exit&quot;</div>
151+
<div class="line">REPEAT</div>
152+
<div class="line">UNTIL INKEY$(&quot;A&quot;) &lt;&gt; &quot;&quot; AND INKEY$(&quot;Z&quot;) &lt;&gt; &quot;&quot;</div>
153+
<div class="line">END</div>
145154
</div><!-- fragment --><hr />
146155
<h3 class="doxsection"><a class="anchor" id="notes-99"></a>
147156
Notes</h3>
148157
<ul>
149158
<li>Printable characters return their usual ASCII values (e.g. <span class="tt">"A"</span> → 65).</li>
150159
<li>Extended keys must be checked via <span class="tt">ASC()</span>.</li>
151-
<li>If no key is pressed, result is <span class="tt">""</span> (empty string).</li>
160+
<li>If no key is pressed, the result is <span class="tt">""</span> (empty string).</li>
161+
<li>If the parameter to <span class="tt">INKEY$</span> contains more than one character, any characters except the first are ignored.</li>
152162
</ul>
153163
<hr />
154164
<p><b>See also:</b> <a class="el" href="ASC.html">ASC</a> · <a class="el" href="INPUT.html">INPUT</a> </p>

docs/REPEAT.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ <h3 class="doxsection"><a class="anchor" id="examples-161"></a>
138138
</div><!-- fragment --><p><b>Loop until a key is pressed</b> </p><div class="fragment"><div class="line">PRINT &quot;Press any key to stop.&quot;</div>
139139
<div class="line">REPEAT</div>
140140
<div class="line"> REM do some periodic work here</div>
141-
<div class="line">UNTIL INKEY$ &lt;&gt; &quot;&quot;</div>
141+
<div class="line">UNTIL INKEY$(&quot;&quot;) &lt;&gt; &quot;&quot;</div>
142142
</div><!-- fragment --><hr />
143143
<h3 class="doxsection"><a class="anchor" id="notes-166"></a>
144144
Notes</h3>

docs/RETURN.html

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ <h3 class="doxsection"><a class="anchor" id="behaviour-6"></a>
117117
</li>
118118
</ul>
119119
<hr />
120-
<h3 class="doxsection"><a class="anchor" id="examples-line-numbers-permitted"></a>
121-
Examples (line numbers permitted)</h3>
120+
<h3 class="doxsection"><a class="anchor" id="examples-162"></a>
121+
Examples</h3>
122122
<p><b>Simple subroutine</b> </p><div class="fragment"><div class="line">10 PRINT &quot;Start&quot;</div>
123123
<div class="line">20 GOSUB 1000</div>
124124
<div class="line">30 PRINT &quot;Back in main code&quot;</div>
@@ -139,7 +139,14 @@ <h3 class="doxsection"><a class="anchor" id="examples-line-numbers-permitted"></
139139
<div class="line">2000 PRINT &quot;Second level&quot;</div>
140140
<div class="line">2010 RETURN</div>
141141
</div><!-- fragment --><p><b>Error: RETURN without GOSUB (do not do this)</b> </p><div class="fragment"><div class="line">10 RETURN</div>
142-
</div><!-- fragment --><hr />
142+
</div><!-- fragment --><p>Here’s a concise section matching your style:</p>
143+
<h3 class="doxsection"><a class="anchor" id="loop-scope-1"></a>
144+
Loop scope</h3>
145+
<p>Loops (<span class="tt">FOR</span>, <span class="tt">WHILE</span>, <span class="tt">REPEAT</span>) are scoped to the current <span class="tt">GOSUB</span>.</p>
146+
<p>Any active loops created inside a <span class="tt">GOSUB</span> are discarded when <span class="tt">RETURN</span> is executed unless they have already been exited normally.</p>
147+
<p>If execution continues and a loop-closing statement is encountered with no matching loop, a runtime error is raised (e.g. <span class="tt">NEXT without FOR</span>).</p>
148+
<p>This differs from BBC BASIC, where loops created inside a <span class="tt">GOSUB</span> could leak into the caller and corrupt the loop stack.</p>
149+
<hr />
143150
<h3 class="doxsection"><a class="anchor" id="see-also-4"></a>
144151
See also</h3>
145152
<ul>

0 commit comments

Comments
 (0)