1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-06-19 17:29:32 +00:00

basic: fixed NEXT, expectTokens()

This commit is contained in:
Steven Hugg 2020-08-12 10:11:10 -05:00
parent e962404c2f
commit 8fdd958859
3 changed files with 20 additions and 7 deletions

View File

@ -31,6 +31,7 @@ export interface BASICOptions {
numericPadding : boolean; // " " or "-" before and " " after numbers? numericPadding : boolean; // " " or "-" before and " " after numbers?
// CONTROL FLOW // CONTROL FLOW
testInitialFor : boolean; // can we skip a NEXT statement? (can't interleave tho) testInitialFor : boolean; // can we skip a NEXT statement? (can't interleave tho)
optionalNextVar : boolean; // can do NEXT without variable
ifElse : boolean; // IF...ELSE construct ifElse : boolean; // IF...ELSE construct
// MISC // MISC
commandsPerSec? : number; // how many commands per second? commandsPerSec? : number; // how many commands per second?
@ -290,7 +291,7 @@ export class BASICParser {
} }
compileError(msg: string, loc?: SourceLocation) { compileError(msg: string, loc?: SourceLocation) {
if (!loc) loc = this.peekToken().$loc; if (!loc) loc = this.peekToken().$loc;
this.errors.push({path:loc.path, line:loc.line, label:loc.label, start:loc.start, end:loc.end, msg:msg}); this.errors.push({path:loc.path, line:loc.line, label:this.curlabel, start:loc.start, end:loc.end, msg:msg});
throw new CompileError(`${msg} (line ${loc.line})`); // TODO: label too? throw new CompileError(`${msg} (line ${loc.line})`); // TODO: label too?
} }
dialectError(what: string, loc?: SourceLocation) { dialectError(what: string, loc?: SourceLocation) {
@ -308,6 +309,14 @@ export class BASICParser {
} }
return tok; return tok;
} }
expectTokens(strlist: string[], msg?: string) : Token {
var tok = this.consumeToken();
var tokstr = tok.str;
if (strlist.indexOf(tokstr) < 0) {
this.compileError(msg || `There should be one of "${strlist}" here.`);
}
return tok;
}
peekToken(): Token { peekToken(): Token {
var tok = this.tokens[0]; var tok = this.tokens[0];
return tok ? tok : this.eol; return tok ? tok : this.eol;
@ -654,11 +663,10 @@ export class BASICParser {
var cond = this.parseExpr(); var cond = this.parseExpr();
var iftrue: Statement[]; var iftrue: Statement[];
// we accept GOTO or THEN if line number provided // we accept GOTO or THEN if line number provided
if (this.peekToken().str == 'GOTO') this.consumeToken(); var thengoto = this.expectTokens(['THEN','GOTO']);
else this.expectToken('THEN');
var lineno = this.peekToken(); var lineno = this.peekToken();
// assume GOTO if number given after THEN // assume GOTO if number given after THEN
if (lineno.type == TokenType.Int) { if (lineno.type == TokenType.Int && thengoto.str == 'THEN') {
this.pushbackToken({type:TokenType.Ident, str:'GOTO', $loc:lineno.$loc}); this.pushbackToken({type:TokenType.Ident, str:'GOTO', $loc:lineno.$loc});
} }
// add fake ":" // add fake ":"
@ -709,7 +717,7 @@ export class BASICParser {
var prompt = this.consumeToken(); var prompt = this.consumeToken();
var promptstr; var promptstr;
if (prompt.type == TokenType.String) { if (prompt.type == TokenType.String) {
this.expectToken(';'); this.expectTokens([';', ',']);
promptstr = stripQuotes(prompt.str); promptstr = stripQuotes(prompt.str);
} else { } else {
this.pushbackToken(prompt); this.pushbackToken(prompt);
@ -884,6 +892,7 @@ export const ECMA55_MINIMAL : BASICOptions = {
numericPadding : true, numericPadding : true,
checkOverflow : true, checkOverflow : true,
testInitialFor : true, testInitialFor : true,
optionalNextVar : false,
ifElse : false, ifElse : false,
bitwiseLogic : false, bitwiseLogic : false,
} }
@ -917,6 +926,7 @@ export const BASICODE : BASICOptions = {
numericPadding : true, numericPadding : true,
checkOverflow : true, checkOverflow : true,
testInitialFor : true, testInitialFor : true,
optionalNextVar : false,
ifElse : false, ifElse : false,
bitwiseLogic : false, bitwiseLogic : false,
} }
@ -952,6 +962,7 @@ export const ALTAIR_BASIC41 : BASICOptions = {
numericPadding : true, numericPadding : true,
checkOverflow : true, checkOverflow : true,
testInitialFor : false, testInitialFor : false,
optionalNextVar : true,
//multipleNextVars : true, // TODO: not supported //multipleNextVars : true, // TODO: not supported
ifElse : true, ifElse : true,
bitwiseLogic : true, bitwiseLogic : true,
@ -994,6 +1005,7 @@ export const APPLESOFT_BASIC : BASICOptions = {
numericPadding : false, numericPadding : false,
checkOverflow : true, checkOverflow : true,
testInitialFor : false, testInitialFor : false,
optionalNextVar : true,
ifElse : false, ifElse : false,
bitwiseLogic : false, bitwiseLogic : false,
} }
@ -1023,6 +1035,7 @@ export const MODERN_BASIC : BASICOptions = {
numericPadding : false, numericPadding : false,
checkOverflow : true, checkOverflow : true,
testInitialFor : true, testInitialFor : true,
optionalNextVar : true,
ifElse : true, ifElse : true,
bitwiseLogic : true, bitwiseLogic : true,
} }

View File

@ -423,7 +423,7 @@ export class BASICRuntime {
} }
nextForLoop(name) { nextForLoop(name) {
var fl = this.forLoops[name]; var fl = this.forLoops[name || (this.opts.optionalNextVar && this.topForLoopName)];
if (!fl) this.runtimeError(`I couldn't find a FOR for this NEXT.`) if (!fl) this.runtimeError(`I couldn't find a FOR for this NEXT.`)
fl.$next(name); fl.$next(name);
} }

View File

@ -179,7 +179,7 @@ class BASICPlatform implements Platform {
ForLoops: this.runtime.forLoops, ForLoops: this.runtime.forLoops,
ReturnStack: this.runtime.returnStack, ReturnStack: this.runtime.returnStack,
NextDatum: this.runtime.datums[this.runtime.dataptr], NextDatum: this.runtime.datums[this.runtime.dataptr],
Dialect: this.runtime.opts, Options: this.runtime.opts,
Internals: this.runtime, Internals: this.runtime,
} }
} }