mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-10 06:54:04 +09:00
basic: NEXT of FOR loop now works but now unary op is not parsed correctly
This commit is contained in:
@@ -869,7 +869,6 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
|
|||||||
var varname = asgnObj.asgnVarName;
|
var varname = asgnObj.asgnVarName;
|
||||||
var generator = asgnObj.asgnValue;
|
var generator = asgnObj.asgnValue;
|
||||||
|
|
||||||
|
|
||||||
// assign new variable
|
// assign new variable
|
||||||
// the var itself will have head of the array, and the head itself will be removed from the array
|
// the var itself will have head of the array, and the head itself will be removed from the array
|
||||||
bStatus.vars[varname] = new BasicVar(generator.start, "num");
|
bStatus.vars[varname] = new BasicVar(generator.start, "num");
|
||||||
@@ -1732,7 +1731,9 @@ bF.parserPrintdbgline = function(icon, msg, lnum, recDepth) {
|
|||||||
*/
|
*/
|
||||||
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);
|
||||||
|
|
||||||
|
if (tokens.length !== states.length) throw lang.syntaxfehler(lnum);
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
let parenDepth = 0;
|
let parenDepth = 0;
|
||||||
@@ -1801,6 +1802,16 @@ bF._parseStmt = function(lnum, tokens, states, recDepth) {
|
|||||||
let treeHead = new BasicAST();
|
let treeHead = new BasicAST();
|
||||||
treeHead.astLnum = lnum;
|
treeHead.astLnum = lnum;
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
// case for: single word (e.g. NEXT for FOR loop)
|
||||||
|
if (tokens.length == 1 && states.length == 1) {
|
||||||
|
bF.parserPrintdbgline('$', "Single Word Function Call", lnum, recDepth);
|
||||||
|
return bF._parseLit(lnum, tokens, states, recDepth + 1, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
let parenDepth = 0;
|
let parenDepth = 0;
|
||||||
let parenStart = -1;
|
let parenStart = -1;
|
||||||
let parenEnd = -1;
|
let parenEnd = -1;
|
||||||
@@ -2341,7 +2352,7 @@ bF._parseIdent = function(lnum, tokens, states, recDepth) {
|
|||||||
/**
|
/**
|
||||||
* @return: BasicAST
|
* @return: BasicAST
|
||||||
*/
|
*/
|
||||||
bF._parseLit = function(lnum, tokens, states, recDepth) {
|
bF._parseLit = function(lnum, tokens, states, recDepth, functionMode) {
|
||||||
bF.parserPrintdbg2(String.fromCharCode(0xA2), lnum, tokens, states, recDepth);
|
bF.parserPrintdbg2(String.fromCharCode(0xA2), lnum, tokens, states, recDepth);
|
||||||
|
|
||||||
if (!Array.isArray(tokens) && !Array.isArray(states)) throw new ParserError("Tokens and states are not array");
|
if (!Array.isArray(tokens) && !Array.isArray(states)) throw new ParserError("Tokens and states are not array");
|
||||||
@@ -2350,7 +2361,7 @@ bF._parseLit = function(lnum, tokens, states, recDepth) {
|
|||||||
let treeHead = new BasicAST();
|
let treeHead = new BasicAST();
|
||||||
treeHead.astLnum = lnum;
|
treeHead.astLnum = lnum;
|
||||||
treeHead.astValue = ("qot" == states[0]) ? tokens[0] : tokens[0].toUpperCase();
|
treeHead.astValue = ("qot" == states[0]) ? tokens[0] : tokens[0].toUpperCase();
|
||||||
treeHead.astType = ("qot" == states[0]) ? "string" : ("num" == states[0]) ? "num" : "lit";
|
treeHead.astType = (functionMode) ? "function" : ("qot" == states[0]) ? "string" : ("num" == states[0]) ? "num" : "lit";
|
||||||
|
|
||||||
return treeHead;
|
return treeHead;
|
||||||
}
|
}
|
||||||
@@ -2579,7 +2590,7 @@ bF._executeAndGet = function(lnum, syntaxTree) {
|
|||||||
try {
|
try {
|
||||||
var execResult = bF._executeSyntaxTree(lnum, syntaxTree, 0);
|
var execResult = bF._executeSyntaxTree(lnum, syntaxTree, 0);
|
||||||
|
|
||||||
serial.println(`Line ${lnum} TRO: ${Object.entries(execResult)}`);
|
if (bF.parserDoDebugPrint) serial.println(`Line ${lnum} TRO: ${Object.entries(execResult)}`);
|
||||||
|
|
||||||
return execResult.troNextLine;
|
return execResult.troNextLine;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ bF.parserPrintdbgline = function(icon, msg, lnum, recDepth) {
|
|||||||
*/
|
*/
|
||||||
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);
|
||||||
|
|
||||||
|
if (tokens.length !== states.length) throw lang.syntaxfehler(lnum);
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
let parenDepth = 0;
|
let parenDepth = 0;
|
||||||
@@ -90,6 +92,16 @@ bF._parseStmt = function(lnum, tokens, states, recDepth) {
|
|||||||
let treeHead = new BasicAST();
|
let treeHead = new BasicAST();
|
||||||
treeHead.astLnum = lnum;
|
treeHead.astLnum = lnum;
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
// case for: single word (e.g. NEXT for FOR loop)
|
||||||
|
if (tokens.length == 1 && states.length == 1) {
|
||||||
|
bF.parserPrintdbgline('$', "Single Word Function Call", lnum, recDepth);
|
||||||
|
return bF._parseLit(lnum, tokens, states, recDepth + 1, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
let parenDepth = 0;
|
let parenDepth = 0;
|
||||||
let parenStart = -1;
|
let parenStart = -1;
|
||||||
let parenEnd = -1;
|
let parenEnd = -1;
|
||||||
@@ -631,7 +643,7 @@ bF._parseIdent = function(lnum, tokens, states, recDepth) {
|
|||||||
/**
|
/**
|
||||||
* @return: BasicAST
|
* @return: BasicAST
|
||||||
*/
|
*/
|
||||||
bF._parseLit = function(lnum, tokens, states, recDepth) {
|
bF._parseLit = function(lnum, tokens, states, recDepth, functionMode) {
|
||||||
bF.parserPrintdbg2(String.fromCharCode(0xA2), lnum, tokens, states, recDepth);
|
bF.parserPrintdbg2(String.fromCharCode(0xA2), lnum, tokens, states, recDepth);
|
||||||
|
|
||||||
if (!Array.isArray(tokens) && !Array.isArray(states)) throw new ParserError("Tokens and states are not array");
|
if (!Array.isArray(tokens) && !Array.isArray(states)) throw new ParserError("Tokens and states are not array");
|
||||||
@@ -640,7 +652,7 @@ bF._parseLit = function(lnum, tokens, states, recDepth) {
|
|||||||
let treeHead = new BasicAST();
|
let treeHead = new BasicAST();
|
||||||
treeHead.astLnum = lnum;
|
treeHead.astLnum = lnum;
|
||||||
treeHead.astValue = ("qot" == states[0]) ? tokens[0] : tokens[0].toUpperCase();
|
treeHead.astValue = ("qot" == states[0]) ? tokens[0] : tokens[0].toUpperCase();
|
||||||
treeHead.astType = ("qot" == states[0]) ? "string" : ("num" == states[0]) ? "num" : "lit";
|
treeHead.astType = (functionMode) ? "function" : ("qot" == states[0]) ? "string" : ("num" == states[0]) ? "num" : "lit";
|
||||||
|
|
||||||
return treeHead;
|
return treeHead;
|
||||||
}
|
}
|
||||||
@@ -729,8 +741,8 @@ let tokens5 = ["ON","6","*","SQR","(","X","-","3",")","GOTO","X","+","1",",","X"
|
|||||||
let states5 = ["lit","num","op","lit","paren","lit","op","num","paren","lit","lit","op","num","sep","lit","op","num","sep","lit","op","num"];
|
let states5 = ["lit","num","op","lit","paren","lit","op","num","paren","lit","lit","op","num","sep","lit","op","num","sep","lit","op","num"];
|
||||||
|
|
||||||
// FOR K=1 TO 10
|
// FOR K=1 TO 10
|
||||||
let tokens6 = ["FOR","K","=","1","TO","10"];
|
let tokens6 = ["FOR","K","=","10","TO","1","STEP","-","1"];
|
||||||
let states6 = ["lit","lit","op","num","op","num"];
|
let states6 = ["lit","lit","op","num","op","num","op","op","num"];
|
||||||
|
|
||||||
// FIXME print(chr(47+round(rnd(1))*45);) outputs bad tree
|
// FIXME print(chr(47+round(rnd(1))*45);) outputs bad tree
|
||||||
let tokens7 = ["PRINT","(","CHR","(","47","+","ROUND","(","RND","(","1",")",")","*","45",")",";",")"];
|
let tokens7 = ["PRINT","(","CHR","(","47","+","ROUND","(","RND","(","1",")",")","*","45",")",";",")"];
|
||||||
@@ -740,10 +752,14 @@ let states7 = ["lit","paren","lit","paren","num","op","lit","paren","lit","paren
|
|||||||
let tokens8 = ["PRINT","4","+","5","*","9"];
|
let tokens8 = ["PRINT","4","+","5","*","9"];
|
||||||
let states8 = ["lit","num","op","num","op","num"];
|
let states8 = ["lit","num","op","num","op","num"];
|
||||||
|
|
||||||
|
// NEXT
|
||||||
|
let tokens9 = ["NEXT"];
|
||||||
|
let states9 = ["lit"];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let trees = bF._parseTokens(lnum,
|
let trees = bF._parseTokens(lnum,
|
||||||
tokens8,
|
tokens6,
|
||||||
states8
|
states6
|
||||||
);
|
);
|
||||||
trees.forEach((t,i) => {
|
trees.forEach((t,i) => {
|
||||||
serial.println("\nParsed Statement #"+(i+1));
|
serial.println("\nParsed Statement #"+(i+1));
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ stmt =
|
|||||||
| "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 , ")"
|
||||||
| expr ;
|
| expr ; (* if the statement contains only one word, treat it as function_call e.g. NEXT for FOR loop *)
|
||||||
|
|
||||||
expr = (* this basically blocks some funny attemps such as using DEFUN as anon function because everything is global in BASIC *)
|
expr = (* this basically blocks some funny attemps such as using DEFUN as anon function because everything is global in BASIC *)
|
||||||
lit
|
lit
|
||||||
|
|||||||
Reference in New Issue
Block a user