diff --git a/core/src/main/java/org/nwapw/abacus/function/DomainException.java b/core/src/main/java/org/nwapw/abacus/function/DomainException.java new file mode 100644 index 0000000..a7a449c --- /dev/null +++ b/core/src/main/java/org/nwapw/abacus/function/DomainException.java @@ -0,0 +1,24 @@ +package org.nwapw.abacus.function; + +/** + * Exception thrown if the function parameters do not match + * requirements. + */ +public class DomainException extends RuntimeException { + + /** + * Creates a new DomainException. + * @param reason the reason for which the exception is thrown. + */ + public DomainException(String reason) { + super(reason); + } + + /** + * Creates a new DomainException with a default message. + */ + public DomainException(){ + this("Domain Error"); + } + +} 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 69f0afc..ed8bb91 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,5 +1,6 @@ package org.nwapw.abacus.function.applicable +import org.nwapw.abacus.function.DomainException import org.nwapw.abacus.plugin.NumberImplementation /** @@ -25,7 +26,7 @@ interface Applicable { * @param params the parameters to apply to. * @return the result of the application. */ - fun applyInternal(implementation: NumberImplementation, params: Array): O? + fun applyInternal(implementation: NumberImplementation, params: Array): O /** * If the parameters can be used with this applicable, returns @@ -34,8 +35,8 @@ interface Applicable { * @param params the parameters to apply to. * @return the result of the operation, or null if parameters do not match. */ - fun apply(implementation: NumberImplementation, vararg params: T): O? { - if (!matchesParams(implementation, params)) return null + fun apply(implementation: NumberImplementation, vararg params: T): O { + if (!matchesParams(implementation, params)) throw DomainException() return applyInternal(implementation, params) } diff --git a/core/src/main/kotlin/org/nwapw/abacus/function/applicable/ReducerApplicable.kt b/core/src/main/kotlin/org/nwapw/abacus/function/applicable/ReducerApplicable.kt index bdb3276..54340a4 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/function/applicable/ReducerApplicable.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/function/applicable/ReducerApplicable.kt @@ -1,5 +1,6 @@ package org.nwapw.abacus.function.applicable +import org.nwapw.abacus.function.DomainException import org.nwapw.abacus.plugin.NumberImplementation import org.nwapw.abacus.tree.Reducer @@ -27,7 +28,7 @@ interface ReducerApplicable { * @param params the arguments to apply to. * @return the result of the application. */ - fun applyWithReducerInternal(implementation: NumberImplementation, reducer: Reducer, params: Array): O? + fun applyWithReducerInternal(implementation: NumberImplementation, reducer: Reducer, params: Array): O /** * Applies this applicable to the given arguments, and reducer, @@ -36,8 +37,8 @@ interface ReducerApplicable { * @param params the arguments to apply to. * @return the result of the application, or null if the arguments are incompatible. */ - fun applyWithReducer(implementation: NumberImplementation, reducer: Reducer, vararg params: T): O? { - if (!matchesParams(implementation, params)) return null + fun applyWithReducer(implementation: NumberImplementation, reducer: Reducer, vararg params: T): O { + if (!matchesParams(implementation, params)) throw DomainException() return applyWithReducerInternal(implementation, reducer, params) } 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 b210226..39cf091 100755 --- a/core/src/test/java/org/nwapw/abacus/tests/CalculationTests.java +++ b/core/src/test/java/org/nwapw/abacus/tests/CalculationTests.java @@ -5,6 +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.number.NumberInterface; import org.nwapw.abacus.plugin.StandardPlugin; import org.nwapw.abacus.tree.TreeNode; @@ -28,11 +29,14 @@ public class CalculationTests { Assert.assertTrue(result.toString().startsWith(output)); } - private void testEvalError(String input, String parseOutput) { + private void testDomainException(String input, String parseOutput) { TreeNode parsedTree = abacus.parseString(input); Assert.assertNotNull(parsedTree); Assert.assertEquals(parsedTree.toString(), parseOutput); - Assert.assertNull(abacus.evaluateTree(parsedTree)); + try { + abacus.evaluateTree(parsedTree); + Assert.fail("Function did not throw DomainException."); + } catch (DomainException e){ } } @Test @@ -73,7 +77,7 @@ public class CalculationTests { @Test public void testLn() { - testEvalError("ln(-1)", "ln((1)`)"); + testDomainException("ln(-1)", "ln((1)`)"); testOutput("ln2", "ln(2)", "0.6931471805599453094172321214581765680755"); } @@ -100,8 +104,8 @@ public class CalculationTests { testOutput("2^-1", "(2^(1)`)", "0.5"); testOutput("2^50", "(2^50)", "112589990684262"); testOutput("7^(-sqrt2*17)", "(7^((sqrt(2)*17))`)", "4.81354609155297814551845300063563"); - testEvalError("0^0", "(0^0)"); - testEvalError("(-13)^.9999", "((13)`^.9999)"); + testDomainException("0^0", "(0^0)"); + testDomainException("(-13)^.9999", "((13)`^.9999)"); } } 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 4f62247..8b05f3f 100644 --- a/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java +++ b/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java @@ -14,6 +14,7 @@ import org.nwapw.abacus.Abacus; 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.number.*; import org.nwapw.abacus.plugin.ClassFinder; import org.nwapw.abacus.plugin.PluginListener; @@ -152,6 +153,8 @@ public class AbacusController implements PluginListener { return resultingString; } catch (ComputationInterruptedException exception) { return ERR_STOP; + } catch (DomainException exception) { + return exception.getMessage(); } catch (RuntimeException exception) { exception.printStackTrace(); return ERR_EXCEPTION;