mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2025-02-16 17:30:27 +00:00
basic: fixed NEXT, expectTokens()
This commit is contained in:
parent
e962404c2f
commit
8fdd958859
@ -31,6 +31,7 @@ export interface BASICOptions {
|
||||
numericPadding : boolean; // " " or "-" before and " " after numbers?
|
||||
// CONTROL FLOW
|
||||
testInitialFor : boolean; // can we skip a NEXT statement? (can't interleave tho)
|
||||
optionalNextVar : boolean; // can do NEXT without variable
|
||||
ifElse : boolean; // IF...ELSE construct
|
||||
// MISC
|
||||
commandsPerSec? : number; // how many commands per second?
|
||||
@ -290,7 +291,7 @@ export class BASICParser {
|
||||
}
|
||||
compileError(msg: string, loc?: SourceLocation) {
|
||||
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?
|
||||
}
|
||||
dialectError(what: string, loc?: SourceLocation) {
|
||||
@ -308,6 +309,14 @@ export class BASICParser {
|
||||
}
|
||||
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 {
|
||||
var tok = this.tokens[0];
|
||||
return tok ? tok : this.eol;
|
||||
@ -654,11 +663,10 @@ export class BASICParser {
|
||||
var cond = this.parseExpr();
|
||||
var iftrue: Statement[];
|
||||
// we accept GOTO or THEN if line number provided
|
||||
if (this.peekToken().str == 'GOTO') this.consumeToken();
|
||||
else this.expectToken('THEN');
|
||||
var thengoto = this.expectTokens(['THEN','GOTO']);
|
||||
var lineno = this.peekToken();
|
||||
// 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});
|
||||
}
|
||||
// add fake ":"
|
||||
@ -709,7 +717,7 @@ export class BASICParser {
|
||||
var prompt = this.consumeToken();
|
||||
var promptstr;
|
||||
if (prompt.type == TokenType.String) {
|
||||
this.expectToken(';');
|
||||
this.expectTokens([';', ',']);
|
||||
promptstr = stripQuotes(prompt.str);
|
||||
} else {
|
||||
this.pushbackToken(prompt);
|
||||
@ -884,6 +892,7 @@ export const ECMA55_MINIMAL : BASICOptions = {
|
||||
numericPadding : true,
|
||||
checkOverflow : true,
|
||||
testInitialFor : true,
|
||||
optionalNextVar : false,
|
||||
ifElse : false,
|
||||
bitwiseLogic : false,
|
||||
}
|
||||
@ -917,6 +926,7 @@ export const BASICODE : BASICOptions = {
|
||||
numericPadding : true,
|
||||
checkOverflow : true,
|
||||
testInitialFor : true,
|
||||
optionalNextVar : false,
|
||||
ifElse : false,
|
||||
bitwiseLogic : false,
|
||||
}
|
||||
@ -952,6 +962,7 @@ export const ALTAIR_BASIC41 : BASICOptions = {
|
||||
numericPadding : true,
|
||||
checkOverflow : true,
|
||||
testInitialFor : false,
|
||||
optionalNextVar : true,
|
||||
//multipleNextVars : true, // TODO: not supported
|
||||
ifElse : true,
|
||||
bitwiseLogic : true,
|
||||
@ -994,6 +1005,7 @@ export const APPLESOFT_BASIC : BASICOptions = {
|
||||
numericPadding : false,
|
||||
checkOverflow : true,
|
||||
testInitialFor : false,
|
||||
optionalNextVar : true,
|
||||
ifElse : false,
|
||||
bitwiseLogic : false,
|
||||
}
|
||||
@ -1023,6 +1035,7 @@ export const MODERN_BASIC : BASICOptions = {
|
||||
numericPadding : false,
|
||||
checkOverflow : true,
|
||||
testInitialFor : true,
|
||||
optionalNextVar : true,
|
||||
ifElse : true,
|
||||
bitwiseLogic : true,
|
||||
}
|
||||
|
@ -423,7 +423,7 @@ export class BASICRuntime {
|
||||
}
|
||||
|
||||
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.`)
|
||||
fl.$next(name);
|
||||
}
|
||||
|
@ -179,7 +179,7 @@ class BASICPlatform implements Platform {
|
||||
ForLoops: this.runtime.forLoops,
|
||||
ReturnStack: this.runtime.returnStack,
|
||||
NextDatum: this.runtime.datums[this.runtime.dataptr],
|
||||
Dialect: this.runtime.opts,
|
||||
Options: this.runtime.opts,
|
||||
Internals: this.runtime,
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user