From 29e08923ccf64befada6498887e7a124e04075ff Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sun, 27 Dec 2020 12:36:48 +0900 Subject: [PATCH] basic: DEFUN can call other DEFUN (different from currying it, currying would return a function, but calling would return a value) --- assets/bios/tbasdist.js | 6 +-- assets/disk0/home/basic/usrapply.bas | 4 +- assets/disk0/tbas/basic.js | 58 +++++++++++++++++++++------- 3 files changed, 50 insertions(+), 18 deletions(-) diff --git a/assets/bios/tbasdist.js b/assets/bios/tbasdist.js index 3ec97a1..f0dcb4a 100644 --- a/assets/bios/tbasdist.js +++ b/assets/bios/tbasdist.js @@ -27,15 +27,15 @@ if (r == 0){ let g=com.pullMessage(0); let execAppPrg = eval("var _appStub=function(exec_args){"+g+"};_appStub;"); // making 'exec_args' a app-level global execAppPrg(); - return 0; } catch (e) { printerrln("\nApp Execution Error: "+(e.stack || e)); - return 1; } } else printerrln("I/O Error"); } else - printerrln("No bootable medium found."); \ No newline at end of file + printerrln("No bootable medium found."); + +println("CPU halted"); \ No newline at end of file diff --git a/assets/disk0/home/basic/usrapply.bas b/assets/disk0/home/basic/usrapply.bas index a01be20..38df331 100644 --- a/assets/disk0/home/basic/usrapply.bas +++ b/assets/disk0/home/basic/usrapply.bas @@ -1,7 +1,7 @@ 1 OPTIONDEBUG 1:OPTIONTRACE 1 -10 DEFUN APPLY(X,F)=F(X):REM bug- F<~X must return function and F(X) must return value but right now they both return a function? +10 DEFUN APPLY(F,X)=F(X) 20 DEFUN FUN(X)=X^2 -30 K=APPLY(42,FUN) +30 K=APPLY(FUN,42) 100 PRINT K 110 PRINT TYPEOF K 120 RESOLVE K diff --git a/assets/disk0/tbas/basic.js b/assets/disk0/tbas/basic.js index 8da6238..6a78e2d 100644 --- a/assets/disk0/tbas/basic.js +++ b/assets/disk0/tbas/basic.js @@ -29,7 +29,9 @@ if (exec_args !== undefined && exec_args[1] !== undefined && exec_args[1].starts return 0; } -const PROD = false; +const THEVERSION = "1.0"; + +const PROD = true; let INDEX_BASE = 0; let TRACEON = (!PROD) && true; let DBGON = (!PROD) && true; @@ -213,7 +215,7 @@ let reNumber = /([0-9]*[.][0-9]+[eE]*[\-+0-9]*[fF]*|[0-9]+[.eEfF][0-9+\-]*[fF]?) let reNum = /[0-9]+/; let tbasexit = false; -const greetText = "Terran BASIC 1.0 "+String.fromCharCode(179)+" Scratchpad Memory: "+vmemsize+" bytes"; +const greetText = `Terran BASIC ${THEVERSION} `+String.fromCharCode(179)+" Scratchpad Memory: "+vmemsize+" bytes"; const greetLeftPad = (80 - greetText.length) >> 1; const greetRightPad = 80 - greetLeftPad - greetText.length; @@ -301,10 +303,10 @@ let curryDefun = function(inputTree, inputValue) { let value = cloneObject(inputValue); bF._recurseApplyAST(exprTree, it => { if (it.astType == "defun_args") { - if (DBGON) { + /*if (DBGON) { serial.println("[curryDefun] found defun_args #"+it.astValue); serial.println(astToString(it)); - } + }*/ // apply arg0 into the tree if (it.astValue == 0) { let valueType = JStoBASICtype(value); @@ -319,23 +321,18 @@ let curryDefun = function(inputTree, inputValue) { it.astType = valueType it.astValue = value; } - if (DBGON) { - serial.println("[curryDefun] applying value "+value); - } + //if (DBGON) serial.println("[curryDefun] applying value "+value); } // shift down arg index else { it.astValue -= 1; - - if (DBGON) { - serial.println("[curryDefun] decrementing arg index"); - } + //if (DBGON) serial.println("[curryDefun] decrementing arg index"); } - if (DBGON) { + /*if (DBGON) { serial.println("[curryDefun] after the task:"); serial.println(astToString(it)); - } + }*/ } }); @@ -2824,6 +2821,41 @@ bF._executeSyntaxTree = function(lnum, stmtnum, syntaxTree, recDepth) { [lnum, stmtnum + 1] ); } + // userdefun with args + // apply given arguments (syntaxTree.astLeaves) to the expression tree and evaluate it + // if tree has leaves and their leaves are all terminal leaves (does not have grandchild AND they are not usrdefun) + else if (syntaxTree.astType == "usrdefun" && syntaxTree.astLeaves[0] !== undefined && + syntaxTree.astLeaves.every(child => child.astLeaves[0] == undefined && child.astType !== "usrdefun")) { + let oldTree = syntaxTree.astValue; + let argsTro = syntaxTree.astLeaves.map(it => bF._executeSyntaxTree(lnum, stmtnum, it, recDepth + 1)); + let newTree = oldTree; // curryDefun() will make a clone of it for us + for (let k = 0; k < argsTro.length; k++) { + newTree = curryDefun(oldTree, argsTro[k].troValue); + } + + // make a javascript function out of the new tree, thess lines are now basically the same as above function calling lines + let func = bStatus.getDefunThunk(lnum, stmtnum, newTree); + + // call whatever the 'func' has whether it's builtin or we just made shit up right above + try { + //let funcCallResult = func(lnum, stmtnum, argsTro, syntaxTree.astSeps); + let funcCallResult = func(lnum, stmtnum, [], syntaxTree.astSeps); + + if (funcCallResult instanceof SyntaxTreeReturnObj) return funcCallResult; + + let retVal = (funcCallResult instanceof JumpObj) ? funcCallResult.jmpReturningValue : funcCallResult; + + return new SyntaxTreeReturnObj( + JStoBASICtype(retVal), + retVal, + (funcCallResult instanceof JumpObj) ? funcCallResult.jmpNext : [lnum, stmtnum + 1] + ); + } + catch (e) { + serial.printerr(`${e}\n${e.stack || "Stack trace undefined"}`); + throw lang.errorinline(lnum, (funcName === undefined) ? "undefined" : funcName, (e === undefined) ? "undefined" : e); + } + } else if (syntaxTree.astType == "num") { if (_debugExec) serial.println(recWedge+"num "+((syntaxTree.astValue)*1)); return new SyntaxTreeReturnObj(syntaxTree.astType, (syntaxTree.astValue)*1, [lnum, stmtnum + 1]);