basic: making function 'call' within the function-type argument sorta works when you strictly curry them; literal function call seems to return undefined or something (see assets/disk0/home/basic/sinc2.bas)

This commit is contained in:
minjaesong
2020-12-24 15:47:54 +09:00
parent 1c3e7c3c15
commit 85334beff8
3 changed files with 30 additions and 21 deletions

View File

@@ -5,12 +5,12 @@
110 Q=IF I==0 THEN 1.0 ELSE SIN(I)/I
120 RETURN
200 LABEL PLOTLINE:REM Converts 0-1 value into screen line. input is Q, results are stored to SQ
210 SQ=CHR(0)
210 SQ=""
220 FOR X=1 TO ZEROLINE+AMP
230 SQ=SQ+(IF X==ROUND(ZEROLINE+Q*AMP) THEN "@" ELSE IF X==10 THEN "|" ELSE CHR(250))
240 NEXT
250 RETURN
1000 FOR I=0 TO 20
1000 FOR I=-40 TO 40
1010 GOSUB SINCQ
1020 GOSUB PLOTLINE
1030 PRINT(SQ)

View File

@@ -3,15 +3,14 @@
10 DEFUN SINC(P)=IF P==0 THEN 1.0 ELSE SIN(P)/P
20 DEFUN TOCHAR(P,X)=IF (X==ROUND(ZEROLINE+P*AMP)) THEN "@" ELSE IF (X==ZEROLINE) THEN "|" ELSE CHR(250)
30 DEFUN SCONCAT(ACC,S)=ACC+S
40 REM DEFUN PLOTLINE(X)=FOLD(SCONCAT,CHR(0),MAP(TOCHAR<~X,1 TO ZEROLINE+AMP))
41 DEFUN PLOTLINE(F,X)=FOLD(SCONCAT,CHR(0),MAP(TOCHAR<~F(X),1 TO ZEROLINE+AMP))
100 FOR I=0 TO 20
110 PRINT PLOTLINE(SINC(I))
40 REM DEFUN PLOTLINE(X)=FOLD(SCONCAT,"",MAP(TOCHAR<~X,1 TO ZEROLINE+AMP))
41 REM PLOTLINE(F,X)=FOLD(SCONCAT,"",MAP(TOCHAR<~F(X),1 TO ZEROLINE+AMP)):REM does not work
42 DEFUN PLOTLINE(F,X)=FOLD(SCONCAT,"",MAP(TOCHAR<~F<~X,1 TO ZEROLINE+AMP)):REM WORKS!
100 FOR I=-40 TO 40
110 PRINT PLOTLINE(SINC,I)
120 NEXT
999 END
1000 REM Known bugs
1010 DEFUN PLOTLINE(F,X)=FOLD(SCONCAT,CHR(0),MAP(TOCHAR<~F(X),1 TO ZEROLINE+AMP))
1011 REM calling user-defined function within DEFUN is not working
1020 REM empty string literal "" is translated to number zero (another JS blunder)
1011 REM calling user-defined function within DEFUN is not working

View File

@@ -29,10 +29,10 @@ if (exec_args !== undefined && exec_args[1] !== undefined && exec_args[1].starts
return 0;
}
const PROD = true;
let INDEX_BASE = 0;
let TRACEON = false;
let DBGON = false;
let TRACEON = (!PROD) && true;
let DBGON = (!PROD) && true;
let DATA_CURSOR = 0;
let DATA_CONSTS = [];
const DEFUNS_BUILD_DEFUNS = true;
@@ -296,8 +296,9 @@ let resolve = function(variable) {
else
throw Error("BasicIntpError: unknown variable/object with type "+variable.troType+", with value "+variable.troValue);
}
let curryDefun = function(inputTree, value) {
let curryDefun = function(inputTree, inputValue) {
let exprTree = cloneObject(inputTree);
let value = cloneObject(inputValue);
bF._recurseApplyAST(exprTree, it => {
if (it.astType == "defun_args") {
if (DBGON) {
@@ -306,9 +307,18 @@ let curryDefun = function(inputTree, value) {
}
// apply arg0 into the tree
if (it.astValue == 0) {
it.astType = JStoBASICtype(value);
it.astValue = value;
let valueType = JStoBASICtype(value);
if (valueType === "usrdefun") {
it.astLnum = value.astLnum;
it.astLeaves = value.astLeaves;
it.astSeps = value.astSeps;
it.astValue = value.astValue
it.astType = value.astType;
}
else {
it.astType = valueType
it.astValue = value;
}
if (DBGON) {
serial.println("[curryDefun] applying value "+value);
}
@@ -1910,7 +1920,7 @@ bF.isSemanticLiteral = function(token, state) {
return undefined == token || "]" == token || ")" == token ||
"qot" == state || "num" == state || "bool" == state || "lit" == state;
}
bF.parserDoDebugPrint = false;
bF.parserDoDebugPrint = (!PROD) && true;
bF.parserPrintdbg = any => { if (bF.parserDoDebugPrint) serial.println(any) };
bF.parserPrintdbg2 = function(icon, lnum, tokens, states, recDepth) {
if (bF.parserDoDebugPrint) {
@@ -2602,10 +2612,10 @@ let JStoBASICtype = function(object) {
else if (object === undefined) return "null";
else if (object.arrName !== undefined) return "internal_arrindexing_lazy";
else if (object.asgnVarName !== undefined) return "internal_assignment_object";
else if (object instanceof ForGen) return "generator";
else if (object instanceof ForGen || object.start !== undefined && object.end !== undefined && typeof object.hasNext == "function") return "generator";
else if (object instanceof BasicAST || object.astLeaves !== undefined) return "usrdefun";
else if (Array.isArray(object)) return "array";
else if (!isNaN(object)) return "num";
else if (isNumable(object)) return "num";
else if (typeof object === "string" || object instanceof String) return "string";
// buncha error msgs
else throw Error("BasicIntpError: un-translatable object with typeof "+(typeof object)+",\ntoString = "+object+",\nentries = "+Object.entries(object));
@@ -2634,8 +2644,8 @@ bF._troNOP = function(lnum, stmtnum) { return new SyntaxTreeReturnObj("null", un
bF._executeSyntaxTree = function(lnum, stmtnum, syntaxTree, recDepth) {
if (lnum === undefined || stmtnum === undefined) throw Error(`Line or statement number is undefined: (${lnum},${stmtnum})`);
let _debugExec = false;
let _debugPrintCurrentLine = false;
let _debugExec = (!PROD) && true;
let _debugPrintCurrentLine = (!PROD) && true;
let recWedge = ">".repeat(recDepth) + " ";
if (_debugExec || _debugPrintCurrentLine) serial.println(recWedge+"@@ EXECUTE @@");