basic: parsing FOR statement, FOR itself still broken :(

This commit is contained in:
minjaesong
2020-12-13 11:19:08 +09:00
parent 5a09c4915d
commit e106327b4b
3 changed files with 66 additions and 13 deletions

View File

@@ -1619,6 +1619,7 @@ linenumber = digits ;
stmt = stmt =
"IF" , expr_sans_asgn , "THEN" , stmt , ["ELSE" , stmt] "IF" , expr_sans_asgn , "THEN" , stmt , ["ELSE" , stmt]
| "FOR" , expr
| "DEFUN" , [ident] , "(" , [ident , {" , " , ident}] , ")" , "=" , expr | "DEFUN" , [ident] , "(" , [ident , {" , " , ident}] , ")" , "=" , expr
| "ON" , expr_sans_asgn , ("GOTO" | "GOSUB") , expr_sans_asgn , {"," , expr_sans_asgn} | "ON" , expr_sans_asgn , ("GOTO" | "GOSUB") , expr_sans_asgn , {"," , expr_sans_asgn}
| "(" , stmt , ")" | "(" , stmt , ")"
@@ -1628,9 +1629,10 @@ expr = (* this basically blocks some funny attemps such as using DEFUN as anon f
lit lit
| "(" , expr , ")" | "(" , expr , ")"
| "IF" , expr_sans_asgn , "THEN" , expr , ["ELSE" , expr] | "IF" , expr_sans_asgn , "THEN" , expr , ["ELSE" , expr]
(* at this point, if OP is found in paren-level 0, skip function_call *)
| function_call
| expr , op , expr | expr , op , expr
| op_uni , expr | op_uni , expr ;
| function_call ;
expr_sans_asgn = ? identical to expr except errors out whenever "=" is found ? ; expr_sans_asgn = ? identical to expr except errors out whenever "=" is found ? ;
@@ -1680,6 +1682,9 @@ IF (type: function, value: IF)
2. true 2. true
[3. false] [3. false]
FOR (type: function, value: FOR)
1. expr (normally (=) but not necessarily)
DEFUN (type: function, value: DEFUN) DEFUN (type: function, value: DEFUN)
1. funcname 1. funcname
1. arg0 1. arg0
@@ -1723,7 +1728,7 @@ bF.parserPrintdbgline = function(icon, msg, lnum, recDepth) {
/** /**
* The starting point to parse those tokens * The starting point to parse those tokens
* @return: BasicAST * @return ARRAY of BasicAST
*/ */
bF._parseTokens = function(lnum, tokens, states) { bF._parseTokens = function(lnum, tokens, states) {
bF.parserPrintdbg2('Line ', lnum, tokens, states, 0); bF.parserPrintdbg2('Line ', lnum, tokens, states, 0);
@@ -1778,6 +1783,7 @@ bF._parseTokens = function(lnum, tokens, states) {
/** Parses following EBNF rule: /** Parses following EBNF rule:
stmt = stmt =
"IF" , expr_sans_asgn , "THEN" , stmt , ["ELSE" , stmt] "IF" , expr_sans_asgn , "THEN" , stmt , ["ELSE" , stmt]
| "FOR" , expr
| "DEFUN" , [ident] , "(" , [ident , {" , " , ident}] , ")" , "=" , expr | "DEFUN" , [ident] , "(" , [ident , {" , " , ident}] , ")" , "=" , expr
| "ON" , expr_sans_asgn , ident , expr_sans_asgn , {"," , expr_sans_asgn} | "ON" , expr_sans_asgn , ident , expr_sans_asgn , {"," , expr_sans_asgn}
| "(" , stmt , ")" | "(" , stmt , ")"
@@ -1847,6 +1853,25 @@ bF._parseStmt = function(lnum, tokens, states, recDepth) {
/*************************************************************************/ /*************************************************************************/
// ## case for:
// | "FOR" , expr
if ("FOR" == headTkn && "lit" == headSta) {
bF.parserPrintdbgline('$', 'FOR Stmt', lnum, recDepth);
treeHead.astValue = "FOR";
treeHead.astType = "function";
treeHead.astLeaves[0] = bF._parseExpr(lnum,
tokens.slice(1, tokens.length),
states.slice(1, states.length),
recDepth + 1
);
return treeHead;
}
/*************************************************************************/
// ## case for: // ## case for:
// | "DEFUN" , [ident] , "(" , [ident , {" , " , ident}] , ")" , "=" , expr // | "DEFUN" , [ident] , "(" , [ident , {" , " , ident}] , ")" , "=" , expr
if ("DEFUN" == headTkn && "lit" == headSta && if ("DEFUN" == headTkn && "lit" == headSta &&
@@ -2553,6 +2578,9 @@ bF._executeAndGet = function(lnum, syntaxTree) {
// EXECUTE // EXECUTE
try { try {
var execResult = bF._executeSyntaxTree(lnum, syntaxTree, 0); var execResult = bF._executeSyntaxTree(lnum, syntaxTree, 0);
serial.println(`Line ${lnum} TRO: ${Object.entries(execResult)}`);
return execResult.troNextLine; return execResult.troNextLine;
} }
catch (e) { catch (e) {

View File

@@ -56,11 +56,15 @@ bF._parseTokens = function(lnum, tokens, states) {
// check for empty tokens // check for empty tokens
if (x.end - x.start <= 0) throw new ParserError("Malformed Line"); if (x.end - x.start <= 0) throw new ParserError("Malformed Line");
return bF._parseStmt(lnum, let tree = bF._parseStmt(lnum,
tokens.slice(x.start, x.end), tokens.slice(x.start, x.end),
states.slice(x.start, x.end), states.slice(x.start, x.end),
1 1
); );
bF.parserPrintdbgline('Tree in ', '\n'+astToString(tree), lnum, 0);
return tree;
}); });
} }
@@ -68,6 +72,7 @@ bF._parseTokens = function(lnum, tokens, states) {
/** Parses following EBNF rule: /** Parses following EBNF rule:
stmt = stmt =
"IF" , expr_sans_asgn , "THEN" , stmt , ["ELSE" , stmt] "IF" , expr_sans_asgn , "THEN" , stmt , ["ELSE" , stmt]
| "FOR" , expr
| "DEFUN" , [ident] , "(" , [ident , {" , " , ident}] , ")" , "=" , expr | "DEFUN" , [ident] , "(" , [ident , {" , " , ident}] , ")" , "=" , expr
| "ON" , expr_sans_asgn , ident , expr_sans_asgn , {"," , expr_sans_asgn} | "ON" , expr_sans_asgn , ident , expr_sans_asgn , {"," , expr_sans_asgn}
| "(" , stmt , ")" | "(" , stmt , ")"
@@ -135,6 +140,26 @@ bF._parseStmt = function(lnum, tokens, states, recDepth) {
if (!(e instanceof ParserError)) throw e; if (!(e instanceof ParserError)) throw e;
} }
/*************************************************************************/
// ## case for:
// | "FOR" , expr
if ("FOR" == headTkn && "lit" == headSta) {
bF.parserPrintdbgline('$', 'FOR Stmt', lnum, recDepth);
treeHead.astValue = "FOR";
treeHead.astType = "function";
treeHead.astLeaves[0] = bF._parseExpr(lnum,
tokens.slice(1, tokens.length),
states.slice(1, states.length),
recDepth + 1
);
return treeHead;
}
/*************************************************************************/ /*************************************************************************/
// ## case for: // ## case for:

View File

@@ -7,7 +7,7 @@ linenumber = digits ;
stmt = stmt =
"IF" , expr_sans_asgn , "THEN" , stmt , ["ELSE" , stmt] "IF" , expr_sans_asgn , "THEN" , stmt , ["ELSE" , stmt]
| "FOR" , expr // TODO | "FOR" , expr
| "DEFUN" , [ident] , "(" , [ident , {" , " , ident}] , ")" , "=" , expr | "DEFUN" , [ident] , "(" , [ident , {" , " , ident}] , ")" , "=" , expr
| "ON" , expr_sans_asgn , ("GOTO" | "GOSUB") , expr_sans_asgn , {"," , expr_sans_asgn} | "ON" , expr_sans_asgn , ("GOTO" | "GOSUB") , expr_sans_asgn , {"," , expr_sans_asgn}
| "(" , stmt , ")" | "(" , stmt , ")"