diff --git a/build.gradle b/build.gradle index ee5a968..df2b0fd 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,22 @@ +buildscript { + ext.kotlin_version = '1.1.3' + ext.dokka_version = '0.9.15' + + repositories { + jcenter() + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath "org.jetbrains.dokka:dokka-gradle-plugin:$dokka_version" + } +} + subprojects { apply plugin: 'java' + apply plugin: 'kotlin' + apply plugin: 'org.jetbrains.dokka' repositories { mavenCentral() diff --git a/core/build.gradle b/core/build.gradle index 55865f2..5aff72f 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -1,7 +1,3 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '1.1.3' -} - dependencies { compile 'com.moandjiezana.toml:toml4j:0.7.1' testCompile 'junit:junit:4.12' diff --git a/core/src/main/java/org/nwapw/abacus/Abacus.java b/core/src/main/java/org/nwapw/abacus/Abacus.java index 826f266..113bda8 100644 --- a/core/src/main/java/org/nwapw/abacus/Abacus.java +++ b/core/src/main/java/org/nwapw/abacus/Abacus.java @@ -53,7 +53,7 @@ public class Abacus { numberReducer = new NumberReducer(this); this.configuration = new Configuration(configuration); LexerTokenizer lexerTokenizer = new LexerTokenizer(); - ShuntingYardParser shuntingYardParser = new ShuntingYardParser(this); + ShuntingYardParser shuntingYardParser = new ShuntingYardParser(); treeBuilder = new TreeBuilder<>(lexerTokenizer, shuntingYardParser); pluginManager.addListener(shuntingYardParser); diff --git a/core/src/main/java/org/nwapw/abacus/parsing/LexerTokenizer.java b/core/src/main/java/org/nwapw/abacus/parsing/LexerTokenizer.java index 790882a..b7bdd1f 100644 --- a/core/src/main/java/org/nwapw/abacus/parsing/LexerTokenizer.java +++ b/core/src/main/java/org/nwapw/abacus/parsing/LexerTokenizer.java @@ -34,6 +34,7 @@ public class LexerTokenizer implements Tokenizer>, PluginListen register(" ", TokenType.WHITESPACE); register(",", TokenType.COMMA); register("[0-9]*(\\.[0-9]+)?", TokenType.NUM); + register("[a-zA-Z]+", TokenType.VARIABLE); register("\\(", TokenType.OPEN_PARENTH); register("\\)", TokenType.CLOSE_PARENTH); }}; 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 c7a5615..c792463 100644 --- a/core/src/main/java/org/nwapw/abacus/parsing/ShuntingYardParser.java +++ b/core/src/main/java/org/nwapw/abacus/parsing/ShuntingYardParser.java @@ -1,6 +1,5 @@ package org.nwapw.abacus.parsing; -import org.nwapw.abacus.Abacus; import org.nwapw.abacus.function.Operator; import org.nwapw.abacus.function.OperatorAssociativity; import org.nwapw.abacus.function.OperatorType; @@ -17,10 +16,6 @@ import java.util.*; */ public class ShuntingYardParser implements Parser>, PluginListener { - /** - * The Abacus instance used to create number instances. - */ - private Abacus abacus; /** * Map of operator precedences, loaded from the plugin operators. */ @@ -35,12 +30,9 @@ public class ShuntingYardParser implements Parser>, PluginListe private Map typeMap; /** - * Creates a new Shunting Yard parser with the given Abacus instance. - * - * @param abacus the abacus instance. + * Creates a new Shunting Yard parser. */ - public ShuntingYardParser(Abacus abacus) { - this.abacus = abacus; + public ShuntingYardParser() { precedenceMap = new HashMap<>(); associativityMap = new HashMap<>(); typeMap = new HashMap<>(); @@ -61,7 +53,7 @@ public class ShuntingYardParser implements Parser>, PluginListe Match match = from.remove(0); previousType = matchType; matchType = match.getType(); - if (matchType == TokenType.NUM) { + if (matchType == TokenType.NUM || matchType == TokenType.VARIABLE) { output.add(match); } else if (matchType == TokenType.FUNCTION) { output.add(new Match<>("", TokenType.INTERNAL_FUNCTION_END)); @@ -143,7 +135,9 @@ public class ShuntingYardParser implements Parser>, PluginListe else return new UnaryNode(operator, applyTo); } } else if (matchType == TokenType.NUM) { - return new NumberNode(abacus.numberFromString(match.getContent())); + return new NumberNode(match.getContent()); + } else if (matchType == TokenType.VARIABLE) { + return new VariableNode(match.getContent()); } else if (matchType == TokenType.FUNCTION) { String functionName = match.getContent(); FunctionNode node = new FunctionNode(functionName); diff --git a/core/src/main/java/org/nwapw/abacus/tree/NumberReducer.java b/core/src/main/java/org/nwapw/abacus/tree/NumberReducer.java index 8584231..4dae775 100644 --- a/core/src/main/java/org/nwapw/abacus/tree/NumberReducer.java +++ b/core/src/main/java/org/nwapw/abacus/tree/NumberReducer.java @@ -27,7 +27,9 @@ public class NumberReducer implements Reducer { @Override public NumberInterface reduceNode(TreeNode node, Object... children) { if (node instanceof NumberNode) { - return ((NumberNode) node).getNumber(); + return abacus.numberFromString(((NumberNode) node).getNumber()); + } else if(node instanceof VariableNode) { + return abacus.numberFromString("0"); } else if (node instanceof BinaryNode) { NumberInterface left = (NumberInterface) children[0]; NumberInterface right = (NumberInterface) children[1]; diff --git a/core/src/main/java/org/nwapw/abacus/tree/TokenType.java b/core/src/main/java/org/nwapw/abacus/tree/TokenType.java index ebb8861..aa1957a 100644 --- a/core/src/main/java/org/nwapw/abacus/tree/TokenType.java +++ b/core/src/main/java/org/nwapw/abacus/tree/TokenType.java @@ -7,7 +7,7 @@ package org.nwapw.abacus.tree; public enum TokenType { INTERNAL_FUNCTION_END(-1), - ANY(0), WHITESPACE(1), COMMA(2), OP(3), NUM(4), FUNCTION(5), OPEN_PARENTH(6), CLOSE_PARENTH(7); + ANY(0), WHITESPACE(1), COMMA(2), OP(3), NUM(4), VARIABLE(5), FUNCTION(6), OPEN_PARENTH(7), CLOSE_PARENTH(8); /** * The priority by which this token gets sorted. 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 03b299d..de6597a 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/tree/NumberNode.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/NumberNode.kt @@ -10,14 +10,14 @@ import org.nwapw.abacus.number.NumberInterface * * @number the number value of this node. */ -data class NumberNode(val number: NumberInterface) : TreeNode() { +data class NumberNode(val number: String) : TreeNode() { override fun reduce(reducer: Reducer): T? { return reducer.reduceNode(this) } override fun toString(): String { - return number.toString() + return number } } \ 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 new file mode 100644 index 0000000..0bf05c6 --- /dev/null +++ b/core/src/main/kotlin/org/nwapw/abacus/tree/VariableNode.kt @@ -0,0 +1,21 @@ +package org.nwapw.abacus.tree + +/** + * A tree node that holds a placeholder variable. + * + * This node holds a variable string, and acts similarly to a number, + * with the key difference of not actually holding a value at runtime. + * + * @param variable the actual variable name that this node represents. + */ +data class VariableNode(val variable: String) : TreeNode() { + + override fun reduce(reducer: Reducer): T? { + return reducer.reduceNode(this) + } + + override fun toString(): String { + return variable + } + +} \ No newline at end of file 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 766376c..b210226 100755 --- a/core/src/test/java/org/nwapw/abacus/tests/CalculationTests.java +++ b/core/src/test/java/org/nwapw/abacus/tests/CalculationTests.java @@ -101,7 +101,7 @@ public class CalculationTests { 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)`^0.9999)"); + testEvalError("(-13)^.9999", "((13)`^.9999)"); } } diff --git a/fx/build.gradle b/fx/build.gradle index f00f056..d72592b 100644 --- a/fx/build.gradle +++ b/fx/build.gradle @@ -1,6 +1,3 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '1.1.3' -} apply plugin: 'application' dependencies {