mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 19:51:51 +09:00
basic: trying to solve why currying does not work as it should do in recursive function
This commit is contained in:
@@ -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
4
assets/curryarray.bas
Normal 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
4
assets/filtercurry.bas
Normal 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
6
assets/qsort.bas
Normal 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
|
||||
Reference in New Issue
Block a user