You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

83 lines
2.0 KiB
JavaScript

'use strict';
const util = require("util");
module.exports = function findOperatorSequences(tree, operatorMap) {
let current = tree;
let currentIndex = 0;
let currentSequence;
let operators = [];
let operands = [];
let operatorSequences = [];
let operatorSequenceMap = {};
function storeCurrentOperatorSequence() {
operatorSequences.push(currentSequence);
if (operatorSequenceMap[currentSequence.precedence] == null) {
operatorSequenceMap[currentSequence.precedence] = [];
}
operatorSequenceMap[currentSequence.precedence].push(currentSequence);
}
while (current != null) {
operators.push(current.operator);
if (current.left != null) {
operands.push(current.left);
} else {
/* Unary prefix operator */
operands.push(null);
}
if (operatorMap[current.operator] == null) {
throw new Error(`Encountered unknown '${current.operator}' operator`);
}
let associativity = operatorMap[current.operator].associativity;
let precedence = operatorMap[current.operator].precedence;
if (currentSequence != null && precedence === currentSequence.precedence) {
/* Next operator in the same sequence. */
currentSequence.length += 1;
} else {
if (currentSequence != null) {
/* We were previously working on a different operator. */
storeCurrentOperatorSequence();
}
currentSequence = {
precedence: precedence,
associativity: associativity,
length: 1,
firstIndex: currentIndex
}
}
if (current.right == null) {
throw new Error("An error occurred; encountered a `null` right operand, but this should never happen");
} else {
if (current.right.type === "operatorExpression") {
current = current.right;
currentIndex += 1;
} else {
/* Store the very last operand. */
operands.push(current.right);
break;
}
}
}
/* Store the very last sequence we were still working on. */
storeCurrentOperatorSequence();
return {
operators,
operands,
operatorSequences,
operatorSequenceMap
}
};