basic: trying to solve why currying does not work as it should do in recursive function

This commit is contained in:
minjaesong
2020-12-21 17:50:27 +09:00
parent e11038254a
commit 8600207e34
4 changed files with 69 additions and 15 deletions

View File

@@ -285,6 +285,14 @@ let curryDefun = function(exprTree, value) {
}
}
});
if (DBGON) {
serial.println("[BASIC.curryDefun] currying value: "+value);
serial.println(Object.entries(value));
serial.println("[BASIC.curryDefun] curried expression tree:");
serial.println(astToString(exprTree));
}
return exprTree;
}
let argCheckErr = function(lnum, o) {
@@ -504,7 +512,9 @@ bStatus.getDefunThunk = function(lnum, stmtnum, exprTree) {
}).forEach(arg => argsMap.push(arg));
if (DBGON) {
serial.println("[BASIC.getDefunThunk] thunk args:");
serial.println("[BASIC.getDefunThunk.invoke] unthunking: ");
serial.println(astToString(tree));
serial.println("[BASIC.getDefunThunk.invoke] thunk args:");
serial.println(argsMap);
}
@@ -512,7 +522,7 @@ bStatus.getDefunThunk = function(lnum, stmtnum, exprTree) {
bF._recurseApplyAST(tree, (it) => {
if ("defun_args" == it.astType) {
if (DBGON) {
serial.println("[BASIC.getDefunThunk] thunk renamed arg tree brance:");
serial.println("[BASIC.getDefunThunk.invoke] thunk renaming arg-tree branch:");
serial.println(astToString(it));
}
@@ -520,14 +530,24 @@ bStatus.getDefunThunk = function(lnum, stmtnum, exprTree) {
let theArg = argsMap[argsIndex]; // instanceof theArg == resolved version of SyntaxTreeReturnObj
if (theArg !== undefined) { // this "forgiveness" is required to implement currying
if (DBGON) {
serial.println("[BASIC.getDefunThunk.invoke] thunk renaming-theArg: "+theArg);
serial.println(Object.entries(theArg));
}
it.astValue = theArg;
it.astType = JStoBASICtype(theArg);
}
if (DBGON) {
serial.println("[BASIC.getDefunThunk.invoke] thunk successfully renamed arg-tree branch:");
serial.println(astToString(it));
}
}
});
if (DBGON) {
serial.println("[BASIC.getDefunThunk] thunk tree:");
serial.println("[BASIC.getDefunThunk.invoke] resulting thunk tree:");
serial.println(astToString(tree));
}
@@ -1142,6 +1162,19 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
return akku;
});
},
/* Syopsis: FILTER function, functor
*/
"FILTER" : function(lnum, stmtnum, args) {
return twoArg(lnum, stmtnum, args, (fn, functor) => {
// TODO test only works with DEFUN'd functions
if (fn.astLeaves === undefined) throw lang.badFunctionCallFormat("Only works with DEFUN'd functions yet");
if (functor.toArray === undefined && !Array.isArray(functor)) throw lang.syntaxfehler(lnum, functor);
// generator?
if (functor.toArray) functor = functor.toArray();
return functor.filter(it => bStatus.getDefunThunk(lnum, stmtnum, fn)(lnum, stmtnum, [it]));
});
},
/* GOTO and GOSUB won't work but that's probably the best...? */
"DO" : function(lnum, stmtnum, args) {
return args[args.length - 1];
@@ -1193,6 +1226,12 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
"CURRY" : function(lnum, stmtnum, args) {
return twoArg(lnum, stmtnum, args, (fn, arg0) => {
if (fn.astLeaves === undefined) throw lang.badFunctionCallFormat("Not a Function");
if (DBGON) {
serial.println("[BASIC.CURRY] currying "+args[0].troValue+" with "+arg0);
serial.println("args[1] = "+Object.entries(args[1]));
}
curryDefun(fn, arg0);
return fn;
});
@@ -2589,9 +2628,9 @@ bF._executeSyntaxTree = function(lnum, stmtnum, syntaxTree, recDepth) {
else
return bF._troNOP(lnum, stmtnum);
}
catch (eeeee) {
catch (e) {
serial.printerr(`${e}\n${e.stack || "Stack trace undefined"}`);
throw lang.errorinline(lnum, "TEST", eeeee);
throw lang.errorinline(lnum, "TEST", e);
}
}
else if ("DEFUN" == funcName) {
@@ -2610,7 +2649,7 @@ bF._executeSyntaxTree = function(lnum, stmtnum, syntaxTree, recDepth) {
// rename the parametres
bF._recurseApplyAST(exprTree, (it) => {
if (it.astType == "lit") {
if (it.astType == "lit" || it.astType == "function") {
// check if parametre name is valid
// if the name is invalid, regard it as a global variable (i.e. do nothing)
if (defunRenamingMap[it.astValue] !== undefined) {
@@ -2621,13 +2660,14 @@ bF._executeSyntaxTree = function(lnum, stmtnum, syntaxTree, recDepth) {
});
// test print new tree
//serial.println("[BASIC.DEFUN] defun debug info for function "+defunName);
//serial.println("[BASIC.DEFUN] defun name tree: ");
//serial.println(astToString(nameTree));
//serial.println("[BASIC.DEFUN] defun renaming map: "+Object.entries(defunRenamingMap));
//serial.println("[BASIC.DEFUN] defun expression tree:");
//serial.println(astToString(exprTree));
if (DBGON) {
serial.println("[BASIC.DEFUN] defun debug info for function "+defunName);
serial.println("[BASIC.DEFUN] defun name tree: ");
serial.println(astToString(nameTree));
serial.println("[BASIC.DEFUN] defun renaming map: "+Object.entries(defunRenamingMap));
serial.println("[BASIC.DEFUN] defun expression tree:");
serial.println(astToString(exprTree));
}
// check if the variable name already exists
// search from constants
if (_basicConsts[defunName]) throw lang.asgnOnConst(lnum, defunName);
@@ -2709,8 +2749,8 @@ bF._executeSyntaxTree = function(lnum, stmtnum, syntaxTree, recDepth) {
if (_debugExec) serial.println(recWedge+"num");
return new SyntaxTreeReturnObj(syntaxTree.astType, (syntaxTree.astValue)*1, [lnum, stmtnum + 1]);
}
else if (syntaxTree.astType == "string" || syntaxTree.astType == "lit" || syntaxTree.astType == "bool") {
if (_debugExec) serial.println(recWedge+"string|literal|bool");
else if (syntaxTree.astType == "lit" || literalTypes.includes(syntaxTree.astType)) {
if (_debugExec) serial.println(recWedge+"literal|string|bool|array");
return new SyntaxTreeReturnObj(syntaxTree.astType, syntaxTree.astValue, [lnum, stmtnum + 1]);
}
else if (syntaxTree.astType == "null") {

4
assets/curryarray.bas Normal file
View File

@@ -0,0 +1,4 @@
1 KS=4!1!2!5!3!NIL
10 DEFUN LESSER(P,X)=X<P
11 KLS=CURRY(LESSER,KS(0))
20 PRINT KLS(6)

4
assets/filtercurry.bas Normal file
View File

@@ -0,0 +1,4 @@
1 XS=4!1!2!3!5!NIL
10 DEFUN K(P,X)=X<P
20 NXS=FILTER(CURRY(K,XS(0)),XS)
30 PRINT NXS

6
assets/qsort.bas Normal file
View File

@@ -0,0 +1,6 @@
10 DEFUN LESSER(P,X)=X<P
11 DEFUN GTEQ(P,X)=X>=P
12 DEFUN QSORT(XS)=IF LEN(XS)<1 THEN NIL ELSE QSORT(FILTER(CURRY(LESSER,XS(0)),XS)) # XS(0)!NIL # QSORT(FILTER(CURRY(GTEQ,XS(0)),XS))
100 L=7!9!4!5!2!3!1!8!6!NIL
110 SL=QSORT(L)
120 PRINT L:PRINT SL