basic: ON statement, DO with GOTO at the end will work now

This commit is contained in:
minjaesong
2020-12-16 11:44:01 +09:00
parent 615db3b2ad
commit 5b3d569d06
3 changed files with 41 additions and 6 deletions

View File

@@ -1114,8 +1114,7 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
},
/* GOTO and GOSUB won't work but that's probably the best...? */
"DO" : function(lnum, stmtnum, args) {
//return resolve(args[args.length - 1]);
return undefined;
return args[args.length - 1];
},
"LABEL" : function(lnum, stmtnum, args) {
let labelname = args[0].troValue;
@@ -1123,6 +1122,24 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
if (labelname === undefined) throw lang.syntaxfehler(lnum, "empty LABEL");
gotoLabels[labelname] = lnum;
},
"ON" : function(lnum, stmtnum, args) {
//args: functionName (string), testvalue (SyntaxTreeReturnObj), arg0 (SyntaxTreeReturnObj), arg1 (SyntaxTreeReturnObj), ...
if (args[2] === undefined) throw lang.syntaxfehler(lnum);
let jmpFun = args.shift();
let testvalue = resolve(args.shift())-INDEX_BASE;
// args must be resolved lazily because jump label is not resolvable
let jmpTarget = args[testvalue];
if (jmpFun !== "GOTO" && jmpFun !== "GOSUB")
throw lang.badFunctionCallFormat(`Not a jump statement: ${jmpFun}`)
if (jmpTarget === undefined)
return undefined;
return bStatus.builtin[jmpFun](lnum, stmtnum, [jmpTarget]);
},
"OPTIONDEBUG" : function(lnum, stmtnum, args) {
return oneArgNum(lnum, stmtnum, args, (lh) => {
if (lh != 0 && lh != 1) throw lang.syntaxfehler(line);
@@ -2258,7 +2275,7 @@ bF._parseIfMode = function(lnum, tokens, states, recDepth, exprMode) {
if ("IF" == headTkn && "lit" == headSta) {
// "THEN" not found, raise error!
if (thenPos == -1) throw new ParserError("IF without THEN in " + lnum);
if (thenPos == -1) throw lang.syntaxfehler(lnum, "IF without THEN");
treeHead.astValue = "IF";
treeHead.astType = "function";
@@ -2550,11 +2567,11 @@ bF._executeSyntaxTree = function(lnum, stmtnum, syntaxTree, recDepth) {
let testValue = bF._executeSyntaxTree(lnum, stmtnum, syntaxTree.astLeaves[0], recDepth + 1);
let functionName = syntaxTree.astLeaves[1].astValue;
let arrays = [];
for (let k = 2; k < astLeaves.length; k++)
for (let k = 2; k < syntaxTree.astLeaves.length; k++)
arrays.push(bF._executeSyntaxTree(lnum, stmtnum, syntaxTree.astLeaves[k], recDepth + 1));
try {
let r = bStatus.builtin["ON"](lnum, stmtnum, [testValue].concat(arrays))
let r = bStatus.builtin["ON"](lnum, stmtnum, [functionName, testValue].concat(arrays))
return new SyntaxTreeReturnObj(JStoBASICtype(r.jmpReturningValue), r.jmpReturningValue, r.jmpNext);
}
catch (e) {
@@ -2592,6 +2609,9 @@ bF._executeSyntaxTree = function(lnum, stmtnum, syntaxTree, recDepth) {
// call whatever the 'func' has whether it's builtin or we just made shit up right above
try {
let funcCallResult = func(lnum, stmtnum, args, syntaxTree.astSeps);
if (funcCallResult instanceof SyntaxTreeReturnObj) return funcCallResult;
let retVal = (funcCallResult instanceof JumpObj) ? funcCallResult.jmpReturningValue : funcCallResult;
return new SyntaxTreeReturnObj(

15
assets/onlabeltest.bas Normal file
View File

@@ -0,0 +1,15 @@
1 OPTIONBASE 1
2 GOTO STARTPOINT
100 LABEL PRINTA
110 PRINT "A"
120 RETURN
200 LABEL PRINTB
210 PRINT "B":PRINT "B"
220 RETURN
300 LABEL PRINTC
310 PRINT "C":PRINT 2+2
320 RETURN
1000 INPUT K:LABEL STARTPOINT
1001 IF K>3 OR K<1 THEN DO(PRINT "INPUT MUST BE 1,2 OR 3";GOTO STARTPOINT)
1010 ON K GOSUB PRINTA,PRINTB,PRINTC
1020 PRINT "BYE"

View File

@@ -530,7 +530,7 @@ bF._parseIfMode = function(lnum, tokens, states, recDepth, exprMode) {
if ("IF" == headTkn && "lit" == headSta) {
// "THEN" not found, raise error!
if (thenPos == -1) throw new ParserError("IF without THEN in " + lnum);
if (thenPos == -1) throw lang.syntaxfehler(lnum, "IF without THEN");
treeHead.astValue = "IF";
treeHead.astType = "function";