From ae66a91c76b904c166458755f46685daa5e7e3b6 Mon Sep 17 00:00:00 2001 From: JoshdRod Date: Tue, 13 Jan 2026 21:31:05 +0000 Subject: [PATCH 01/11] ! Add boilerplate for Node class Node class contains properties: - type - content - leftNode - rightNode - parent - commutative - precedence --- pages/index/script.js | 120 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 2 deletions(-) diff --git a/pages/index/script.js b/pages/index/script.js index 8a4447d..0298cbb 100644 --- a/pages/index/script.js +++ b/pages/index/script.js @@ -777,8 +777,7 @@ function treeToMathJax(tree, currentNodeIndex=0) break; } default: - output += currentNode.content; - break; + output += currentNode.content; break; } return output; } @@ -800,3 +799,120 @@ function cleanExpression(expression) cleanExpression = cleanExpression.replaceAll(' ', ''); return cleanExpression; } + + + +class Node { + constructor(content, type, leftNode=-1, rightNode=-1, parent=-1) { + this.type = type; + this.content = content; + this.leftNode = leftNode; + this.rightNode = rightNode; + this.parent = parent; + } + + set type(type) { + switch (type) { + case "number": + return NodeType.NUMBER; + break; + case "constant": + return NodeType.CONSTANT; + break; + case "variable": + return NodeType.VARIABLE; + break; + case "operator": + return NodeType.OPERATOR; + break; + case "function": + return NodeType.FUNCTION; + break; + case "open bracket": + return NodeType.OPEN_BRACKET; + break; + case "close bracket": + return NodeType.CLOSE_BRACKET; + break; + default: // Invalid type! + throw `Invalid type! Got ${type}, which is not in the type list.`; + } + } + + set content(content) { + // TODO: Add some input validation here + switch (this.type) { + case NodeType.NUMBER: + return content; + break; + case NodeType.CONSTANT: + return content; + break; + case NodeType.VARIABLE: + return content; + break; + case NodeType.OPERATOR: + match (content) { + case '+': + return Operator.ADDITION; + break; + case '-': + return Operator.SUBTRACTION; + break; + case '*': + return Operator.MULTIPLICATION; + break; + case '/': + return Operator.DIVISION; + break; + case '^': + return Operator.EXPONENTIATION; + break; + default: + throw `Attempted to create Operator node with non-operator content. Given: ${content}`; + break; + } + case NodeType.FUNCTION: + return content; + break; + case NodeType.OPEN_BRACKET: + return content; + break; + case NodeType.CLOSE_BRACKET: + return content; + break; + } + } + + get precedence() { + if (this.type != NodeType.OPERATOR) { + throw "Attempted to access precedence of non-operator."; + } + match (this.content) { + case Operator.ADDITION: + case Operator.MULTIPLICATION: + return true; + break; + default: + return false; + } + } +} + +class Operator { + static #_ADDITION = '+'; + static #_SUBTRACTION = '-'; + static #_MULTIPLICATION = '*'; + static #_DIVISION = '/'; + static #_EXPONENTIATION = '^'; +} + +class NodeType { + static #_NUMBER = 0; + static #_CONSTANT = 1; + static #_VARIABLE = 2; + static #_OPERATOR = 3; + static #_FUNCTION = 4; + static #_OPEN_BRACKET = 5; + static #_CLOSE_BRACKET = 6; +} From e8a006690dd7fecb2fde9db262de5bb3cd8f98de Mon Sep 17 00:00:00 2001 From: JoshdRod Date: Sun, 18 Jan 2026 16:25:44 +0000 Subject: [PATCH 02/11] ! Make expressionToComponentList work with refactored node object Previously, expressionToComponentList wasn't able to use the new Node class, for a few reasons: - The Node class needs to be defined before it is accessed (see the Temporal Dead Zone https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#temporal_dead_zone_tdz) - Move Node class to a new file - Add private type and content properties, which are accessed by the Node getter and setters --- index.html | 1 + pages/index/script.js | 163 ++---------------------------------------- pages/index/tree.js | 155 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 161 insertions(+), 158 deletions(-) create mode 100644 pages/index/tree.js diff --git a/index.html b/index.html index 1a5dacc..178709e 100644 --- a/index.html +++ b/index.html @@ -133,6 +133,7 @@

Integrle

+ diff --git a/pages/index/script.js b/pages/index/script.js index 0298cbb..027e947 100644 --- a/pages/index/script.js +++ b/pages/index/script.js @@ -158,21 +158,11 @@ function expressionToComponentList(expression) || list[list.length - 1].type == "function")) ) { - list.push({ - content: "+", - type: "operator", - precedence: 0, - commutative: true, - leftNode: -1, - rightNode: -1, - parent: -1, - depth: -1 - }); - + list.push(new Node("operator", '+')); } - content = "-1"; - type = "number"; + type = "number"; + content = "-1"; i++; } @@ -215,8 +205,6 @@ function expressionToComponentList(expression) { content = exp[i]; type = "operator"; - precedence = {'+': 0, '-': 0, '/': 1, '*': 1, '^': 2}[exp[i]]; - commutative = {'+': true, '-': false, '/': false, '*': true, '^': false}[exp[i]]; i++; } @@ -266,22 +254,7 @@ function expressionToComponentList(expression) } // Add new component - let newComponent = { - content: content, - type: type, - leftNode: -1, - rightNode: -1, - parent: -1, - depth: -1 - }; - - if (type == "operator" || type == "function") { - newComponent.precedence = precedence; - if (type == "operator") { - newComponent.commutative = commutative; - } - } - list.push(newComponent); + list.push(new Node(type, content)); // Check for implicit * signs // If previous component is: Number, Variable, or Close Bracket @@ -296,16 +269,7 @@ function expressionToComponentList(expression) && ["open bracket", "number", "variable", "function"].includes(list[list.length - 1].type) ) { - list.splice(-1, 0, { - content: '*', - type: "operator", - precedence: 1, - leftNode: -1, - rightNode: -1, - parent: -1, - depth: -1, - commutative: true - }); + list.splice(-1, 0, new Node("operator", '*')); } } @@ -799,120 +763,3 @@ function cleanExpression(expression) cleanExpression = cleanExpression.replaceAll(' ', ''); return cleanExpression; } - - - -class Node { - constructor(content, type, leftNode=-1, rightNode=-1, parent=-1) { - this.type = type; - this.content = content; - this.leftNode = leftNode; - this.rightNode = rightNode; - this.parent = parent; - } - - set type(type) { - switch (type) { - case "number": - return NodeType.NUMBER; - break; - case "constant": - return NodeType.CONSTANT; - break; - case "variable": - return NodeType.VARIABLE; - break; - case "operator": - return NodeType.OPERATOR; - break; - case "function": - return NodeType.FUNCTION; - break; - case "open bracket": - return NodeType.OPEN_BRACKET; - break; - case "close bracket": - return NodeType.CLOSE_BRACKET; - break; - default: // Invalid type! - throw `Invalid type! Got ${type}, which is not in the type list.`; - } - } - - set content(content) { - // TODO: Add some input validation here - switch (this.type) { - case NodeType.NUMBER: - return content; - break; - case NodeType.CONSTANT: - return content; - break; - case NodeType.VARIABLE: - return content; - break; - case NodeType.OPERATOR: - match (content) { - case '+': - return Operator.ADDITION; - break; - case '-': - return Operator.SUBTRACTION; - break; - case '*': - return Operator.MULTIPLICATION; - break; - case '/': - return Operator.DIVISION; - break; - case '^': - return Operator.EXPONENTIATION; - break; - default: - throw `Attempted to create Operator node with non-operator content. Given: ${content}`; - break; - } - case NodeType.FUNCTION: - return content; - break; - case NodeType.OPEN_BRACKET: - return content; - break; - case NodeType.CLOSE_BRACKET: - return content; - break; - } - } - - get precedence() { - if (this.type != NodeType.OPERATOR) { - throw "Attempted to access precedence of non-operator."; - } - match (this.content) { - case Operator.ADDITION: - case Operator.MULTIPLICATION: - return true; - break; - default: - return false; - } - } -} - -class Operator { - static #_ADDITION = '+'; - static #_SUBTRACTION = '-'; - static #_MULTIPLICATION = '*'; - static #_DIVISION = '/'; - static #_EXPONENTIATION = '^'; -} - -class NodeType { - static #_NUMBER = 0; - static #_CONSTANT = 1; - static #_VARIABLE = 2; - static #_OPERATOR = 3; - static #_FUNCTION = 4; - static #_OPEN_BRACKET = 5; - static #_CLOSE_BRACKET = 6; -} diff --git a/pages/index/tree.js b/pages/index/tree.js new file mode 100644 index 0000000..2e344aa --- /dev/null +++ b/pages/index/tree.js @@ -0,0 +1,155 @@ +class Operator { + static #_ADDITION = '+'; + static get ADDITION() { return this.#_ADDITION; } + static #_SUBTRACTION = '-'; + static get SUBTRACTION() { return this.#_SUBTRACTION; } + static #_MULTIPLICATION = '*'; + static get MULITPLICATION() { return this.#_MULTIPLICATION; } + static #_DIVISION = '/'; + static get DIVISION() { return this.#_DIVISION; } + static #_EXPONENTIATION = '^'; + static get EXPONENTIATION() { return this.#_EXPONENTIATION; } +} + +class NodeType { + static #_NUMBER = "NUMBER"; + static get NUMBER() { return this.#_NUMBER; } + static #_CONSTANT = "CONSTANT"; + static get CONSTANT() { return this.#_CONSTANT; } + static #_VARIABLE = "VARIABLE"; + static get VARIABLE() { return this.#_VARIABLE; } + static #_OPERATOR = "OPERATOR"; + static get OPERATOR() { return this.#_OPERATOR; } + static #_FUNCTION = "FUNCTION"; + static get FUNCTION() { return this.#_FUNCTION; } + static #_OPEN_BRACKET = "OPEN BRACKET"; + static get OPEN_BRACKET() { return this.#_OPEN_BRACKET; } + static #_CLOSE_BRACKET = "CLOSE BRACKET"; + static get CLOSE_BRACKET() { return this.#_CLOSE_BRACKET; } +} + +class Node { + constructor(type, content, leftNode=-1, rightNode=-1, parent=-1) { + this.type = type; + this.content = content; + this.leftNode = leftNode; + this.rightNode = rightNode; + this.parent = parent; + } + + #_type; + get type() { + return this.#_type; + } + set type(type) { + switch (type) { + case "number": + this.#_type = NodeType.NUMBER; + break; + case "constant": + this.#_type = NodeType.CONSTANT; + break; + case "variable": + this.#_type = NodeType.VARIABLE; + break; + case "operator": + this.#_type = NodeType.OPERATOR; + break; + case "function": + this.#_type = NodeType.FUNCTION; + break; + case "open bracket": + this.#_type = NodeType.OPEN_BRACKET; + break; + case "close bracket": + this.#_type = NodeType.CLOSE_BRACKET; + break; + default: // Invalid type! + throw `Invalid type! Got ${type}, which is not in the type list.`; + } + } + + #_content; + get content() { + return this.#_content; + } + set content(content) { + // TODO: Add some input validation here + switch (this.type) { + case NodeType.NUMBER: + this.#_content = content; + break; + case NodeType.CONSTANT: + this.#_content = content; + break; + case NodeType.VARIABLE: + this.#_content = content; + break; + case NodeType.OPERATOR: + switch (content) { + case '+': + this.#_content = Operator.ADDITION; + break; + case '-': + this.#_content = Operator.SUBTRACTION; + break; + case '*': + this.#_content = Operator.MULTIPLICATION; + break; + case '/': + this.#_content = Operator.DIVISION; + break; + case '^': + this.#_content = Operator.EXPONENTIATION; + break; + default: + throw `Attempted to create Operator node with non-operator content. Given: ${content}`; + break; + } + case NodeType.FUNCTION: + this.#_content = content; + break; + case NodeType.OPEN_BRACKET: + this.#_content = content; + break; + case NodeType.CLOSE_BRACKET: + this.#_content = content; + break; + } + } + + get precedence() { + if (this.type != NodeType.OPERATOR) { + throw "Attempted to access precedence of non-operator."; + } + switch (this.content) { + case Operator.ADDITION: + case Operator.SUBTRACTION: + return 0; + break; + case Operator.MULTIPLICATION: + case Operator.DIVISION: + return 1; + break; + case Operator.EXPONENTIATION: + return 2; + break; + default: + throw `Node of operator type has content ${this.content}, which should not be possible.`; + } + } + + get commutative() { + if (this.type != NodeType.OPERATOR) { + throw "Attempted to query commutativity of non-operator."; + } + switch (this.content) { + case Operator.ADDITION: + case Operator.MULTIPLICATION: + return true; + break; + default: + return false; + } + } +} From 52e61a9573d72ef0d04c55ec60597e06665806ca Mon Sep 17 00:00:00 2001 From: JoshdRod Date: Sun, 18 Jan 2026 16:45:08 +0000 Subject: [PATCH 03/11] ! Make componentToPostfix work with refactored node object - Change node type references to the enum, instead of string - Fix spelling errors --- pages/index/script.js | 19 +++++++++---------- pages/index/tree.js | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/pages/index/script.js b/pages/index/script.js index 027e947..91e83e9 100644 --- a/pages/index/script.js +++ b/pages/index/script.js @@ -154,8 +154,8 @@ function expressionToComponentList(expression) ( !(list.length == 0 || list.length > 0 && - (list[list.length - 1].type == "open bracket" - || list[list.length - 1].type == "function")) + (list[list.length - 1].type == NodeType.OPEN_BRACKET + || list[list.length - 1].type == NodeType.FUNCTION)) ) { list.push(new Node("operator", '+')); @@ -265,8 +265,8 @@ function expressionToComponentList(expression) // e.g (10 + x)(3 + x) -> ( 10 + x ) * ( 3 + x ) if ( list.length >= 2 - && ["close bracket", "number", "variable"].includes(list[list.length - 2].type) - && ["open bracket", "number", "variable", "function"].includes(list[list.length - 1].type) + && [NodeType.CLOSE_BRACKET, NodeType.NUMBER, NodeType.VARIABLE].includes(list[list.length - 2].type) + && [NodeType.OPEN_BRACKET, NodeType.NUMBER, NodeType.VARIABLE, NodeType.FUNCTION].includes(list[list.length - 1].type) ) { list.splice(-1, 0, new Node("operator", '*')); @@ -288,12 +288,12 @@ function componentListToPostfix(list) { let component = list[index]; // If number, constant, or variable, put in output - if (["number", "constant", "variable"].includes(component.type)) + if ([NodeType.NUMBER, NodeType.CONSTANT, NodeType.VARIABLE].includes(component.type)) { postfixList.push(component); } // If (, recurse and add to string - else if (component.type == "open bracket") + else if (component.type == NodeType.OPEN_BRACKET) { let bracketEval = componentListToPostfix(list.slice(index+1)); index += bracketEval.index + 1; // +1, as list indices start from 0 @@ -302,7 +302,7 @@ function componentListToPostfix(list) postfixList.push(operatorStack.pop()); } // If ), return - else if (component.type == "close bracket") + else if (component.type == NodeType.CLOSE_BRACKET) { postfixList.push(...operatorStack.reverse()); return { @@ -311,12 +311,11 @@ function componentListToPostfix(list) }; } // If operator or function, look at stack - else if (component.type == "operator" || component.type == "function") - { + else if (component.type == NodeType.OPERATOR || component.type == NodeType.FUNCTION) { // If function, push // Functions never cause an operator to be popped. e.g: in 1 * 2 + 3, the + causes the * to be popped. // In 1 * sin(3), the sin doesn't cause the * to be popped. - if (component.type == "function") + if (component.type == NodeType.FUNCTION) operatorStack.push(component); // If higher precedence than top of stack, push diff --git a/pages/index/tree.js b/pages/index/tree.js index 2e344aa..28c55ed 100644 --- a/pages/index/tree.js +++ b/pages/index/tree.js @@ -4,7 +4,7 @@ class Operator { static #_SUBTRACTION = '-'; static get SUBTRACTION() { return this.#_SUBTRACTION; } static #_MULTIPLICATION = '*'; - static get MULITPLICATION() { return this.#_MULTIPLICATION; } + static get MULTIPLICATION() { return this.#_MULTIPLICATION; } static #_DIVISION = '/'; static get DIVISION() { return this.#_DIVISION; } static #_EXPONENTIATION = '^'; From cee11fe8c346826b76912118c55a2910e669ba47 Mon Sep 17 00:00:00 2001 From: JoshdRod Date: Sun, 18 Jan 2026 19:30:29 +0000 Subject: [PATCH 04/11] Make postfixToTree work with refactored node object - Change references to node type to reference the enum --- pages/index/script.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pages/index/script.js b/pages/index/script.js index 91e83e9..8bbe833 100644 --- a/pages/index/script.js +++ b/pages/index/script.js @@ -355,22 +355,22 @@ function postfixToTree(components, index=0, parentIndex=-1, depth=0) switch(currentComponent.type) { - case "function": - case "operator": { + case NodeType.FUNCTION: + case NodeType.OPERATOR: { let componentIndex = index; currentComponent.leftNode = index+1; index = postfixToTree(components, index+1, componentIndex, depth+1); - if (currentComponent.type == "operator") + if (currentComponent.type == NodeType.OPERATOR) { currentComponent.rightNode = index+1; index = postfixToTree(components, index+1, componentIndex, depth+1); } break; } - case "number": - case "constant": + case NodeType.NUMBER: + case NodeType.CONSTANT: break; } From b194b7853e78eb8e31a1b4c9c6a7adb274c45a67 Mon Sep 17 00:00:00 2001 From: JoshdRod Date: Sun, 18 Jan 2026 19:40:12 +0000 Subject: [PATCH 05/11] ! Make normaliseTree work for refactored node object - Change references to node type to reference the enum --- pages/index/script.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pages/index/script.js b/pages/index/script.js index 8bbe833..1ff2f9e 100644 --- a/pages/index/script.js +++ b/pages/index/script.js @@ -390,7 +390,7 @@ function normaliseTree(tree, rootNodeIndex=0) { let currentNode = tree[currentNodeIndex]; // If commutative node found, add children to list - if (currentNode.type == "operator" && currentNode.commutative == true) + if (currentNode.type == NodeType.OPERATOR && currentNode.commutative == true) { let terms = findCommutativeNodes(tree, currentNodeIndex, currentNode.content); let commutativeNodes = terms.nodes; @@ -461,7 +461,7 @@ function findCommutativeNodes(tree, opNodeIndex, operator) for (const node of nodesToCheck) { - if (node.type != "operator" || node.commutative == false) + if (node.type != NodeType.OPERATOR || node.commutative == false) { commutativeNodesList.push(tree.indexOf(node)); let parentNode = tree[node.parent]; From 0ab8c9997c1653a5368160c3ebf28b7ad27840b3 Mon Sep 17 00:00:00 2001 From: JoshdRod Date: Sun, 18 Jan 2026 20:15:42 +0000 Subject: [PATCH 06/11] Make treeToMathJax work for refactored node object - Replace references to string literals in the function to use the NodeType and Operator enums --- pages/index/script.js | 56 +++++++++++++++++++++---------------------- pages/index/tree.js | 7 ++++-- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/pages/index/script.js b/pages/index/script.js index 1ff2f9e..3b85a14 100644 --- a/pages/index/script.js +++ b/pages/index/script.js @@ -610,7 +610,7 @@ function treeToMathJax(tree, currentNodeIndex=0) let output = ""; switch (currentNode.type) { - case "operator": + case NodeType.OPERATOR: { // If children of operator are another operator, use ()s let rightNodeIndex = currentNode.rightNode; @@ -618,15 +618,15 @@ function treeToMathJax(tree, currentNodeIndex=0) let leftNodeIndex = currentNode.leftNode; let leftNode = tree[leftNodeIndex]; - if (rightNode.type == "operator") + if (rightNode.type == NodeType.OPERATOR) { // If division, use {}s instead of ()s switch (rightNode.content) { - case '+': + case Operator.ADDITION: output += `(${treeToMathJax(tree, rightNodeIndex)})`; break; - case '/': + case Operator.DIVISION: output += `{${treeToMathJax(tree, rightNodeIndex)}}`; break; default: @@ -639,46 +639,46 @@ function treeToMathJax(tree, currentNodeIndex=0) switch (currentNode.content) { - case '/': + case Operator.DIVISION: output += " \\over "; break; - case '*': + case Operator.MULTIPLICATION: // Implied * sign // Due to mutiplication representing a -ive number (e.g: -4 -> -1 * 4) - if (rightNode.type == "number" && rightNode.content == "-1") + if (rightNode.type == NodeType.NUMBER && rightNode.content == "-1") break; - if (rightNode.type == "number" || - (rightNode.type == "operator" && - (rightNode.content == '+' || rightNode.content == '/' || rightNode.content == '*') + if (rightNode.type == NodeType.NUMBER || + (rightNode.type == NodeType.OPERATOR && + (rightNode.content == Operator.ADDITION || rightNode.content == Operator.DIVISION || rightNode.content == Operator.MULTIPLICATION) ) ) { - if (leftNode.type == "constant" || leftNode.type == "variable" || leftNode.type == "function" || - (leftNode.type == "operator" && - (leftNode.content == '+') + if (leftNode.type == NodeType.CONSTANT || leftNode.type == NodeType.VARIABLE || leftNode.type == NodeType.FUNCTION || + (leftNode.type == NodeType.OPERATOR && + (leftNode.content == Operator.ADDITION) ) ) { break; } } - if (rightNode.type == "variable") + if (rightNode.type == NodeType.VARIABLE) { - if (leftNode.type == "function" || (leftNode.type == "operator" && leftNode.content == '+')) + if (leftNode.type == NodeType.FUNCTION || (leftNode.type == NodeType.OPERATOR && leftNode.content == Operator.ADDITION)) break; } - if (rightNode.type == "function") + if (rightNode.type == NodeType.FUNCTION) { - if (leftNode.type == "function") + if (leftNode.type == NodeType.FUNCTION) break; } - output += '*'; + output += Operator.MULTIPLICATION; break; - case '+': + case Operator.ADDITION: // If addition is actually representing a subtraction, ignore + sign (e.g: 1-2 -> 1+(-1*2)) - if (leftNode.type == "operator" && leftNode.content == '*') + if (leftNode.type == NodeType.OPERATOR && leftNode.content == Operator.MULTIPLICATION) { - if (tree[leftNode.rightNode].type == "number" && tree[leftNode.rightNode].content == '-1') + if (tree[leftNode.rightNode].type == NodeType.NUMBER && tree[leftNode.rightNode].content == '-1') break; } else @@ -691,15 +691,15 @@ function treeToMathJax(tree, currentNodeIndex=0) break; } - if (leftNode.type == "operator") + if (leftNode.type == NodeType.OPERATOR) { // If division, use {}s instead of ()s switch (leftNode.content) { - case '+': + case Operator.ADDITION: output += `(${treeToMathJax(tree, leftNodeIndex)})`; break; - case '/': + case Operator.DIVISION: output += `{${treeToMathJax(tree, leftNodeIndex)}}`; break; default: @@ -712,16 +712,16 @@ function treeToMathJax(tree, currentNodeIndex=0) break; } - case "function": + case NodeType.FUNCTION: output += `\\${currentNode.content}`; let leftNodeIndex = currentNode.leftNode; let leftNode = tree[leftNodeIndex]; - if (leftNode.type == "operator") + if (leftNode.type == NodeType.OPERATOR) { // If division, use {}s instead of ()s switch (leftNode.content) { - case '/': + case Operator.DIVISION: output += `{${treeToMathJax(tree, leftNodeIndex)}}`; break; default: @@ -733,7 +733,7 @@ function treeToMathJax(tree, currentNodeIndex=0) output += `({${treeToMathJax(tree, leftNodeIndex)}})`; break; - case "number": + case NodeType.NUMBER: if (currentNode.content == "-1") { output += '-'; diff --git a/pages/index/tree.js b/pages/index/tree.js index 28c55ed..ff79c45 100644 --- a/pages/index/tree.js +++ b/pages/index/tree.js @@ -119,8 +119,11 @@ class Node { } get precedence() { - if (this.type != NodeType.OPERATOR) { - throw "Attempted to access precedence of non-operator."; + if (this.type != NodeType.OPERATOR && this.type != NodeType.FUNCTION) { + throw "Attempted to access precedence of non-operator or function."; + } + if (this.type == NodeType.FUNCTION) { + return 0.5; // TODO: Maybe we change this so they're all ints? } switch (this.content) { case Operator.ADDITION: From 3661b7df606afb30384f624a585df9d00e16f6b9 Mon Sep 17 00:00:00 2001 From: JoshdRod Date: Fri, 30 Jan 2026 20:58:41 +0000 Subject: [PATCH 07/11] Remove breaks after return Returning in a switch-case statement terminates the statement. Hence, a break after the return is just dead code, and unneeded. --- pages/index/tree.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pages/index/tree.js b/pages/index/tree.js index ff79c45..43f620d 100644 --- a/pages/index/tree.js +++ b/pages/index/tree.js @@ -129,14 +129,11 @@ class Node { case Operator.ADDITION: case Operator.SUBTRACTION: return 0; - break; case Operator.MULTIPLICATION: case Operator.DIVISION: return 1; - break; case Operator.EXPONENTIATION: return 2; - break; default: throw `Node of operator type has content ${this.content}, which should not be possible.`; } @@ -150,7 +147,6 @@ class Node { case Operator.ADDITION: case Operator.MULTIPLICATION: return true; - break; default: return false; } From 8b60438773a3d41e9efa510cc70eb6102642f182 Mon Sep 17 00:00:00 2001 From: JoshdRod Date: Sun, 1 Feb 2026 13:52:53 +0000 Subject: [PATCH 08/11] Fix incorrect content for operators Previously, a missing break caused the setting of content for any Operator Node to fall into the function case. e.g: This would set its content as '+', instead of OPERATOR.ADDITION. Currently, these two things are the same thing, but this could deviate in the future. --- pages/index/tree.js | 1 + 1 file changed, 1 insertion(+) diff --git a/pages/index/tree.js b/pages/index/tree.js index 43f620d..89aeed9 100644 --- a/pages/index/tree.js +++ b/pages/index/tree.js @@ -106,6 +106,7 @@ class Node { throw `Attempted to create Operator node with non-operator content. Given: ${content}`; break; } + break; case NodeType.FUNCTION: this.#_content = content; break; From 8b1856cc6c0465f5c90e85474fbb558822f5d746 Mon Sep 17 00:00:00 2001 From: Joshua Rodriguez Date: Sun, 1 Feb 2026 14:12:17 +0000 Subject: [PATCH 09/11]