Skip to content

Commit

Permalink
Bugfix mixed array access function call expression parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
BalaM314 committed Nov 30, 2023
1 parent b5b84ee commit b1feb36
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 10 deletions.
20 changes: 15 additions & 5 deletions src/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ export const operatorsByPriority = ((input) => input.map(row => row.map(o => Arr
["multiply", "divide", "integer_divide", "mod"],
//no exponentiation operator?
[["not", "unary"]],
//(function call)
//(array access)
]);
/** Indexed by OperatorType */
export const operators = Object.fromEntries(operatorsByPriority.flat()
Expand Down Expand Up @@ -303,7 +305,7 @@ export function parseExpression(input) {
return parseExpression(input.slice(1, -1));
//Special case: function call
if (input[0]?.type == "name" && input[1]?.type == "parentheses.open" && input.at(-1)?.type == "parentheses.close") {
let parenNestLevel = 0; //Duped paren handling, unavoidable
let parenNestLevel = 0, bracketNestLevel = 0; //Duped paren handling, unavoidable
return {
operatorToken: input[0],
operator: "function call",
Expand All @@ -314,23 +316,31 @@ export function parseExpression(input) {
parenNestLevel++;
else if (t.type == "parentheses.close")
parenNestLevel--;
return parenNestLevel == 0 && t.type == "punctuation.comma";
else if (t.type == "bracket.open")
bracketNestLevel++;
else if (t.type == "bracket.close")
bracketNestLevel--;
return parenNestLevel == 0 && bracketNestLevel == 0 && t.type == "punctuation.comma";
})).map(parseExpression)
};
}
//Special case: array access
if (input[0]?.type == "name" && input[1]?.type == "bracket.open" && input.at(-1)?.type == "bracket.close" && input.length > 3) {
let bracketNestLevel = 0; //Duped paren handling but [] this time, unavoidable
let parenNestLevel = 0, bracketNestLevel = 0; //Duped paren handling but [] this time, unavoidable
return {
operatorToken: input[0],
operator: "array access",
//Split the tokens between the parens on commas
nodes: splitArray(input.slice(2, -1), t => {
if (t.type == "bracket.open")
if (t.type == "parentheses.open")
parenNestLevel++;
else if (t.type == "parentheses.close")
parenNestLevel--;
else if (t.type == "bracket.open")
bracketNestLevel++;
else if (t.type == "bracket.close")
bracketNestLevel--;
return bracketNestLevel == 0 && t.type == "punctuation.comma";
return parenNestLevel == 0 && bracketNestLevel == 0 && t.type == "punctuation.comma";
}).map(parseExpression)
};
}
Expand Down
16 changes: 11 additions & 5 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ export const operatorsByPriority = ((input:(OperatorType | [type:OperatorType, "
["multiply", "divide", "integer_divide", "mod"],
//no exponentiation operator?
[["not", "unary"]],
//(function call)
//(array access)
]);
/** Indexed by OperatorType */
export const operators = Object.fromEntries(
Expand Down Expand Up @@ -297,7 +299,7 @@ export function parseExpression(input:Token[]):ExpressionASTNode {

//Special case: function call
if(input[0]?.type == "name" && input[1]?.type == "parentheses.open" && input.at(-1)?.type == "parentheses.close"){
let parenNestLevel = 0; //Duped paren handling, unavoidable
let parenNestLevel = 0, bracketNestLevel = 0; //Duped paren handling, unavoidable
return {
operatorToken: input[0],
operator: "function call",
Expand All @@ -307,23 +309,27 @@ export function parseExpression(input:Token[]):ExpressionASTNode {
: splitArray(input.slice(2, -1), t => {
if(t.type == "parentheses.open") parenNestLevel ++;
else if(t.type == "parentheses.close") parenNestLevel --;
return parenNestLevel == 0 && t.type == "punctuation.comma";
else if(t.type == "bracket.open") bracketNestLevel ++;
else if(t.type == "bracket.close") bracketNestLevel --;
return parenNestLevel == 0 && bracketNestLevel == 0 && t.type == "punctuation.comma";
})
).map(parseExpression)
};
}

//Special case: array access
if(input[0]?.type == "name" && input[1]?.type == "bracket.open" && input.at(-1)?.type == "bracket.close" && input.length > 3){
let bracketNestLevel = 0; //Duped paren handling but [] this time, unavoidable
let parenNestLevel = 0, bracketNestLevel = 0; //Duped paren handling but [] this time, unavoidable
return {
operatorToken: input[0],
operator: "array access",
//Split the tokens between the parens on commas
nodes: splitArray(input.slice(2, -1), t => {
if(t.type == "bracket.open") bracketNestLevel ++;
if(t.type == "parentheses.open") parenNestLevel ++;
else if(t.type == "parentheses.close") parenNestLevel --;
else if(t.type == "bracket.open") bracketNestLevel ++;
else if(t.type == "bracket.close") bracketNestLevel --;
return bracketNestLevel == 0 && t.type == "punctuation.comma";
return parenNestLevel == 0 && bracketNestLevel == 0 && t.type == "punctuation.comma";
}).map(parseExpression)
};
}
Expand Down

0 comments on commit b1feb36

Please sign in to comment.