mirror of
https://github.com/DanilaFe/abacus
synced 2026-01-25 16:15:19 +00:00
Compare commits
13 Commits
pages-crea
...
variable-p
| Author | SHA1 | Date | |
|---|---|---|---|
| 192269ea9a | |||
| f134e5aa04 | |||
| ece9f1ae04 | |||
| 553c7354c1 | |||
| 50ede6460c | |||
| beb583a231 | |||
| e0ff229df4 | |||
| 1c751353f1 | |||
| 0a15043b63 | |||
| 21e059c1ca | |||
| 16faceb3cc | |||
| 251da90d57 | |||
| a7536b198f |
16
build.gradle
16
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 {
|
subprojects {
|
||||||
|
|
||||||
apply plugin: 'java'
|
apply plugin: 'java'
|
||||||
|
apply plugin: 'kotlin'
|
||||||
|
apply plugin: 'org.jetbrains.dokka'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
plugins {
|
|
||||||
id 'org.jetbrains.kotlin.jvm' version '1.1.3'
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile 'com.moandjiezana.toml:toml4j:0.7.1'
|
compile 'com.moandjiezana.toml:toml4j:0.7.1'
|
||||||
testCompile 'junit:junit:4.12'
|
testCompile 'junit:junit:4.12'
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class Abacus {
|
|||||||
numberReducer = new NumberReducer(this);
|
numberReducer = new NumberReducer(this);
|
||||||
this.configuration = new Configuration(configuration);
|
this.configuration = new Configuration(configuration);
|
||||||
LexerTokenizer lexerTokenizer = new LexerTokenizer();
|
LexerTokenizer lexerTokenizer = new LexerTokenizer();
|
||||||
ShuntingYardParser shuntingYardParser = new ShuntingYardParser(this);
|
ShuntingYardParser shuntingYardParser = new ShuntingYardParser();
|
||||||
treeBuilder = new TreeBuilder<>(lexerTokenizer, shuntingYardParser);
|
treeBuilder = new TreeBuilder<>(lexerTokenizer, shuntingYardParser);
|
||||||
|
|
||||||
pluginManager.addListener(shuntingYardParser);
|
pluginManager.addListener(shuntingYardParser);
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
package org.nwapw.abacus.function;
|
package org.nwapw.abacus.function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum that holds the type of documentation that has been
|
||||||
|
* registered with Abacus.
|
||||||
|
*/
|
||||||
public enum DocumentationType {
|
public enum DocumentationType {
|
||||||
|
|
||||||
FUNCTION
|
FUNCTION
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ public class LexerTokenizer implements Tokenizer<Match<TokenType>>, PluginListen
|
|||||||
register(" ", TokenType.WHITESPACE);
|
register(" ", TokenType.WHITESPACE);
|
||||||
register(",", TokenType.COMMA);
|
register(",", TokenType.COMMA);
|
||||||
register("[0-9]*(\\.[0-9]+)?", TokenType.NUM);
|
register("[0-9]*(\\.[0-9]+)?", TokenType.NUM);
|
||||||
|
register("[a-zA-Z]+", TokenType.VARIABLE);
|
||||||
register("\\(", TokenType.OPEN_PARENTH);
|
register("\\(", TokenType.OPEN_PARENTH);
|
||||||
register("\\)", TokenType.CLOSE_PARENTH);
|
register("\\)", TokenType.CLOSE_PARENTH);
|
||||||
}};
|
}};
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package org.nwapw.abacus.parsing;
|
package org.nwapw.abacus.parsing;
|
||||||
|
|
||||||
import org.nwapw.abacus.Abacus;
|
|
||||||
import org.nwapw.abacus.function.Operator;
|
import org.nwapw.abacus.function.Operator;
|
||||||
import org.nwapw.abacus.function.OperatorAssociativity;
|
import org.nwapw.abacus.function.OperatorAssociativity;
|
||||||
import org.nwapw.abacus.function.OperatorType;
|
import org.nwapw.abacus.function.OperatorType;
|
||||||
@@ -17,10 +16,6 @@ import java.util.*;
|
|||||||
*/
|
*/
|
||||||
public class ShuntingYardParser implements Parser<Match<TokenType>>, PluginListener {
|
public class ShuntingYardParser implements Parser<Match<TokenType>>, PluginListener {
|
||||||
|
|
||||||
/**
|
|
||||||
* The Abacus instance used to create number instances.
|
|
||||||
*/
|
|
||||||
private Abacus abacus;
|
|
||||||
/**
|
/**
|
||||||
* Map of operator precedences, loaded from the plugin operators.
|
* Map of operator precedences, loaded from the plugin operators.
|
||||||
*/
|
*/
|
||||||
@@ -35,12 +30,9 @@ public class ShuntingYardParser implements Parser<Match<TokenType>>, PluginListe
|
|||||||
private Map<String, OperatorType> typeMap;
|
private Map<String, OperatorType> typeMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Shunting Yard parser with the given Abacus instance.
|
* Creates a new Shunting Yard parser.
|
||||||
*
|
|
||||||
* @param abacus the abacus instance.
|
|
||||||
*/
|
*/
|
||||||
public ShuntingYardParser(Abacus abacus) {
|
public ShuntingYardParser() {
|
||||||
this.abacus = abacus;
|
|
||||||
precedenceMap = new HashMap<>();
|
precedenceMap = new HashMap<>();
|
||||||
associativityMap = new HashMap<>();
|
associativityMap = new HashMap<>();
|
||||||
typeMap = new HashMap<>();
|
typeMap = new HashMap<>();
|
||||||
@@ -61,7 +53,7 @@ public class ShuntingYardParser implements Parser<Match<TokenType>>, PluginListe
|
|||||||
Match<TokenType> match = from.remove(0);
|
Match<TokenType> match = from.remove(0);
|
||||||
previousType = matchType;
|
previousType = matchType;
|
||||||
matchType = match.getType();
|
matchType = match.getType();
|
||||||
if (matchType == TokenType.NUM) {
|
if (matchType == TokenType.NUM || matchType == TokenType.VARIABLE) {
|
||||||
output.add(match);
|
output.add(match);
|
||||||
} else if (matchType == TokenType.FUNCTION) {
|
} else if (matchType == TokenType.FUNCTION) {
|
||||||
output.add(new Match<>("", TokenType.INTERNAL_FUNCTION_END));
|
output.add(new Match<>("", TokenType.INTERNAL_FUNCTION_END));
|
||||||
@@ -143,7 +135,9 @@ public class ShuntingYardParser implements Parser<Match<TokenType>>, PluginListe
|
|||||||
else return new UnaryNode(operator, applyTo);
|
else return new UnaryNode(operator, applyTo);
|
||||||
}
|
}
|
||||||
} else if (matchType == TokenType.NUM) {
|
} 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) {
|
} else if (matchType == TokenType.FUNCTION) {
|
||||||
String functionName = match.getContent();
|
String functionName = match.getContent();
|
||||||
FunctionNode node = new FunctionNode(functionName);
|
FunctionNode node = new FunctionNode(functionName);
|
||||||
|
|||||||
@@ -27,7 +27,9 @@ public class NumberReducer implements Reducer<NumberInterface> {
|
|||||||
@Override
|
@Override
|
||||||
public NumberInterface reduceNode(TreeNode node, Object... children) {
|
public NumberInterface reduceNode(TreeNode node, Object... children) {
|
||||||
if (node instanceof NumberNode) {
|
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) {
|
} else if (node instanceof BinaryNode) {
|
||||||
NumberInterface left = (NumberInterface) children[0];
|
NumberInterface left = (NumberInterface) children[0];
|
||||||
NumberInterface right = (NumberInterface) children[1];
|
NumberInterface right = (NumberInterface) children[1];
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ package org.nwapw.abacus.tree;
|
|||||||
public enum TokenType {
|
public enum TokenType {
|
||||||
|
|
||||||
INTERNAL_FUNCTION_END(-1),
|
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.
|
* The priority by which this token gets sorted.
|
||||||
|
|||||||
@@ -10,14 +10,14 @@ import org.nwapw.abacus.number.NumberInterface
|
|||||||
*
|
*
|
||||||
* @number the number value of this node.
|
* @number the number value of this node.
|
||||||
*/
|
*/
|
||||||
data class NumberNode(val number: NumberInterface) : TreeNode() {
|
data class NumberNode(val number: String) : TreeNode() {
|
||||||
|
|
||||||
override fun <T : Any> reduce(reducer: Reducer<T>): T? {
|
override fun <T : Any> reduce(reducer: Reducer<T>): T? {
|
||||||
return reducer.reduceNode(this)
|
return reducer.reduceNode(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return number.toString()
|
return number
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
21
core/src/main/kotlin/org/nwapw/abacus/tree/VariableNode.kt
Normal file
21
core/src/main/kotlin/org/nwapw/abacus/tree/VariableNode.kt
Normal file
@@ -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 <T : Any> reduce(reducer: Reducer<T>): T? {
|
||||||
|
return reducer.reduceNode(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return variable
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -101,7 +101,7 @@ public class CalculationTests {
|
|||||||
testOutput("2^50", "(2^50)", "112589990684262");
|
testOutput("2^50", "(2^50)", "112589990684262");
|
||||||
testOutput("7^(-sqrt2*17)", "(7^((sqrt(2)*17))`)", "4.81354609155297814551845300063563");
|
testOutput("7^(-sqrt2*17)", "(7^((sqrt(2)*17))`)", "4.81354609155297814551845300063563");
|
||||||
testEvalError("0^0", "(0^0)");
|
testEvalError("0^0", "(0^0)");
|
||||||
testEvalError("(-13)^.9999", "((13)`^0.9999)");
|
testEvalError("(-13)^.9999", "((13)`^.9999)");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
img {
|
img {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 432px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div#buttons {
|
div#buttons {
|
||||||
|
|||||||
@@ -5,6 +5,23 @@ title: About
|
|||||||
permalink: /about/
|
permalink: /about/
|
||||||
---
|
---
|
||||||
|
|
||||||
Welcome to the Abacus project website.
|
## So... what IS Abacus?
|
||||||
This website is currently under construction, please, check
|
It's a calculator. Obviously. But what makes it better than
|
||||||
back later.
|
what already exists? There's a few things. Abacus is:
|
||||||
|
* Programmable, and not in TI Basic.
|
||||||
|
* Precise. With the "precise" option, Abacus can keep up to 50 significant figures.
|
||||||
|
* Capable. Ever wonder what 2<sup>700</sup> is? How about 8!!? Abacus can tell you!
|
||||||
|
* Offline. While Wolfram Alpha can do powerful math, it needs internet connection!
|
||||||
|
* Built for the desktop. Why use buttons on the screen when there's buttons on the keyboard?
|
||||||
|
* Open source. Don't like something? Help is always welcome!
|
||||||
|
|
||||||
|
## Why was Abacus made?
|
||||||
|
The initial project was proposed for the [Northwest Advanced Programming Workshop](http://nwapw.org/about/).
|
||||||
|
You can read the project proposal on the main GitHub page, although the idea has
|
||||||
|
changed quite a bit, mostly in shifting from "fast" to "precise".
|
||||||
|
|
||||||
|
## What is Abacus made with?
|
||||||
|
Java and Kotlin. Java provides a good layer of abstraction and a great standard
|
||||||
|
library, while Kotlin allows for the reduction of boilerplate code and null
|
||||||
|
safety. Using JVM-based languages also allows Abacus to expose its entire
|
||||||
|
API to plugins, and load them at runtime.
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ a {
|
|||||||
color: $background-color;
|
color: $background-color;
|
||||||
|
|
||||||
&.button {
|
&.button {
|
||||||
|
display: inline-block;
|
||||||
background-color: $background-color;
|
background-color: $background-color;
|
||||||
color: $clear-color;
|
color: $clear-color;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
plugins {
|
|
||||||
id 'org.jetbrains.kotlin.jvm' version '1.1.3'
|
|
||||||
}
|
|
||||||
apply plugin: 'application'
|
apply plugin: 'application'
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|||||||
Reference in New Issue
Block a user