basic: DEFUN can call other DEFUN (different from currying it, currying would return a function, but calling would return a value)

This commit is contained in:
minjaesong
2020-12-27 12:36:48 +09:00
parent 83a53499bc
commit 29e08923cc
3 changed files with 50 additions and 18 deletions

View File

@@ -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.");
printerrln("No bootable medium found.");
println("CPU halted");

View File

@@ -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

View File

@@ -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]);