mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-29 14:51:17 +00:00
basic: ON..GOSUB, CLEAR, rearranged platform menu
This commit is contained in:
parent
cf39cd4f58
commit
946037a1c9
19
index.html
19
index.html
@ -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=msx-libcv">MSX (libCV)</a></li>
|
||||||
<li><a class="dropdown-item" href="?platform=apple2">Apple ][+</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=zx">ZX Spectrum</a></li>
|
||||||
|
<li><a class="dropdown-item" href="?platform=x86">x86 (FreeDOS)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="dropdown dropdown-submenu">
|
<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=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=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-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=williams-z80">Williams (Z80)</a></li>
|
||||||
<li><a class="dropdown-item" href="?platform=sound_williams-z80">Williams Sound (Z80)</a></li>
|
<li><a class="dropdown-item" href="?platform=sound_williams-z80">Williams Sound (Z80)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -211,6 +213,14 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
|||||||
<li><a class="dropdown-item" href="?platform=verilog-vga">Verilog (VGA @ 25 Mhz)</a></li>
|
<li><a class="dropdown-item" href="?platform=verilog-vga">Verilog (VGA @ 25 Mhz)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="dropdown dropdown-submenu">
|
||||||
|
<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">
|
<li class="dropdown dropdown-submenu">
|
||||||
<a tabindex="-1" href="#">MAME Emulators</a>
|
<a tabindex="-1" href="#">MAME Emulators</a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
@ -222,15 +232,6 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
|||||||
<li><a class="dropdown-item" href="?platform=nes.mame">NES (MAME)</a></li>
|
<li><a class="dropdown-item" href="?platform=nes.mame">NES (MAME)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</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>
|
|
||||||
</ul>
|
</ul>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ export interface RETURN_Statement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ONGOTO_Statement {
|
export interface ONGOTO_Statement {
|
||||||
command: "ONGOTO";
|
command: "ONGOTO" | "ONGOSUB";
|
||||||
expr: Expr;
|
expr: Expr;
|
||||||
labels: Expr[];
|
labels: Expr[];
|
||||||
}
|
}
|
||||||
@ -706,9 +706,11 @@ export class BASICParser {
|
|||||||
}
|
}
|
||||||
stmt__ON() : ONGOTO_Statement {
|
stmt__ON() : ONGOTO_Statement {
|
||||||
var expr = this.parseExpr();
|
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();
|
var labels = this.parseLabelList();
|
||||||
return { command:'ONGOTO', expr:expr, labels:labels };
|
return { command:cmd, expr:expr, labels:labels };
|
||||||
}
|
}
|
||||||
stmt__DEF() : DEF_Statement {
|
stmt__DEF() : DEF_Statement {
|
||||||
var lexpr = this.parseVarSubscriptOrFunc();
|
var lexpr = this.parseVarSubscriptOrFunc();
|
||||||
@ -728,6 +730,9 @@ export class BASICParser {
|
|||||||
this.decls[lexpr.name] = this.lasttoken.$loc;
|
this.decls[lexpr.name] = this.lasttoken.$loc;
|
||||||
return { command:'GET', lexpr:lexpr };
|
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)
|
// TODO: CHANGE A TO A$ (4th edition, A(0) is len and A(1..) are chars)
|
||||||
stmt__OPTION() : OPTION_Statement {
|
stmt__OPTION() : OPTION_Statement {
|
||||||
var tokname = this.consumeToken();
|
var tokname = this.consumeToken();
|
||||||
@ -826,7 +831,7 @@ export const ECMA55_MINIMAL : BASICOptions = {
|
|||||||
validKeywords : ['BASE','DATA','DEF','DIM','END',
|
validKeywords : ['BASE','DATA','DEF','DIM','END',
|
||||||
'FOR','GO','GOSUB','GOTO','IF','INPUT','LET','NEXT','ON','OPTION','PRINT',
|
'FOR','GO','GOSUB','GOTO','IF','INPUT','LET','NEXT','ON','OPTION','PRINT',
|
||||||
'RANDOMIZE','READ','REM','RESTORE','RETURN','STEP','STOP','SUB','THEN','TO'
|
'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'],
|
validFunctions : ['ABS','ATN','COS','EXP','INT','LOG','RND','SGN','SIN','SQR','TAB','TAN'],
|
||||||
validOperators : ['=', '<>', '<', '>', '<=', '>=', '+', '-', '*', '/', '^'],
|
validOperators : ['=', '<>', '<', '>', '<=', '>=', '+', '-', '*', '/', '^'],
|
||||||
printZoneLength : 15,
|
printZoneLength : 15,
|
||||||
@ -857,7 +862,7 @@ export const ALTAIR_BASIC40 : BASICOptions = {
|
|||||||
tickComments : false,
|
tickComments : false,
|
||||||
validKeywords : null, // all
|
validKeywords : null, // all
|
||||||
validFunctions : null, // all
|
validFunctions : null, // all
|
||||||
validOperators : null, // all ['\\','MOD','NOT','AND','OR','XOR','EQV','IMP'],
|
validOperators : null, // all
|
||||||
printZoneLength : 15,
|
printZoneLength : 15,
|
||||||
numericPadding : true,
|
numericPadding : true,
|
||||||
checkOverflow : true,
|
checkOverflow : true,
|
||||||
@ -884,10 +889,19 @@ export const APPLESOFT_BASIC : BASICOptions = {
|
|||||||
maxStringLength : 255,
|
maxStringLength : 255,
|
||||||
sparseArrays : false,
|
sparseArrays : false,
|
||||||
tickComments : false,
|
tickComments : false,
|
||||||
validKeywords : null, // all
|
validKeywords : [
|
||||||
validFunctions : ['ABS','ATN','COS','EXP','INT','LOG','RND','SGN','SIN','SQR','TAN',
|
'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',
|
'LEN','LEFT$','MID$','RIGHT$','STR$','VAL','CHR$','ASC',
|
||||||
'FRE','SCRN','PDL','PEEK'], // TODO
|
'FRE','SCRN','PDL','PEEK','POS'],
|
||||||
validOperators : ['=', '<>', '<', '>', '<=', '>=', '+', '-', '*', '/', '^', 'AND', 'NOT', 'OR'],
|
validOperators : ['=', '<>', '<', '>', '<=', '>=', '+', '-', '*', '/', '^', 'AND', 'NOT', 'OR'],
|
||||||
printZoneLength : 16,
|
printZoneLength : 16,
|
||||||
numericPadding : false,
|
numericPadding : false,
|
||||||
|
@ -90,15 +90,18 @@ export class BASICRuntime {
|
|||||||
reset() {
|
reset() {
|
||||||
this.curpc = 0;
|
this.curpc = 0;
|
||||||
this.dataptr = 0;
|
this.dataptr = 0;
|
||||||
this.vars = {};
|
this.clearVars();
|
||||||
this.arrays = {};
|
|
||||||
this.defs = {};
|
|
||||||
this.forLoops = [];
|
this.forLoops = [];
|
||||||
this.returnStack = [];
|
this.returnStack = [];
|
||||||
this.column = 0;
|
this.column = 0;
|
||||||
this.running = true;
|
this.running = true;
|
||||||
this.exited = false;
|
this.exited = false;
|
||||||
}
|
}
|
||||||
|
clearVars() {
|
||||||
|
this.vars = {};
|
||||||
|
this.arrays = {};
|
||||||
|
this.defs = {}; // TODO? only in interpreters
|
||||||
|
}
|
||||||
|
|
||||||
getBuiltinFunctions() {
|
getBuiltinFunctions() {
|
||||||
var fnames = this.program && this.opts.validFunctions;
|
var fnames = this.program && this.opts.validFunctions;
|
||||||
@ -119,18 +122,13 @@ export class BASICRuntime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getLineForPC(pc:number) {
|
getLineForPC(pc:number) {
|
||||||
var line;
|
var stmt = this.allstmts[pc];
|
||||||
do {
|
return stmt && stmt.$loc && stmt.$loc.line;
|
||||||
line = this.pc2line.get(pc);
|
|
||||||
if (line != null) break;
|
|
||||||
} while (--pc >= 0);
|
|
||||||
return line;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getLabelForPC(pc:number) {
|
getLabelForPC(pc:number) {
|
||||||
var lineno = this.getLineForPC(pc);
|
var stmt = this.allstmts[pc];
|
||||||
var pgmline = this.program.lines[lineno];
|
return stmt && stmt.$loc && stmt.$loc.label;
|
||||||
return pgmline ? pgmline.label : '?';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentSourceLocation() : SourceLocation {
|
getCurrentSourceLocation() : SourceLocation {
|
||||||
@ -138,6 +136,11 @@ export class BASICRuntime {
|
|||||||
return stmt && stmt.$loc;
|
return stmt && stmt.$loc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getCurrentLabel() : string {
|
||||||
|
var loc = this.getCurrentSourceLocation();
|
||||||
|
return loc && loc.label;
|
||||||
|
}
|
||||||
|
|
||||||
getStatement() {
|
getStatement() {
|
||||||
return this.allstmts[this.curpc];
|
return this.allstmts[this.curpc];
|
||||||
}
|
}
|
||||||
@ -439,6 +442,13 @@ export class BASICRuntime {
|
|||||||
if (value < 1 || value > labels.length)
|
if (value < 1 || value > labels.length)
|
||||||
this.runtimeError(`I needed a number between 1 and ${labels.length}, but I got ${value}.`);
|
this.runtimeError(`I needed a number between 1 and ${labels.length}, but I got ${value}.`);
|
||||||
this.gotoLabel(labels[value-1]);
|
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 {
|
nextDatum() : basic.Value {
|
||||||
@ -550,7 +560,10 @@ export class BASICRuntime {
|
|||||||
do__ONGOTO(stmt : basic.ONGOTO_Statement) {
|
do__ONGOTO(stmt : basic.ONGOTO_Statement) {
|
||||||
var expr = this.expr2js(stmt.expr);
|
var expr = this.expr2js(stmt.expr);
|
||||||
var labels = stmt.labels.map((arg) => this.expr2js(arg, {isconst:true})).join(', ');
|
var labels = stmt.labels.map((arg) => this.expr2js(arg, {isconst:true})).join(', ');
|
||||||
|
if (stmt.command == 'ONGOTO')
|
||||||
return `this.onGotoLabel(${expr}, ${labels})`;
|
return `this.onGotoLabel(${expr}, ${labels})`;
|
||||||
|
else
|
||||||
|
return `this.onGosubLabel(${expr}, ${labels})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
do__DATA() {
|
do__DATA() {
|
||||||
@ -596,6 +609,10 @@ export class BASICRuntime {
|
|||||||
})`;
|
})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do__CLEAR() {
|
||||||
|
return 'this.clearVars()';
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: ONERR, ON ERROR GOTO
|
// TODO: ONERR, ON ERROR GOTO
|
||||||
// TODO: "SUBSCRIPT ERROR" (range check)
|
// TODO: "SUBSCRIPT ERROR" (range check)
|
||||||
// TODO: gosubs nested too deeply
|
// TODO: gosubs nested too deeply
|
||||||
|
@ -173,7 +173,17 @@ class BASICPlatform implements Platform {
|
|||||||
$.extend(true, this.runtime, state);
|
$.extend(true, this.runtime, state);
|
||||||
}
|
}
|
||||||
getDebugTree() {
|
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) {
|
inspect(sym: string) {
|
||||||
var o = this.runtime.vars[sym];
|
var o = this.runtime.vars[sym];
|
||||||
|
Loading…
Reference in New Issue
Block a user