From 1575d3e57443a06d15f45047d530884b973b4edf Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 7 Sep 2017 12:31:40 -0700 Subject: [PATCH 1/5] Remove nullability from tree nodes. --- .../nwapw/abacus/parsing/ShuntingYardParser.java | 15 ++++++++------- .../kotlin/org/nwapw/abacus/tree/BinaryNode.kt | 4 ++-- .../main/kotlin/org/nwapw/abacus/tree/CallNode.kt | 8 ++------ .../kotlin/org/nwapw/abacus/tree/FunctionNode.kt | 2 +- .../org/nwapw/abacus/tree/NumberBinaryNode.kt | 6 +++--- .../org/nwapw/abacus/tree/NumberUnaryNode.kt | 4 ++-- .../org/nwapw/abacus/tree/TreeValueBinaryNode.kt | 2 +- .../nwapw/abacus/tree/TreeValueFunctionNode.kt | 2 +- .../org/nwapw/abacus/tree/TreeValueUnaryNode.kt | 2 +- .../kotlin/org/nwapw/abacus/tree/UnaryNode.kt | 4 ++-- 10 files changed, 23 insertions(+), 26 deletions(-) diff --git a/core/src/main/java/org/nwapw/abacus/parsing/ShuntingYardParser.java b/core/src/main/java/org/nwapw/abacus/parsing/ShuntingYardParser.java index 9d326a8..611f5c9 100644 --- a/core/src/main/java/org/nwapw/abacus/parsing/ShuntingYardParser.java +++ b/core/src/main/java/org/nwapw/abacus/parsing/ShuntingYardParser.java @@ -154,19 +154,20 @@ public class ShuntingYardParser implements Parser>, PluginListe return new VariableNode(match.getContent()); } else if (matchType == TokenType.FUNCTION || matchType == TokenType.TREE_VALUE_FUNCTION) { String functionName = match.getContent(); - CallNode node; - if (matchType == TokenType.FUNCTION) { - node = new FunctionNode(functionName); - } else { - node = new TreeValueFunctionNode(functionName); - } + List children = new ArrayList<>(); while (!matches.isEmpty() && matches.get(0).getType() != TokenType.INTERNAL_FUNCTION_END) { TreeNode argument = constructRecursive(matches); if (argument == null) return null; - node.getChildren().add(0, argument); + children.add(0, argument); } if (matches.isEmpty()) return null; matches.remove(0); + CallNode node; + if (matchType == TokenType.FUNCTION) { + node = new FunctionNode(functionName, children); + } else { + node = new TreeValueFunctionNode(functionName, children); + } return node; } return null; diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/BinaryNode.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/BinaryNode.kt index 4d0d9dd..aa04571 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/BinaryNode.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/BinaryNode.kt @@ -11,10 +11,10 @@ package org.nwapw.abacus.tree * @param left the left node. * @param right the right node. */ -abstract class BinaryNode(val operation: String, val left: TreeNode? = null, val right: TreeNode?) : TreeNode() { +abstract class BinaryNode(val operation: String, val left: TreeNode, val right: TreeNode) : TreeNode() { override fun toString(): String { - return "(" + (left?.toString() ?: "null") + operation + (right?.toString() ?: "null") + ")" + return "(" + left.toString() + operation + right.toString() + ")" } } \ No newline at end of file diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/CallNode.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/CallNode.kt index 5f99494..38595dd 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/CallNode.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/CallNode.kt @@ -7,13 +7,9 @@ package org.nwapw.abacus.tree * to extend this functionality. * * @param callTo the name of the things being called. + * @param children the children of this node. */ -abstract class CallNode(val callTo: String) : TreeNode() { - - /** - * The list of children this node has. - */ - val children: MutableList = mutableListOf() +abstract class CallNode(val callTo: String, val children: List) : TreeNode() { override fun toString(): String { val buffer = StringBuffer() diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/FunctionNode.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/FunctionNode.kt index 813ad52..d6a7696 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/FunctionNode.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/FunctionNode.kt @@ -8,7 +8,7 @@ package org.nwapw.abacus.tree * * @param function the function string. */ -class FunctionNode(function: String) : CallNode(function) { +class FunctionNode(function: String, children: List) : CallNode(function, children) { override fun reduce(reducer: Reducer): T? { val children = Array(children.size, { children[it].reduce(reducer) ?: return null; }) diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/NumberBinaryNode.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/NumberBinaryNode.kt index 74c2206..36f585f 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/NumberBinaryNode.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/NumberBinaryNode.kt @@ -10,12 +10,12 @@ package org.nwapw.abacus.tree * @param left the left child of this node. * @param right the right child of this node. */ -class NumberBinaryNode(operation: String, left: TreeNode?, right: TreeNode?) +class NumberBinaryNode(operation: String, left: TreeNode, right: TreeNode) : BinaryNode(operation, left, right) { override fun reduce(reducer: Reducer): T? { - val left = left?.reduce(reducer) ?: return null - val right = right?.reduce(reducer) ?: return null + val left = left.reduce(reducer) ?: return null + val right = right.reduce(reducer) ?: return null return reducer.reduceNode(this, left, right) } diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/NumberUnaryNode.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/NumberUnaryNode.kt index e4fee3f..1dff327 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/NumberUnaryNode.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/NumberUnaryNode.kt @@ -8,11 +8,11 @@ package org.nwapw.abacus.tree * @param operation the operation this node performs. * @param child the child this node should be applied to. */ -class NumberUnaryNode(operation: String, child: TreeNode?) +class NumberUnaryNode(operation: String, child: TreeNode) : UnaryNode(operation, child) { override fun reduce(reducer: Reducer): T? { - val child = applyTo?.reduce(reducer) ?: return null + val child = applyTo.reduce(reducer) return reducer.reduceNode(this, child) } diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueBinaryNode.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueBinaryNode.kt index 4edfef3..e29319b 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueBinaryNode.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueBinaryNode.kt @@ -11,7 +11,7 @@ package org.nwapw.abacus.tree * @param left the left child of this node. * @param right the right child of this node. */ -class TreeValueBinaryNode(operation: String, left: TreeNode?, right: TreeNode?) +class TreeValueBinaryNode(operation: String, left: TreeNode, right: TreeNode) : BinaryNode(operation, left, right) { override fun reduce(reducer: Reducer): T? { diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueFunctionNode.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueFunctionNode.kt index 68c358e..ca24d9d 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueFunctionNode.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueFunctionNode.kt @@ -7,7 +7,7 @@ package org.nwapw.abacus.tree * is mostly to help the reducer. Besides that, this class also does not * even attempt to reduce its children. */ -class TreeValueFunctionNode(name: String) : CallNode(name) { +class TreeValueFunctionNode(name: String, children: List) : CallNode(name, children) { override fun reduce(reducer: Reducer): T? { return reducer.reduceNode(this) diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueUnaryNode.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueUnaryNode.kt index fdc0db5..7c3d836 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueUnaryNode.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueUnaryNode.kt @@ -9,7 +9,7 @@ package org.nwapw.abacus.tree * @param operation the operation this node performs. * @param child the node the operation should be applied to. */ -class TreeValueUnaryNode(operation: String, child: TreeNode?) +class TreeValueUnaryNode(operation: String, child: TreeNode) : UnaryNode(operation, child) { override fun reduce(reducer: Reducer): T? { diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/UnaryNode.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/UnaryNode.kt index 285231b..ea518e2 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/UnaryNode.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/UnaryNode.kt @@ -9,10 +9,10 @@ package org.nwapw.abacus.tree * @param operation the operation applied to the given node. * @param applyTo the node to which the operation will be applied. */ -abstract class UnaryNode(val operation: String, val applyTo: TreeNode? = null) : TreeNode() { +abstract class UnaryNode(val operation: String, val applyTo: TreeNode) : TreeNode() { override fun toString(): String { - return "(" + (applyTo?.toString() ?: "null") + ")" + operation + return "(" + applyTo.toString() + ")" + operation } } \ No newline at end of file From 52ab357fe1d74f4ce9b5e08c3849c038db268a5a Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 7 Sep 2017 12:53:12 -0700 Subject: [PATCH 2/5] Remove nullability from reduction. --- .../nwapw/abacus/function/DomainException.java | 2 +- .../abacus/function/EvaluationException.java | 2 +- .../number/ComputationInterruptedException.java | 2 +- .../org/nwapw/abacus/plugin/StandardPlugin.java | 7 ++----- .../org/nwapw/abacus/tree/EvaluationResult.kt | 2 +- .../kotlin/org/nwapw/abacus/tree/FunctionNode.kt | 4 ++-- .../org/nwapw/abacus/tree/NumberBinaryNode.kt | 6 +++--- .../kotlin/org/nwapw/abacus/tree/NumberNode.kt | 2 +- .../org/nwapw/abacus/tree/NumberReducer.kt | 16 +++++++++------- .../org/nwapw/abacus/tree/NumberUnaryNode.kt | 2 +- .../main/kotlin/org/nwapw/abacus/tree/Reducer.kt | 2 +- .../kotlin/org/nwapw/abacus/tree/TreeNode.kt | 2 +- .../org/nwapw/abacus/tree/TreeValueBinaryNode.kt | 2 +- .../nwapw/abacus/tree/TreeValueFunctionNode.kt | 2 +- .../org/nwapw/abacus/tree/TreeValueUnaryNode.kt | 4 ++-- .../kotlin/org/nwapw/abacus/tree/VariableNode.kt | 2 +- .../org/nwapw/abacus/fx/AbacusController.java | 8 ++------ 17 files changed, 31 insertions(+), 36 deletions(-) diff --git a/core/src/main/java/org/nwapw/abacus/function/DomainException.java b/core/src/main/java/org/nwapw/abacus/function/DomainException.java index a7a449c..2d09dc3 100644 --- a/core/src/main/java/org/nwapw/abacus/function/DomainException.java +++ b/core/src/main/java/org/nwapw/abacus/function/DomainException.java @@ -18,7 +18,7 @@ public class DomainException extends RuntimeException { * Creates a new DomainException with a default message. */ public DomainException(){ - this("Domain Error"); + this("Domain error."); } } diff --git a/core/src/main/java/org/nwapw/abacus/function/EvaluationException.java b/core/src/main/java/org/nwapw/abacus/function/EvaluationException.java index bad85b9..55db570 100644 --- a/core/src/main/java/org/nwapw/abacus/function/EvaluationException.java +++ b/core/src/main/java/org/nwapw/abacus/function/EvaluationException.java @@ -11,7 +11,7 @@ public class EvaluationException extends RuntimeException { * Creates a new EvaluationException with the default string. */ public EvaluationException() { - super("Error evaluating expression."); + super("Evaluation error."); } /** diff --git a/core/src/main/java/org/nwapw/abacus/number/ComputationInterruptedException.java b/core/src/main/java/org/nwapw/abacus/number/ComputationInterruptedException.java index 2f7b3fd..e055508 100644 --- a/core/src/main/java/org/nwapw/abacus/number/ComputationInterruptedException.java +++ b/core/src/main/java/org/nwapw/abacus/number/ComputationInterruptedException.java @@ -10,7 +10,7 @@ public class ComputationInterruptedException extends RuntimeException { * Creates a new exception of this type. */ public ComputationInterruptedException() { - super("Computation interrupted by user."); + super("Computation interrupted."); } } diff --git a/core/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java b/core/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java index e144bbc..edaa3a5 100755 --- a/core/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java +++ b/core/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java @@ -29,8 +29,7 @@ public class StandardPlugin extends Plugin { @Override public NumberInterface applyInternal(MutableEvaluationContext context, TreeNode[] params) { String assignTo = ((VariableNode) params[0]).getVariable(); - NumberInterface value = params[1].reduce(context.getReducer()); - if(value == null) throw new EvaluationException(); + NumberInterface value = params[1].reduce(context.getInheritedReducer()); context.setVariable(assignTo, value); return value; } @@ -48,9 +47,7 @@ public class StandardPlugin extends Plugin { public NumberInterface applyInternal(MutableEvaluationContext context, TreeNode[] params) { String assignTo = ((VariableNode) params[0]).getVariable(); context.setDefinition(assignTo, params[1]); - NumberInterface value = params[1].reduce(context.getReducer()); - if(value == null) throw new EvaluationException(); - return value; + return params[1].reduce(context.getInheritedReducer()); } }; /** diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/EvaluationResult.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/EvaluationResult.kt index e94c9d6..a499877 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/EvaluationResult.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/EvaluationResult.kt @@ -3,4 +3,4 @@ package org.nwapw.abacus.tree import org.nwapw.abacus.context.MutableEvaluationContext import org.nwapw.abacus.number.NumberInterface -data class EvaluationResult(val value: NumberInterface?, val resultingContext: MutableEvaluationContext) \ No newline at end of file +data class EvaluationResult(val value: NumberInterface, val resultingContext: MutableEvaluationContext) \ No newline at end of file diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/FunctionNode.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/FunctionNode.kt index d6a7696..e4d2acb 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/FunctionNode.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/FunctionNode.kt @@ -10,8 +10,8 @@ package org.nwapw.abacus.tree */ class FunctionNode(function: String, children: List) : CallNode(function, children) { - override fun reduce(reducer: Reducer): T? { - val children = Array(children.size, { children[it].reduce(reducer) ?: return null; }) + override fun reduce(reducer: Reducer): T { + val children = Array(children.size, { children[it].reduce(reducer) }) return reducer.reduceNode(this, *children) } diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/NumberBinaryNode.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/NumberBinaryNode.kt index 36f585f..3742477 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/NumberBinaryNode.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/NumberBinaryNode.kt @@ -13,9 +13,9 @@ package org.nwapw.abacus.tree class NumberBinaryNode(operation: String, left: TreeNode, right: TreeNode) : BinaryNode(operation, left, right) { - override fun reduce(reducer: Reducer): T? { - val left = left.reduce(reducer) ?: return null - val right = right.reduce(reducer) ?: return null + override fun reduce(reducer: Reducer): T { + val left = left.reduce(reducer) + val right = right.reduce(reducer) return reducer.reduceNode(this, left, right) } diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/NumberNode.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/NumberNode.kt index 3507568..9278301 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/NumberNode.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/NumberNode.kt @@ -10,7 +10,7 @@ package org.nwapw.abacus.tree */ class NumberNode(val number: String) : TreeNode() { - override fun reduce(reducer: Reducer): T? { + override fun reduce(reducer: Reducer): T { return reducer.reduceNode(this) } diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/NumberReducer.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/NumberReducer.kt index c1a1da8..8f61923 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/NumberReducer.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/NumberReducer.kt @@ -2,6 +2,7 @@ package org.nwapw.abacus.tree import org.nwapw.abacus.Abacus import org.nwapw.abacus.context.EvaluationContext +import org.nwapw.abacus.function.EvaluationException import org.nwapw.abacus.number.NumberInterface class NumberReducer(val abacus: Abacus, context: EvaluationContext) : Reducer { @@ -12,18 +13,19 @@ class NumberReducer(val abacus: Abacus, context: EvaluationContext) : Reducer { context.inheritedNumberImplementation?.instanceForString(treeNode.number) + ?: throw EvaluationException() } is VariableNode -> { val variable = context.getVariable(treeNode.variable) if(variable != null) return variable val definition = context.getDefinition(treeNode.variable) if(definition != null) return definition.reduce(this) - null + throw EvaluationException() } is NumberUnaryNode -> { val child = children[0] as NumberInterface @@ -34,29 +36,29 @@ class NumberReducer(val abacus: Abacus, context: EvaluationContext) : Reducer { val left = children[0] as NumberInterface val right = children[1] as NumberInterface - val promotionResult = promotionManager.promote(left, right) ?: return null + val promotionResult = promotionManager.promote(left, right) ?: throw EvaluationException() context.numberImplementation = promotionResult.promotedTo abacus.pluginManager.operatorFor(treeNode.operation).apply(context, *promotionResult.items) } is FunctionNode -> { val promotionResult = promotionManager - .promote(*children.map { it as NumberInterface }.toTypedArray()) ?: return null + .promote(*children.map { it as NumberInterface }.toTypedArray()) ?: throw EvaluationException() context.numberImplementation = promotionResult.promotedTo abacus.pluginManager.functionFor(treeNode.callTo).apply(context, *promotionResult.items) } is TreeValueUnaryNode -> { abacus.pluginManager.treeValueOperatorFor(treeNode.operation) - .apply(context, treeNode.applyTo ?: return null) + .apply(context, treeNode.applyTo) } is TreeValueBinaryNode -> { abacus.pluginManager.treeValueOperatorFor(treeNode.operation) - .apply(context, treeNode.left ?: return null, treeNode.right ?: return null) + .apply(context, treeNode.left, treeNode.right) } is TreeValueFunctionNode -> { abacus.pluginManager.treeValueFunctionFor(treeNode.callTo) .apply(context, *treeNode.children.toTypedArray()) } - else -> null + else -> throw EvaluationException() } } diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/NumberUnaryNode.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/NumberUnaryNode.kt index 1dff327..01a494f 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/NumberUnaryNode.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/NumberUnaryNode.kt @@ -11,7 +11,7 @@ package org.nwapw.abacus.tree class NumberUnaryNode(operation: String, child: TreeNode) : UnaryNode(operation, child) { - override fun reduce(reducer: Reducer): T? { + override fun reduce(reducer: Reducer): T { val child = applyTo.reduce(reducer) return reducer.reduceNode(this, child) } diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/Reducer.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/Reducer.kt index 412af29..45cb4dc 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/Reducer.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/Reducer.kt @@ -14,6 +14,6 @@ interface Reducer { * @param treeNode the tree node to reduce. * @param children the list of children, of type T. */ - fun reduceNode(treeNode: TreeNode, vararg children: Any): T? + fun reduceNode(treeNode: TreeNode, vararg children: Any): T } \ No newline at end of file diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/TreeNode.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/TreeNode.kt index 2017739..a17b191 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/TreeNode.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/TreeNode.kt @@ -5,6 +5,6 @@ package org.nwapw.abacus.tree */ abstract class TreeNode { - abstract fun reduce(reducer: Reducer): T? + abstract fun reduce(reducer: Reducer): T } \ No newline at end of file diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueBinaryNode.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueBinaryNode.kt index e29319b..97cd0cf 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueBinaryNode.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueBinaryNode.kt @@ -14,7 +14,7 @@ package org.nwapw.abacus.tree class TreeValueBinaryNode(operation: String, left: TreeNode, right: TreeNode) : BinaryNode(operation, left, right) { - override fun reduce(reducer: Reducer): T? { + override fun reduce(reducer: Reducer): T { return reducer.reduceNode(this) } diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueFunctionNode.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueFunctionNode.kt index ca24d9d..18301d8 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueFunctionNode.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueFunctionNode.kt @@ -9,7 +9,7 @@ package org.nwapw.abacus.tree */ class TreeValueFunctionNode(name: String, children: List) : CallNode(name, children) { - override fun reduce(reducer: Reducer): T? { + override fun reduce(reducer: Reducer): T { return reducer.reduceNode(this) } diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueUnaryNode.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueUnaryNode.kt index 7c3d836..dab3f52 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueUnaryNode.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/TreeValueUnaryNode.kt @@ -12,8 +12,8 @@ package org.nwapw.abacus.tree class TreeValueUnaryNode(operation: String, child: TreeNode) : UnaryNode(operation, child) { - override fun reduce(reducer: Reducer): T? { - return reducer.reduceNode(this); + override fun reduce(reducer: Reducer): T { + return reducer.reduceNode(this) } } \ No newline at end of file diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/VariableNode.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/VariableNode.kt index 93d91dc..0fdf887 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/VariableNode.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/VariableNode.kt @@ -10,7 +10,7 @@ package org.nwapw.abacus.tree */ class VariableNode(val variable: String) : TreeNode() { - override fun reduce(reducer: Reducer): T? { + override fun reduce(reducer: Reducer): T { return reducer.reduceNode(this) } diff --git a/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java b/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java index 5f23a9a..f7fb44d 100644 --- a/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java +++ b/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java @@ -15,6 +15,7 @@ import org.nwapw.abacus.config.Configuration; import org.nwapw.abacus.function.Documentation; import org.nwapw.abacus.function.DocumentationType; import org.nwapw.abacus.function.DomainException; +import org.nwapw.abacus.function.EvaluationException; import org.nwapw.abacus.number.*; import org.nwapw.abacus.plugin.ClassFinder; import org.nwapw.abacus.plugin.PluginListener; @@ -147,16 +148,11 @@ public class AbacusController implements PluginListener { } EvaluationResult result = abacus.evaluateTree(constructedTree); NumberInterface evaluatedNumber = result.getValue(); - if (evaluatedNumber == null) { - return ERR_EVAL; - } String resultingString = evaluatedNumber.toString(); historyData.add(new HistoryModel(inputField.getText(), constructedTree.toString(), resultingString)); abacus.applyToContext(result.getResultingContext()); return resultingString; - } catch (ComputationInterruptedException exception) { - return ERR_STOP; - } catch (DomainException exception) { + } catch (ComputationInterruptedException | DomainException | EvaluationException exception) { return exception.getMessage(); } catch (RuntimeException exception) { exception.printStackTrace(); From 45de25cd50f08a1404cd52e87006ebd5bc413974 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 7 Sep 2017 13:05:16 -0700 Subject: [PATCH 3/5] Move exceptions to their own package and subclass one class. --- .../java/org/nwapw/abacus/exception/AbacusException.java | 9 +++++++++ .../ComputationInterruptedException.java | 6 +++--- .../abacus/{function => exception}/DomainException.java | 8 ++++---- .../{function => exception}/EvaluationException.java | 8 ++++---- .../java/org/nwapw/abacus/number/NumberInterface.java | 2 ++ .../org/nwapw/abacus/function/applicable/Applicable.kt | 2 +- .../main/kotlin/org/nwapw/abacus/tree/NumberReducer.kt | 2 +- .../java/org/nwapw/abacus/tests/CalculationTests.java | 2 +- .../main/java/org/nwapw/abacus/fx/AbacusController.java | 5 +++-- 9 files changed, 28 insertions(+), 16 deletions(-) create mode 100644 core/src/main/java/org/nwapw/abacus/exception/AbacusException.java rename core/src/main/java/org/nwapw/abacus/{number => exception}/ComputationInterruptedException.java (56%) rename core/src/main/java/org/nwapw/abacus/{function => exception}/DomainException.java (71%) rename core/src/main/java/org/nwapw/abacus/{function => exception}/EvaluationException.java (75%) diff --git a/core/src/main/java/org/nwapw/abacus/exception/AbacusException.java b/core/src/main/java/org/nwapw/abacus/exception/AbacusException.java new file mode 100644 index 0000000..894e959 --- /dev/null +++ b/core/src/main/java/org/nwapw/abacus/exception/AbacusException.java @@ -0,0 +1,9 @@ +package org.nwapw.abacus.exception; + +public class AbacusException extends RuntimeException { + + public AbacusException(String baseMessage, String description){ + super(baseMessage + ((description == null) ? "." : (": " + description))); + } + +} diff --git a/core/src/main/java/org/nwapw/abacus/number/ComputationInterruptedException.java b/core/src/main/java/org/nwapw/abacus/exception/ComputationInterruptedException.java similarity index 56% rename from core/src/main/java/org/nwapw/abacus/number/ComputationInterruptedException.java rename to core/src/main/java/org/nwapw/abacus/exception/ComputationInterruptedException.java index e055508..bd77649 100644 --- a/core/src/main/java/org/nwapw/abacus/number/ComputationInterruptedException.java +++ b/core/src/main/java/org/nwapw/abacus/exception/ComputationInterruptedException.java @@ -1,16 +1,16 @@ -package org.nwapw.abacus.number; +package org.nwapw.abacus.exception; /** * Exception thrown when the computation is interrupted by * the user. */ -public class ComputationInterruptedException extends RuntimeException { +public class ComputationInterruptedException extends AbacusException { /** * Creates a new exception of this type. */ public ComputationInterruptedException() { - super("Computation interrupted."); + super("Computation interrupted", null); } } diff --git a/core/src/main/java/org/nwapw/abacus/function/DomainException.java b/core/src/main/java/org/nwapw/abacus/exception/DomainException.java similarity index 71% rename from core/src/main/java/org/nwapw/abacus/function/DomainException.java rename to core/src/main/java/org/nwapw/abacus/exception/DomainException.java index 2d09dc3..4b7fe17 100644 --- a/core/src/main/java/org/nwapw/abacus/function/DomainException.java +++ b/core/src/main/java/org/nwapw/abacus/exception/DomainException.java @@ -1,24 +1,24 @@ -package org.nwapw.abacus.function; +package org.nwapw.abacus.exception; /** * Exception thrown if the function parameters do not match * requirements. */ -public class DomainException extends RuntimeException { +public class DomainException extends AbacusException { /** * Creates a new DomainException. * @param reason the reason for which the exception is thrown. */ public DomainException(String reason) { - super(reason); + super("Domain error", reason); } /** * Creates a new DomainException with a default message. */ public DomainException(){ - this("Domain error."); + this(null); } } diff --git a/core/src/main/java/org/nwapw/abacus/function/EvaluationException.java b/core/src/main/java/org/nwapw/abacus/exception/EvaluationException.java similarity index 75% rename from core/src/main/java/org/nwapw/abacus/function/EvaluationException.java rename to core/src/main/java/org/nwapw/abacus/exception/EvaluationException.java index 55db570..4763aaf 100644 --- a/core/src/main/java/org/nwapw/abacus/function/EvaluationException.java +++ b/core/src/main/java/org/nwapw/abacus/exception/EvaluationException.java @@ -1,17 +1,17 @@ -package org.nwapw.abacus.function; +package org.nwapw.abacus.exception; /** * An exception thrown primarily from Tree Value operators and functions, * which have to deal with the result of a Reducer as well as the results * of Applicable. */ -public class EvaluationException extends RuntimeException { +public class EvaluationException extends AbacusException { /** * Creates a new EvaluationException with the default string. */ public EvaluationException() { - super("Evaluation error."); + this(null); } /** @@ -19,7 +19,7 @@ public class EvaluationException extends RuntimeException { * @param message the message string. */ public EvaluationException(String message) { - super(message); + super("Evaluation error", message); } } diff --git a/core/src/main/java/org/nwapw/abacus/number/NumberInterface.java b/core/src/main/java/org/nwapw/abacus/number/NumberInterface.java index 4a3fe5c..8727425 100755 --- a/core/src/main/java/org/nwapw/abacus/number/NumberInterface.java +++ b/core/src/main/java/org/nwapw/abacus/number/NumberInterface.java @@ -1,5 +1,7 @@ package org.nwapw.abacus.number; +import org.nwapw.abacus.exception.ComputationInterruptedException; + /** * An interface used to represent a number. */ diff --git a/core/src/main/kotlin/org/nwapw/abacus/function/applicable/Applicable.kt b/core/src/main/kotlin/org/nwapw/abacus/function/applicable/Applicable.kt index 8d824a8..5103d8b 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/function/applicable/Applicable.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/function/applicable/Applicable.kt @@ -1,7 +1,7 @@ package org.nwapw.abacus.function.applicable import org.nwapw.abacus.context.MutableEvaluationContext -import org.nwapw.abacus.function.DomainException +import org.nwapw.abacus.exception.DomainException /** * A class that can be applied to arguments. diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/NumberReducer.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/NumberReducer.kt index 8f61923..e94ab46 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/NumberReducer.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/NumberReducer.kt @@ -2,7 +2,7 @@ package org.nwapw.abacus.tree import org.nwapw.abacus.Abacus import org.nwapw.abacus.context.EvaluationContext -import org.nwapw.abacus.function.EvaluationException +import org.nwapw.abacus.exception.EvaluationException import org.nwapw.abacus.number.NumberInterface class NumberReducer(val abacus: Abacus, context: EvaluationContext) : Reducer { diff --git a/core/src/test/java/org/nwapw/abacus/tests/CalculationTests.java b/core/src/test/java/org/nwapw/abacus/tests/CalculationTests.java index af85be6..1aee10e 100755 --- a/core/src/test/java/org/nwapw/abacus/tests/CalculationTests.java +++ b/core/src/test/java/org/nwapw/abacus/tests/CalculationTests.java @@ -5,7 +5,7 @@ import org.junit.BeforeClass; import org.junit.Test; import org.nwapw.abacus.Abacus; import org.nwapw.abacus.config.Configuration; -import org.nwapw.abacus.function.DomainException; +import org.nwapw.abacus.exception.DomainException; import org.nwapw.abacus.number.NumberInterface; import org.nwapw.abacus.plugin.StandardPlugin; import org.nwapw.abacus.tree.TreeNode; diff --git a/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java b/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java index f7fb44d..c05f03b 100644 --- a/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java +++ b/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java @@ -12,10 +12,11 @@ import javafx.util.Callback; import javafx.util.StringConverter; import org.nwapw.abacus.Abacus; import org.nwapw.abacus.config.Configuration; +import org.nwapw.abacus.exception.ComputationInterruptedException; import org.nwapw.abacus.function.Documentation; import org.nwapw.abacus.function.DocumentationType; -import org.nwapw.abacus.function.DomainException; -import org.nwapw.abacus.function.EvaluationException; +import org.nwapw.abacus.exception.DomainException; +import org.nwapw.abacus.exception.EvaluationException; import org.nwapw.abacus.number.*; import org.nwapw.abacus.plugin.ClassFinder; import org.nwapw.abacus.plugin.PluginListener; From be94394a5c502688085c733223dd274475715b73 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 7 Sep 2017 13:05:49 -0700 Subject: [PATCH 4/5] Catch one exception. --- fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java b/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java index c05f03b..1f50424 100644 --- a/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java +++ b/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java @@ -12,6 +12,7 @@ import javafx.util.Callback; import javafx.util.StringConverter; import org.nwapw.abacus.Abacus; import org.nwapw.abacus.config.Configuration; +import org.nwapw.abacus.exception.AbacusException; import org.nwapw.abacus.exception.ComputationInterruptedException; import org.nwapw.abacus.function.Documentation; import org.nwapw.abacus.function.DocumentationType; @@ -153,7 +154,7 @@ public class AbacusController implements PluginListener { historyData.add(new HistoryModel(inputField.getText(), constructedTree.toString(), resultingString)); abacus.applyToContext(result.getResultingContext()); return resultingString; - } catch (ComputationInterruptedException | DomainException | EvaluationException exception) { + } catch (AbacusException exception) { return exception.getMessage(); } catch (RuntimeException exception) { exception.printStackTrace(); From 5b4773dee1a69838042aa98bbb0591754a2bf677 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 7 Sep 2017 13:21:18 -0700 Subject: [PATCH 5/5] Do not use null in exceptions and add messages to exceptions. --- .../org/nwapw/abacus/exception/AbacusException.java | 2 +- .../exception/ComputationInterruptedException.java | 2 +- .../org/nwapw/abacus/exception/DomainException.java | 2 +- .../nwapw/abacus/exception/EvaluationException.java | 2 +- .../nwapw/abacus/function/applicable/Applicable.kt | 3 ++- .../kotlin/org/nwapw/abacus/tree/NumberReducer.kt | 12 +++++++----- 6 files changed, 13 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/org/nwapw/abacus/exception/AbacusException.java b/core/src/main/java/org/nwapw/abacus/exception/AbacusException.java index 894e959..f71cfe1 100644 --- a/core/src/main/java/org/nwapw/abacus/exception/AbacusException.java +++ b/core/src/main/java/org/nwapw/abacus/exception/AbacusException.java @@ -3,7 +3,7 @@ package org.nwapw.abacus.exception; public class AbacusException extends RuntimeException { public AbacusException(String baseMessage, String description){ - super(baseMessage + ((description == null) ? "." : (": " + description))); + super(baseMessage + ((description.equals("")) ? "." : (": " + description))); } } diff --git a/core/src/main/java/org/nwapw/abacus/exception/ComputationInterruptedException.java b/core/src/main/java/org/nwapw/abacus/exception/ComputationInterruptedException.java index bd77649..5674a27 100644 --- a/core/src/main/java/org/nwapw/abacus/exception/ComputationInterruptedException.java +++ b/core/src/main/java/org/nwapw/abacus/exception/ComputationInterruptedException.java @@ -10,7 +10,7 @@ public class ComputationInterruptedException extends AbacusException { * Creates a new exception of this type. */ public ComputationInterruptedException() { - super("Computation interrupted", null); + super("Computation interrupted", ""); } } diff --git a/core/src/main/java/org/nwapw/abacus/exception/DomainException.java b/core/src/main/java/org/nwapw/abacus/exception/DomainException.java index 4b7fe17..e1cf139 100644 --- a/core/src/main/java/org/nwapw/abacus/exception/DomainException.java +++ b/core/src/main/java/org/nwapw/abacus/exception/DomainException.java @@ -18,7 +18,7 @@ public class DomainException extends AbacusException { * Creates a new DomainException with a default message. */ public DomainException(){ - this(null); + this(""); } } diff --git a/core/src/main/java/org/nwapw/abacus/exception/EvaluationException.java b/core/src/main/java/org/nwapw/abacus/exception/EvaluationException.java index 4763aaf..5eed066 100644 --- a/core/src/main/java/org/nwapw/abacus/exception/EvaluationException.java +++ b/core/src/main/java/org/nwapw/abacus/exception/EvaluationException.java @@ -11,7 +11,7 @@ public class EvaluationException extends AbacusException { * Creates a new EvaluationException with the default string. */ public EvaluationException() { - this(null); + this(""); } /** diff --git a/core/src/main/kotlin/org/nwapw/abacus/function/applicable/Applicable.kt b/core/src/main/kotlin/org/nwapw/abacus/function/applicable/Applicable.kt index 5103d8b..0d64ba6 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/function/applicable/Applicable.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/function/applicable/Applicable.kt @@ -36,7 +36,8 @@ interface Applicable { * @return the result of the operation, or null if parameters do not match. */ fun apply(context: MutableEvaluationContext, vararg params: T): O { - if (!matchesParams(context, params)) throw DomainException() + if (!matchesParams(context, params)) + throw DomainException("parameters do not match function requirements.") return applyInternal(context, params) } diff --git a/core/src/main/kotlin/org/nwapw/abacus/tree/NumberReducer.kt b/core/src/main/kotlin/org/nwapw/abacus/tree/NumberReducer.kt index e94ab46..7a80ca7 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/NumberReducer.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/NumberReducer.kt @@ -18,14 +18,14 @@ class NumberReducer(val abacus: Abacus, context: EvaluationContext) : Reducer { context.inheritedNumberImplementation?.instanceForString(treeNode.number) - ?: throw EvaluationException() + ?: throw EvaluationException("no number implementation selected.") } is VariableNode -> { val variable = context.getVariable(treeNode.variable) if(variable != null) return variable val definition = context.getDefinition(treeNode.variable) if(definition != null) return definition.reduce(this) - throw EvaluationException() + throw EvaluationException("variable is not defined.") } is NumberUnaryNode -> { val child = children[0] as NumberInterface @@ -36,13 +36,15 @@ class NumberReducer(val abacus: Abacus, context: EvaluationContext) : Reducer { val left = children[0] as NumberInterface val right = children[1] as NumberInterface - val promotionResult = promotionManager.promote(left, right) ?: throw EvaluationException() + val promotionResult = promotionManager.promote(left, right) ?: + throw EvaluationException("promotion failed.") context.numberImplementation = promotionResult.promotedTo abacus.pluginManager.operatorFor(treeNode.operation).apply(context, *promotionResult.items) } is FunctionNode -> { val promotionResult = promotionManager - .promote(*children.map { it as NumberInterface }.toTypedArray()) ?: throw EvaluationException() + .promote(*children.map { it as NumberInterface }.toTypedArray()) ?: + throw EvaluationException("promotion failed.") context.numberImplementation = promotionResult.promotedTo abacus.pluginManager.functionFor(treeNode.callTo).apply(context, *promotionResult.items) } @@ -58,7 +60,7 @@ class NumberReducer(val abacus: Abacus, context: EvaluationContext) : Reducer throw EvaluationException() + else -> throw EvaluationException("unrecognized tree node.") } }