mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-09 06:34:04 +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;
|
return exprTree;
|
||||||
}
|
}
|
||||||
let argCheckErr = function(lnum, o) {
|
let argCheckErr = function(lnum, o) {
|
||||||
@@ -504,7 +512,9 @@ bStatus.getDefunThunk = function(lnum, stmtnum, exprTree) {
|
|||||||
}).forEach(arg => argsMap.push(arg));
|
}).forEach(arg => argsMap.push(arg));
|
||||||
|
|
||||||
if (DBGON) {
|
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);
|
serial.println(argsMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -512,7 +522,7 @@ bStatus.getDefunThunk = function(lnum, stmtnum, exprTree) {
|
|||||||
bF._recurseApplyAST(tree, (it) => {
|
bF._recurseApplyAST(tree, (it) => {
|
||||||
if ("defun_args" == it.astType) {
|
if ("defun_args" == it.astType) {
|
||||||
if (DBGON) {
|
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));
|
serial.println(astToString(it));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -520,14 +530,24 @@ bStatus.getDefunThunk = function(lnum, stmtnum, exprTree) {
|
|||||||
let theArg = argsMap[argsIndex]; // instanceof theArg == resolved version of SyntaxTreeReturnObj
|
let theArg = argsMap[argsIndex]; // instanceof theArg == resolved version of SyntaxTreeReturnObj
|
||||||
|
|
||||||
if (theArg !== undefined) { // this "forgiveness" is required to implement currying
|
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.astValue = theArg;
|
||||||
it.astType = JStoBASICtype(theArg);
|
it.astType = JStoBASICtype(theArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DBGON) {
|
||||||
|
serial.println("[BASIC.getDefunThunk.invoke] thunk successfully renamed arg-tree branch:");
|
||||||
|
serial.println(astToString(it));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (DBGON) {
|
if (DBGON) {
|
||||||
serial.println("[BASIC.getDefunThunk] thunk tree:");
|
serial.println("[BASIC.getDefunThunk.invoke] resulting thunk tree:");
|
||||||
serial.println(astToString(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;
|
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...? */
|
/* GOTO and GOSUB won't work but that's probably the best...? */
|
||||||
"DO" : function(lnum, stmtnum, args) {
|
"DO" : function(lnum, stmtnum, args) {
|
||||||
return args[args.length - 1];
|
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) {
|
"CURRY" : function(lnum, stmtnum, args) {
|
||||||
return twoArg(lnum, stmtnum, args, (fn, arg0) => {
|
return twoArg(lnum, stmtnum, args, (fn, arg0) => {
|
||||||
if (fn.astLeaves === undefined) throw lang.badFunctionCallFormat("Not a Function");
|
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);
|
curryDefun(fn, arg0);
|
||||||
return fn;
|
return fn;
|
||||||
});
|
});
|
||||||
@@ -2589,9 +2628,9 @@ bF._executeSyntaxTree = function(lnum, stmtnum, syntaxTree, recDepth) {
|
|||||||
else
|
else
|
||||||
return bF._troNOP(lnum, stmtnum);
|
return bF._troNOP(lnum, stmtnum);
|
||||||
}
|
}
|
||||||
catch (eeeee) {
|
catch (e) {
|
||||||
serial.printerr(`${e}\n${e.stack || "Stack trace undefined"}`);
|
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) {
|
else if ("DEFUN" == funcName) {
|
||||||
@@ -2610,7 +2649,7 @@ bF._executeSyntaxTree = function(lnum, stmtnum, syntaxTree, recDepth) {
|
|||||||
|
|
||||||
// rename the parametres
|
// rename the parametres
|
||||||
bF._recurseApplyAST(exprTree, (it) => {
|
bF._recurseApplyAST(exprTree, (it) => {
|
||||||
if (it.astType == "lit") {
|
if (it.astType == "lit" || it.astType == "function") {
|
||||||
// check if parametre name is valid
|
// check if parametre name is valid
|
||||||
// if the name is invalid, regard it as a global variable (i.e. do nothing)
|
// if the name is invalid, regard it as a global variable (i.e. do nothing)
|
||||||
if (defunRenamingMap[it.astValue] !== undefined) {
|
if (defunRenamingMap[it.astValue] !== undefined) {
|
||||||
@@ -2621,13 +2660,14 @@ bF._executeSyntaxTree = function(lnum, stmtnum, syntaxTree, recDepth) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// test print new tree
|
// test print new tree
|
||||||
//serial.println("[BASIC.DEFUN] defun debug info for function "+defunName);
|
if (DBGON) {
|
||||||
//serial.println("[BASIC.DEFUN] defun name tree: ");
|
serial.println("[BASIC.DEFUN] defun debug info for function "+defunName);
|
||||||
//serial.println(astToString(nameTree));
|
serial.println("[BASIC.DEFUN] defun name tree: ");
|
||||||
//serial.println("[BASIC.DEFUN] defun renaming map: "+Object.entries(defunRenamingMap));
|
serial.println(astToString(nameTree));
|
||||||
//serial.println("[BASIC.DEFUN] defun expression tree:");
|
serial.println("[BASIC.DEFUN] defun renaming map: "+Object.entries(defunRenamingMap));
|
||||||
//serial.println(astToString(exprTree));
|
serial.println("[BASIC.DEFUN] defun expression tree:");
|
||||||
|
serial.println(astToString(exprTree));
|
||||||
|
}
|
||||||
// check if the variable name already exists
|
// check if the variable name already exists
|
||||||
// search from constants
|
// search from constants
|
||||||
if (_basicConsts[defunName]) throw lang.asgnOnConst(lnum, defunName);
|
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");
|
if (_debugExec) serial.println(recWedge+"num");
|
||||||
return new SyntaxTreeReturnObj(syntaxTree.astType, (syntaxTree.astValue)*1, [lnum, stmtnum + 1]);
|
return new SyntaxTreeReturnObj(syntaxTree.astType, (syntaxTree.astValue)*1, [lnum, stmtnum + 1]);
|
||||||
}
|
}
|
||||||
else if (syntaxTree.astType == "string" || syntaxTree.astType == "lit" || syntaxTree.astType == "bool") {
|
else if (syntaxTree.astType == "lit" || literalTypes.includes(syntaxTree.astType)) {
|
||||||
if (_debugExec) serial.println(recWedge+"string|literal|bool");
|
if (_debugExec) serial.println(recWedge+"literal|string|bool|array");
|
||||||
return new SyntaxTreeReturnObj(syntaxTree.astType, syntaxTree.astValue, [lnum, stmtnum + 1]);
|
return new SyntaxTreeReturnObj(syntaxTree.astType, syntaxTree.astValue, [lnum, stmtnum + 1]);
|
||||||
}
|
}
|
||||||
else if (syntaxTree.astType == "null") {
|
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