basic: ON..GOSUB, CLEAR, rearranged platform menu

This commit is contained in:
Steven Hugg 2020-08-10 08:07:09 -05:00
parent cf39cd4f58
commit 946037a1c9
4 changed files with 86 additions and 44 deletions

View File

@ -191,6 +191,7 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
<li><a class="dropdown-item" href="?platform=msx-libcv">MSX (libCV)</a></li>
<li><a class="dropdown-item" href="?platform=apple2">Apple ][+</a></li>
<li><a class="dropdown-item" href="?platform=zx">ZX Spectrum</a></li>
<li><a class="dropdown-item" href="?platform=x86">x86 (FreeDOS)</a></li>
</ul>
</li>
<li class="dropdown dropdown-submenu">
@ -200,6 +201,7 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
<li><a class="dropdown-item" href="?platform=mw8080bw">Midway 8080</a></li>
<li><a class="dropdown-item" href="?platform=galaxian-scramble">Galaxian/Scramble</a></li>
<li><a class="dropdown-item" href="?platform=vector-z80color">Atari Color Vector (Z80)</a></li>
<li><a class="dropdown-item" href="?platform=vector-ataricolor">Atari Color Vector (6502)</a></li>
<li><a class="dropdown-item" href="?platform=williams-z80">Williams (Z80)</a></li>
<li><a class="dropdown-item" href="?platform=sound_williams-z80">Williams Sound (Z80)</a></li>
</ul>
@ -211,26 +213,25 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
<li><a class="dropdown-item" href="?platform=verilog-vga">Verilog (VGA @ 25 Mhz)</a></li>
</ul>
</li>
<li class="dropdown dropdown-submenu">
<a tabindex="-1" href="#">MAME Emulators</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="?platform=atari8-800xl.mame">Atari 800XL (MAME)</a></li>
<li><a class="dropdown-item" href="?platform=atari8-5200.mame">Atari 5200 (MAME)</a></li>
<hr>
<li><a class="dropdown-item" href="?platform=vcs.mame">Atari 2600 (MAME)</a></li>
<li><a class="dropdown-item" href="?platform=coleco.mame">ColecoVision (MAME)</a></li>
<li><a class="dropdown-item" href="?platform=nes.mame">NES (MAME)</a></li>
</ul>
</li>
<li class="dropdown dropdown-submenu">
<a tabindex="-1" href="#">Other</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="?platform=vector-ataricolor">Atari Color Vector (6502)</a></li>
<li><a class="dropdown-item" href="?platform=x86">x86 (FreeDOS)</a></li>
<li><a class="dropdown-item" href="?platform=zmachine">Z-Machine</a></li>
<li><a class="dropdown-item" href="?platform=markdown">Markdown Text Editor</a></li>
</ul>
</li>
<a tabindex="-1" href="#">Text-Based</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="?platform=basic">BASIC</a></li>
<li><a class="dropdown-item" href="?platform=zmachine">Z-Machine</a></li>
<li><a class="dropdown-item" href="?platform=markdown">Markdown Text Editor</a></li>
</ul>
</li>
<li class="dropdown dropdown-submenu">
<a tabindex="-1" href="#">MAME Emulators</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="?platform=atari8-800xl.mame">Atari 800XL (MAME)</a></li>
<li><a class="dropdown-item" href="?platform=atari8-5200.mame">Atari 5200 (MAME)</a></li>
<hr>
<li><a class="dropdown-item" href="?platform=vcs.mame">Atari 2600 (MAME)</a></li>
<li><a class="dropdown-item" href="?platform=coleco.mame">ColecoVision (MAME)</a></li>
<li><a class="dropdown-item" href="?platform=nes.mame">NES (MAME)</a></li>
</ul>
</li>
</ul>
</span>

View File

@ -88,7 +88,7 @@ export interface RETURN_Statement {
}
export interface ONGOTO_Statement {
command: "ONGOTO";
command: "ONGOTO" | "ONGOSUB";
expr: Expr;
labels: Expr[];
}
@ -706,9 +706,11 @@ export class BASICParser {
}
stmt__ON() : ONGOTO_Statement {
var expr = this.parseExpr();
this.expectToken('GOTO');
var gotok = this.consumeToken();
var cmd = {GOTO:'ONGOTO', GOSUB:'ONGOSUB'}[gotok.str];
if (!cmd) this.compileError(`There should be a GOTO or GOSUB here.`);
var labels = this.parseLabelList();
return { command:'ONGOTO', expr:expr, labels:labels };
return { command:cmd, expr:expr, labels:labels };
}
stmt__DEF() : DEF_Statement {
var lexpr = this.parseVarSubscriptOrFunc();
@ -728,6 +730,9 @@ export class BASICParser {
this.decls[lexpr.name] = this.lasttoken.$loc;
return { command:'GET', lexpr:lexpr };
}
stmt__CLEAR() : NoArgStatement {
return { command:'CLEAR' };
}
// TODO: CHANGE A TO A$ (4th edition, A(0) is len and A(1..) are chars)
stmt__OPTION() : OPTION_Statement {
var tokname = this.consumeToken();
@ -826,7 +831,7 @@ export const ECMA55_MINIMAL : BASICOptions = {
validKeywords : ['BASE','DATA','DEF','DIM','END',
'FOR','GO','GOSUB','GOTO','IF','INPUT','LET','NEXT','ON','OPTION','PRINT',
'RANDOMIZE','READ','REM','RESTORE','RETURN','STEP','STOP','SUB','THEN','TO'
],
], // TODO: no ON...GOSUB
validFunctions : ['ABS','ATN','COS','EXP','INT','LOG','RND','SGN','SIN','SQR','TAB','TAN'],
validOperators : ['=', '<>', '<', '>', '<=', '>=', '+', '-', '*', '/', '^'],
printZoneLength : 15,
@ -857,7 +862,7 @@ export const ALTAIR_BASIC40 : BASICOptions = {
tickComments : false,
validKeywords : null, // all
validFunctions : null, // all
validOperators : null, // all ['\\','MOD','NOT','AND','OR','XOR','EQV','IMP'],
validOperators : null, // all
printZoneLength : 15,
numericPadding : true,
checkOverflow : true,
@ -884,10 +889,19 @@ export const APPLESOFT_BASIC : BASICOptions = {
maxStringLength : 255,
sparseArrays : false,
tickComments : false,
validKeywords : null, // all
validFunctions : ['ABS','ATN','COS','EXP','INT','LOG','RND','SGN','SIN','SQR','TAN',
'LEN','LEFT$','MID$','RIGHT$','STR$','VAL','CHR$','ASC',
'FRE','SCRN','PDL','PEEK'], // TODO
validKeywords : [
'CLEAR','LET','DIM','DEF','FN','GOTO','GOSUB','RETURN','ON','POP',
'FOR','TO','NEXT','IF','THEN','END','STOP','ONERR','RESUME',
'PRINT','INPUT','GET','HOME','HTAB','VTAB',
'INVERSE','FLASH','NORMAL','TEXT',
'GR','COLOR','PLOT','HLIN','VLIN',
'HGR','HGR2','HPLOT','HCOLOR','AT',
'DATA','READ','RESTORE',
'REM','TRACE','NOTRACE'],
validFunctions : [
'ABS','ATN','COS','EXP','INT','LOG','RND','SGN','SIN','SQR','TAN',
'LEN','LEFT$','MID$','RIGHT$','STR$','VAL','CHR$','ASC',
'FRE','SCRN','PDL','PEEK','POS'],
validOperators : ['=', '<>', '<', '>', '<=', '>=', '+', '-', '*', '/', '^', 'AND', 'NOT', 'OR'],
printZoneLength : 16,
numericPadding : false,

View File

@ -90,16 +90,19 @@ export class BASICRuntime {
reset() {
this.curpc = 0;
this.dataptr = 0;
this.vars = {};
this.arrays = {};
this.defs = {};
this.clearVars();
this.forLoops = [];
this.returnStack = [];
this.column = 0;
this.running = true;
this.exited = false;
}
clearVars() {
this.vars = {};
this.arrays = {};
this.defs = {}; // TODO? only in interpreters
}
getBuiltinFunctions() {
var fnames = this.program && this.opts.validFunctions;
// if no valid function list, look for ABC...() functions in prototype
@ -119,18 +122,13 @@ export class BASICRuntime {
}
getLineForPC(pc:number) {
var line;
do {
line = this.pc2line.get(pc);
if (line != null) break;
} while (--pc >= 0);
return line;
var stmt = this.allstmts[pc];
return stmt && stmt.$loc && stmt.$loc.line;
}
getLabelForPC(pc:number) {
var lineno = this.getLineForPC(pc);
var pgmline = this.program.lines[lineno];
return pgmline ? pgmline.label : '?';
var stmt = this.allstmts[pc];
return stmt && stmt.$loc && stmt.$loc.label;
}
getCurrentSourceLocation() : SourceLocation {
@ -138,6 +136,11 @@ export class BASICRuntime {
return stmt && stmt.$loc;
}
getCurrentLabel() : string {
var loc = this.getCurrentSourceLocation();
return loc && loc.label;
}
getStatement() {
return this.allstmts[this.curpc];
}
@ -228,7 +231,7 @@ export class BASICRuntime {
this.runtimeError("I tried to POP, but there wasn't a corresponding GOSUB.");
this.returnStack.pop();
}
valueToString(obj) : string {
var str;
if (typeof obj === 'number') {
@ -439,6 +442,13 @@ export class BASICRuntime {
if (value < 1 || value > labels.length)
this.runtimeError(`I needed a number between 1 and ${labels.length}, but I got ${value}.`);
this.gotoLabel(labels[value-1]);
}
onGosubLabel(value: number, ...labels: string[]) {
value = this.ROUND(value);
if (value < 1 || value > labels.length)
this.runtimeError(`I needed a number between 1 and ${labels.length}, but I got ${value}.`);
this.gosubLabel(labels[value-1]);
}
nextDatum() : basic.Value {
@ -550,7 +560,10 @@ export class BASICRuntime {
do__ONGOTO(stmt : basic.ONGOTO_Statement) {
var expr = this.expr2js(stmt.expr);
var labels = stmt.labels.map((arg) => this.expr2js(arg, {isconst:true})).join(', ');
return `this.onGotoLabel(${expr}, ${labels})`;
if (stmt.command == 'ONGOTO')
return `this.onGotoLabel(${expr}, ${labels})`;
else
return `this.onGosubLabel(${expr}, ${labels})`;
}
do__DATA() {
@ -596,6 +609,10 @@ export class BASICRuntime {
})`;
}
do__CLEAR() {
return 'this.clearVars()';
}
// TODO: ONERR, ON ERROR GOTO
// TODO: "SUBSCRIPT ERROR" (range check)
// TODO: gosubs nested too deeply

View File

@ -173,7 +173,17 @@ class BASICPlatform implements Platform {
$.extend(true, this.runtime, state);
}
getDebugTree() {
return this.runtime;
return {
Variables: this.runtime.vars,
Arrays: this.runtime.arrays,
Functions: this.runtime.defs,
ForLoops: this.runtime.forLoops,
ReturnStack: this.runtime.returnStack,
CurrentLine: this.runtime.getCurrentLabel(),
NextDatum: this.runtime.datums[this.runtime.dataptr],
Dialect: this.runtime.opts,
Internals: this.runtime,
}
}
inspect(sym: string) {
var o = this.runtime.vars[sym];