From 5b3d569d06bcd642fb901d630f5dfca3b2ea23b8 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Wed, 16 Dec 2020 11:44:01 +0900 Subject: [PATCH] basic: ON statement, DO with GOTO at the end will work now --- assets/basic.js | 30 +++++++++++++++++++++++++----- assets/onlabeltest.bas | 15 +++++++++++++++ assets/tbas/parser_wip.js | 2 +- 3 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 assets/onlabeltest.bas diff --git a/assets/basic.js b/assets/basic.js index fbf1c98..31046eb 100644 --- a/assets/basic.js +++ b/assets/basic.js @@ -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( diff --git a/assets/onlabeltest.bas b/assets/onlabeltest.bas new file mode 100644 index 0000000..1704646 --- /dev/null +++ b/assets/onlabeltest.bas @@ -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" diff --git a/assets/tbas/parser_wip.js b/assets/tbas/parser_wip.js index 7495505..300678f 100644 --- a/assets/tbas/parser_wip.js +++ b/assets/tbas/parser_wip.js @@ -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";