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:
parent
e962404c2f
commit
8fdd958859
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user