mirror of
https://github.com/DanilaFe/abacus
synced 2026-01-26 16:45:21 +00:00
Compare commits
13 Commits
rational-n
...
function-d
| Author | SHA1 | Date | |
|---|---|---|---|
| 33b175a3c6 | |||
| c95a6df304 | |||
| 3316f02e2b | |||
| 6767a0e4aa | |||
| 400e4578a0 | |||
| 9d92d0eebb | |||
| fdcf2b5c6d | |||
| 8c3de54d0c | |||
| 5a57544067 | |||
| 61f40c72aa | |||
| ea5ff08c09 | |||
| 5f80c0bf14 | |||
| e61cfdca46 |
1
build.gradle
Executable file → Normal file
1
build.gradle
Executable file → Normal file
@@ -11,7 +11,6 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile group: 'org.apache.commons', name: 'commons-math3', version: '3.6.1'
|
|
||||||
compile 'com.moandjiezana.toml:toml4j:0.7.1'
|
compile 'com.moandjiezana.toml:toml4j:0.7.1'
|
||||||
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8"
|
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8"
|
||||||
testCompile 'junit:junit:4.12'
|
testCompile 'junit:junit:4.12'
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package org.nwapw.abacus.function;
|
||||||
|
|
||||||
|
public enum DocumentationType {
|
||||||
|
|
||||||
|
FUNCTION
|
||||||
|
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import javafx.collections.FXCollections;
|
|||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.collections.transformation.FilteredList;
|
import javafx.collections.transformation.FilteredList;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.control.cell.CheckBoxListCell;
|
import javafx.scene.control.cell.CheckBoxListCell;
|
||||||
import javafx.scene.text.Text;
|
import javafx.scene.text.Text;
|
||||||
@@ -14,6 +15,8 @@ import javafx.util.Callback;
|
|||||||
import javafx.util.StringConverter;
|
import javafx.util.StringConverter;
|
||||||
import org.nwapw.abacus.Abacus;
|
import org.nwapw.abacus.Abacus;
|
||||||
import org.nwapw.abacus.config.Configuration;
|
import org.nwapw.abacus.config.Configuration;
|
||||||
|
import org.nwapw.abacus.function.Documentation;
|
||||||
|
import org.nwapw.abacus.function.DocumentationType;
|
||||||
import org.nwapw.abacus.number.ComputationInterruptedException;
|
import org.nwapw.abacus.number.ComputationInterruptedException;
|
||||||
import org.nwapw.abacus.number.NumberInterface;
|
import org.nwapw.abacus.number.NumberInterface;
|
||||||
import org.nwapw.abacus.plugin.ClassFinder;
|
import org.nwapw.abacus.plugin.ClassFinder;
|
||||||
@@ -24,7 +27,10 @@ import org.nwapw.abacus.tree.TreeNode;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -97,7 +103,7 @@ public class AbacusController implements PluginListener {
|
|||||||
@FXML
|
@FXML
|
||||||
private TextField computationLimitField;
|
private TextField computationLimitField;
|
||||||
@FXML
|
@FXML
|
||||||
private ListView<String> functionListView;
|
private ListView<Documentation> functionListView;
|
||||||
@FXML
|
@FXML
|
||||||
private TextField functionListSearchField;
|
private TextField functionListSearchField;
|
||||||
|
|
||||||
@@ -120,11 +126,11 @@ public class AbacusController implements PluginListener {
|
|||||||
/**
|
/**
|
||||||
* The list of functions that are registered in the calculator.
|
* The list of functions that are registered in the calculator.
|
||||||
*/
|
*/
|
||||||
private ObservableList<String> functionList;
|
private ObservableList<Documentation> functionList;
|
||||||
/**
|
/**
|
||||||
* The filtered list displayed to the user.
|
* The filtered list displayed to the user.
|
||||||
*/
|
*/
|
||||||
private FilteredList<String> functionFilter;
|
private FilteredList<Documentation> functionFilter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The abacus instance used for changing the plugin configuration.
|
* The abacus instance used for changing the plugin configuration.
|
||||||
@@ -216,7 +222,7 @@ public class AbacusController implements PluginListener {
|
|||||||
Callback<TableColumn<HistoryModel, String>, TableCell<HistoryModel, String>> cellFactory =
|
Callback<TableColumn<HistoryModel, String>, TableCell<HistoryModel, String>> cellFactory =
|
||||||
param -> new CopyableCell<>();
|
param -> new CopyableCell<>();
|
||||||
Callback<ListView<ToggleablePlugin>, ListCell<ToggleablePlugin>> pluginCellFactory =
|
Callback<ListView<ToggleablePlugin>, ListCell<ToggleablePlugin>> pluginCellFactory =
|
||||||
param -> new CheckBoxListCell<>(ToggleablePlugin::getEnabledProperty, new StringConverter<ToggleablePlugin>() {
|
param -> new CheckBoxListCell<>(ToggleablePlugin::enabledProperty, new StringConverter<ToggleablePlugin>() {
|
||||||
@Override
|
@Override
|
||||||
public String toString(ToggleablePlugin object) {
|
public String toString(ToggleablePlugin object) {
|
||||||
return object.getClassName().substring(object.getClassName().lastIndexOf('.') + 1);
|
return object.getClassName().substring(object.getClassName().lastIndexOf('.') + 1);
|
||||||
@@ -224,15 +230,15 @@ public class AbacusController implements PluginListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ToggleablePlugin fromString(String string) {
|
public ToggleablePlugin fromString(String string) {
|
||||||
return new ToggleablePlugin(string, true);
|
return new ToggleablePlugin(true, string);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
functionList = FXCollections.observableArrayList();
|
functionList = FXCollections.observableArrayList();
|
||||||
functionFilter = new FilteredList<>(functionList, (s) -> true);
|
functionFilter = new FilteredList<>(functionList, (s) -> true);
|
||||||
functionListView.setItems(functionFilter);
|
functionListView.setItems(functionFilter);
|
||||||
functionListSearchField.textProperty().addListener((observable, oldValue, newValue) ->
|
functionListSearchField.textProperty().addListener((observable, oldValue, newValue) ->
|
||||||
functionFilter.setPredicate((newValue.length() == 0) ? ((s) -> true) : ((s) -> s.contains(newValue))));
|
functionFilter.setPredicate((newValue.length() == 0) ? ((s) -> true) : ((s) -> s.matches(newValue))));
|
||||||
|
functionListView.setCellFactory(param -> new DocumentationCell());
|
||||||
historyData = FXCollections.observableArrayList();
|
historyData = FXCollections.observableArrayList();
|
||||||
historyTable.setItems(historyData);
|
historyTable.setItems(historyData);
|
||||||
numberImplementationOptions = FXCollections.observableArrayList();
|
numberImplementationOptions = FXCollections.observableArrayList();
|
||||||
@@ -243,11 +249,11 @@ public class AbacusController implements PluginListener {
|
|||||||
enabledPluginView.setItems(enabledPlugins);
|
enabledPluginView.setItems(enabledPlugins);
|
||||||
enabledPluginView.setCellFactory(pluginCellFactory);
|
enabledPluginView.setCellFactory(pluginCellFactory);
|
||||||
inputColumn.setCellFactory(cellFactory);
|
inputColumn.setCellFactory(cellFactory);
|
||||||
inputColumn.setCellValueFactory(cell -> cell.getValue().getInputProperty());
|
inputColumn.setCellValueFactory(cell -> cell.getValue().inputProperty());
|
||||||
parsedColumn.setCellFactory(cellFactory);
|
parsedColumn.setCellFactory(cellFactory);
|
||||||
parsedColumn.setCellValueFactory(cell -> cell.getValue().getParsedProperty());
|
parsedColumn.setCellValueFactory(cell -> cell.getValue().parsedProperty());
|
||||||
outputColumn.setCellFactory(cellFactory);
|
outputColumn.setCellFactory(cellFactory);
|
||||||
outputColumn.setCellValueFactory(cell -> cell.getValue().getOutputProperty());
|
outputColumn.setCellValueFactory(cell -> cell.getValue().outputProperty());
|
||||||
coreTabPane.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
|
coreTabPane.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
if (oldValue.equals(settingsTab)) alertIfApplyNeeded(true);
|
if (oldValue.equals(settingsTab)) alertIfApplyNeeded(true);
|
||||||
});
|
});
|
||||||
@@ -343,12 +349,14 @@ public class AbacusController implements PluginListener {
|
|||||||
numberImplementationBox.getSelectionModel().select(toSelect);
|
numberImplementationBox.getSelectionModel().select(toSelect);
|
||||||
for (Class<?> pluginClass : abacus.getPluginManager().getLoadedPluginClasses()) {
|
for (Class<?> pluginClass : abacus.getPluginManager().getLoadedPluginClasses()) {
|
||||||
String fullName = pluginClass.getName();
|
String fullName = pluginClass.getName();
|
||||||
ToggleablePlugin plugin = new ToggleablePlugin(fullName, !disabledPlugins.contains(fullName));
|
ToggleablePlugin plugin = new ToggleablePlugin(!disabledPlugins.contains(fullName), fullName);
|
||||||
plugin.getEnabledProperty().addListener(e -> changesMade = true);
|
plugin.enabledProperty().addListener(e -> changesMade = true);
|
||||||
enabledPlugins.add(plugin);
|
enabledPlugins.add(plugin);
|
||||||
}
|
}
|
||||||
functionList.addAll(manager.getAllFunctions());
|
PluginManager pluginManager = abacus.getPluginManager();
|
||||||
functionList.sort(String::compareTo);
|
functionList.addAll(manager.getAllFunctions().stream().map(name -> pluginManager.documentationFor(name, DocumentationType.FUNCTION))
|
||||||
|
.collect(Collectors.toCollection(ArrayList::new)));
|
||||||
|
functionList.sort(Comparator.comparing(Documentation::getCodeName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
58
src/main/java/org/nwapw/abacus/fx/DocumentationCell.java
Normal file
58
src/main/java/org/nwapw/abacus/fx/DocumentationCell.java
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package org.nwapw.abacus.fx;
|
||||||
|
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.control.ListCell;
|
||||||
|
import javafx.scene.control.TitledPane;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
|
import org.nwapw.abacus.function.Documentation;
|
||||||
|
|
||||||
|
public class DocumentationCell extends ListCell<Documentation> {
|
||||||
|
|
||||||
|
private Label codeNameLabel;
|
||||||
|
private Label nameLabel;
|
||||||
|
private Label description;
|
||||||
|
private Label longDescription;
|
||||||
|
private TitledPane titledPane;
|
||||||
|
|
||||||
|
public DocumentationCell(){
|
||||||
|
VBox vbox = new VBox();
|
||||||
|
vbox.setSpacing(10);
|
||||||
|
titledPane = new TitledPane();
|
||||||
|
codeNameLabel = new Label();
|
||||||
|
nameLabel = new Label();
|
||||||
|
description = new Label();
|
||||||
|
longDescription = new Label();
|
||||||
|
codeNameLabel.setWrapText(true);
|
||||||
|
nameLabel.setWrapText(true);
|
||||||
|
description.setWrapText(true);
|
||||||
|
longDescription.setWrapText(true);
|
||||||
|
vbox.getChildren().add(codeNameLabel);
|
||||||
|
vbox.getChildren().add(nameLabel);
|
||||||
|
vbox.getChildren().add(description);
|
||||||
|
vbox.getChildren().add(longDescription);
|
||||||
|
titledPane.textProperty().bindBidirectional(codeNameLabel.textProperty());
|
||||||
|
titledPane.setContent(vbox);
|
||||||
|
titledPane.setExpanded(false);
|
||||||
|
titledPane.prefWidthProperty().bind(widthProperty());
|
||||||
|
|
||||||
|
visibleProperty().addListener((a, b, c) -> titledPane.setExpanded(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateItem(Documentation item, boolean empty) {
|
||||||
|
super.updateItem(item, empty);
|
||||||
|
if(empty){
|
||||||
|
codeNameLabel.setText("");
|
||||||
|
nameLabel.setText("");
|
||||||
|
description.setText("");
|
||||||
|
longDescription.setText("");
|
||||||
|
setGraphic(null);
|
||||||
|
} else {
|
||||||
|
codeNameLabel.setText(item.getCodeName());
|
||||||
|
nameLabel.setText(item.getName());
|
||||||
|
description.setText(item.getDescription());
|
||||||
|
longDescription.setText(item.getLongDescription());
|
||||||
|
setGraphic(titledPane);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
97
src/main/java/org/nwapw/abacus/fx/HistoryModel.java
Normal file
97
src/main/java/org/nwapw/abacus/fx/HistoryModel.java
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
package org.nwapw.abacus.fx;
|
||||||
|
|
||||||
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
|
import javafx.beans.property.StringProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The data model used for storing history entries.
|
||||||
|
*/
|
||||||
|
public class HistoryModel {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The property used for displaying the column
|
||||||
|
* for the user input.
|
||||||
|
*/
|
||||||
|
private final StringProperty input;
|
||||||
|
/**
|
||||||
|
* The property used for displaying the column
|
||||||
|
* that contains the parsed input.
|
||||||
|
*/
|
||||||
|
private final StringProperty parsed;
|
||||||
|
/**
|
||||||
|
* The property used for displaying the column
|
||||||
|
* that contains the program output.
|
||||||
|
*/
|
||||||
|
private final StringProperty output;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new history model with the given variables.
|
||||||
|
*
|
||||||
|
* @param input the user input
|
||||||
|
* @param parsed the parsed input
|
||||||
|
* @param output the program output.
|
||||||
|
*/
|
||||||
|
public HistoryModel(String input, String parsed, String output) {
|
||||||
|
this.input = new SimpleStringProperty();
|
||||||
|
this.parsed = new SimpleStringProperty();
|
||||||
|
this.output = new SimpleStringProperty();
|
||||||
|
this.input.setValue(input);
|
||||||
|
this.parsed.setValue(parsed);
|
||||||
|
this.output.setValue(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the input property.
|
||||||
|
*
|
||||||
|
* @return the input property.
|
||||||
|
*/
|
||||||
|
public StringProperty inputProperty() {
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the input.
|
||||||
|
*
|
||||||
|
* @return the input.
|
||||||
|
*/
|
||||||
|
public String getInput() {
|
||||||
|
return input.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the parsed input property.
|
||||||
|
*
|
||||||
|
* @return the parsed input property.
|
||||||
|
*/
|
||||||
|
public StringProperty parsedProperty() {
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the parsed input.
|
||||||
|
*
|
||||||
|
* @return the parsed input.
|
||||||
|
*/
|
||||||
|
public String getParsed() {
|
||||||
|
return parsed.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the output property.
|
||||||
|
*
|
||||||
|
* @return the output property.
|
||||||
|
*/
|
||||||
|
public StringProperty outputProperty() {
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the program output.
|
||||||
|
*
|
||||||
|
* @return the output.
|
||||||
|
*/
|
||||||
|
public String getOutput() {
|
||||||
|
return output.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
60
src/main/java/org/nwapw/abacus/fx/ToggleablePlugin.java
Normal file
60
src/main/java/org/nwapw/abacus/fx/ToggleablePlugin.java
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package org.nwapw.abacus.fx;
|
||||||
|
|
||||||
|
import javafx.beans.property.BooleanProperty;
|
||||||
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that represents an entry in the plugin check box list.
|
||||||
|
* The changes from this property are written to the config on application.
|
||||||
|
*/
|
||||||
|
public class ToggleablePlugin {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The property that determines whether the plugin will be enabled.
|
||||||
|
*/
|
||||||
|
private final BooleanProperty enabled;
|
||||||
|
/**
|
||||||
|
* The name of the class this entry toggles.
|
||||||
|
*/
|
||||||
|
private final String className;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new toggleable plugin with the given properties.
|
||||||
|
*
|
||||||
|
* @param enabled the enabled / disabled state at the beginning.
|
||||||
|
* @param className the name of the class this plugin toggles.
|
||||||
|
*/
|
||||||
|
public ToggleablePlugin(boolean enabled, String className) {
|
||||||
|
this.enabled = new SimpleBooleanProperty();
|
||||||
|
this.enabled.setValue(enabled);
|
||||||
|
this.className = className;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the enabled property of this plugin.
|
||||||
|
*
|
||||||
|
* @return the enabled property.
|
||||||
|
*/
|
||||||
|
public BooleanProperty enabledProperty() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if this plugin entry should be enabled.
|
||||||
|
*
|
||||||
|
* @return whether this plugin will be enabled.
|
||||||
|
*/
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the class name this plugin toggles.
|
||||||
|
*
|
||||||
|
* @return the class name that should be disabled.
|
||||||
|
*/
|
||||||
|
public String getClassName() {
|
||||||
|
return className;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -128,9 +128,5 @@ public class NaiveNumber extends NumberInterface {
|
|||||||
return Double.toString(Math.round(value * shiftBy) / shiftBy);
|
return Double.toString(Math.round(value * shiftBy) / shiftBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public NumberInterface getMaxError(){
|
|
||||||
return new NaiveNumber(Math.pow(10, -18));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -255,11 +255,4 @@ public abstract class NumberInterface {
|
|||||||
return promoteToInternal(toClass);
|
return promoteToInternal(toClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the smallest error this instance can tolerate depending
|
|
||||||
* on its precision and value.
|
|
||||||
* @return the smallest error that should be permitted in calculations.
|
|
||||||
*/
|
|
||||||
public abstract NumberInterface getMaxError();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
package org.nwapw.abacus.number;
|
package org.nwapw.abacus.number;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.RoundingMode;
|
||||||
import java.math.MathContext;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A number that uses a BigDecimal to store its value,
|
* A number that uses a BigDecimal to store its value,
|
||||||
@@ -23,21 +22,6 @@ public class PreciseNumber extends NumberInterface {
|
|||||||
*/
|
*/
|
||||||
public static final PreciseNumber TEN = new PreciseNumber(BigDecimal.TEN);
|
public static final PreciseNumber TEN = new PreciseNumber(BigDecimal.TEN);
|
||||||
|
|
||||||
/**
|
|
||||||
* The number of extra significant figures kept in calculations before rounding for output.
|
|
||||||
*/
|
|
||||||
private static int numExtraInternalSigFigs = 15;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MathContext that is used when rounding a number prior to output.
|
|
||||||
*/
|
|
||||||
private static MathContext outputContext = new MathContext(50);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MathContext that is actually used in calculations.
|
|
||||||
*/
|
|
||||||
private static MathContext internalContext = new MathContext(outputContext.getPrecision()+numExtraInternalSigFigs);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value of the PreciseNumber.
|
* The value of the PreciseNumber.
|
||||||
*/
|
*/
|
||||||
@@ -62,18 +46,9 @@ public class PreciseNumber extends NumberInterface {
|
|||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a precise number from the given BigInteger.
|
|
||||||
*
|
|
||||||
* @param value a BigInteger object representing the value of the number.
|
|
||||||
*/
|
|
||||||
public PreciseNumber(BigInteger value) {
|
|
||||||
this.value = new BigDecimal(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxPrecision() {
|
public int getMaxPrecision() {
|
||||||
return internalContext.getPrecision();
|
return 65;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -83,7 +58,7 @@ public class PreciseNumber extends NumberInterface {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NumberInterface divideInternal(NumberInterface divisor) {
|
public NumberInterface divideInternal(NumberInterface divisor) {
|
||||||
return new PreciseNumber(value.divide(((PreciseNumber) divisor).value, internalContext));
|
return new PreciseNumber(value.divide(((PreciseNumber) divisor).value, this.getMaxPrecision(), RoundingMode.HALF_UP));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -172,11 +147,7 @@ public class PreciseNumber extends NumberInterface {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return value.round(outputContext).toString();
|
BigDecimal rounded = value.setScale(getMaxPrecision() - 15, RoundingMode.HALF_UP);
|
||||||
}
|
return rounded.stripTrailingZeros().toPlainString();
|
||||||
|
|
||||||
@Override
|
|
||||||
public NumberInterface getMaxError(){
|
|
||||||
return new PreciseNumber(value.ulp()).multiplyInternal(TEN.intPowInternal(value.precision()-internalContext.getPrecision()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,115 +0,0 @@
|
|||||||
package org.nwapw.abacus.number;
|
|
||||||
|
|
||||||
import org.apache.commons.math3.fraction.BigFraction;
|
|
||||||
import org.apache.commons.math3.fraction.Fraction;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
public class RationalNumber extends NumberInterface{
|
|
||||||
|
|
||||||
static final RationalNumber ONE = new RationalNumber(BigFraction.ONE);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The value of the number.
|
|
||||||
*/
|
|
||||||
private BigFraction value;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new instance with the given value.
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
public RationalNumber(BigFraction value){
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMaxPrecision() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected NumberInterface multiplyInternal(NumberInterface multiplier) {
|
|
||||||
return new RationalNumber(value.multiply(((RationalNumber)multiplier).value));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected NumberInterface divideInternal(NumberInterface divisor) {
|
|
||||||
return new RationalNumber(value.divide(((RationalNumber)divisor).value));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected NumberInterface addInternal(NumberInterface summand) {
|
|
||||||
return new RationalNumber(value.add(((RationalNumber)summand).value));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected NumberInterface subtractInternal(NumberInterface subtrahend) {
|
|
||||||
return new RationalNumber(value.subtract(((RationalNumber)subtrahend).value));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected NumberInterface negateInternal() {
|
|
||||||
return new RationalNumber(value.negate());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected NumberInterface intPowInternal(int exponent) {
|
|
||||||
return new RationalNumber(value.pow(exponent));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(NumberInterface number) {
|
|
||||||
return value.compareTo(((RationalNumber)number).value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int signum() {
|
|
||||||
return value.getNumerator().signum();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected NumberInterface ceilingInternal() {
|
|
||||||
if(value.getNumeratorAsInt() != 1){
|
|
||||||
return floorInternal().add(ONE);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected NumberInterface floorInternal() {
|
|
||||||
BigInteger floor = value.bigDecimalValue().toBigInteger();
|
|
||||||
if(value.compareTo(BigFraction.ZERO) < 0 && value.getDenominatorAsInt() != 1){
|
|
||||||
floor = floor.subtract(BigInteger.ONE);
|
|
||||||
}
|
|
||||||
return new RationalNumber(new BigFraction(floor));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected NumberInterface fractionalPartInternal() {
|
|
||||||
return this.subtractInternal(floorInternal());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int intValue() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected NumberInterface promoteToInternal(Class<? extends NumberInterface> toClass) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NumberInterface getMaxError() {
|
|
||||||
return toPreciseNumber().getMaxError();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString(){
|
|
||||||
return toPreciseNumber().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
PreciseNumber toPreciseNumber(){
|
|
||||||
return (PreciseNumber) new PreciseNumber(value.getNumerator()).divideInternal(new PreciseNumber(value.getDenominator()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package org.nwapw.abacus.plugin;
|
package org.nwapw.abacus.plugin;
|
||||||
|
|
||||||
|
import org.nwapw.abacus.function.Documentation;
|
||||||
|
import org.nwapw.abacus.function.DocumentationType;
|
||||||
import org.nwapw.abacus.function.Function;
|
import org.nwapw.abacus.function.Function;
|
||||||
import org.nwapw.abacus.function.Operator;
|
import org.nwapw.abacus.function.Operator;
|
||||||
import org.nwapw.abacus.number.NumberInterface;
|
import org.nwapw.abacus.number.NumberInterface;
|
||||||
@@ -94,6 +96,15 @@ public abstract class Plugin {
|
|||||||
manager.registerNumberImplementation(name, implementation);
|
manager.registerNumberImplementation(name, implementation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To be used in load(). Registers a documentation instance
|
||||||
|
* used to explain some element of the plugin to the user.
|
||||||
|
* @param documentation the documentation instance.
|
||||||
|
*/
|
||||||
|
protected final void registerDocumentation(Documentation documentation){
|
||||||
|
manager.registerDocumentation(documentation);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches the PluginManager for the given function name.
|
* Searches the PluginManager for the given function name.
|
||||||
* This can be used by the plugins internally in order to call functions
|
* This can be used by the plugins internally in order to call functions
|
||||||
@@ -130,6 +141,17 @@ public abstract class Plugin {
|
|||||||
return manager.numberImplementationFor(name);
|
return manager.numberImplementationFor(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches the PluginManager for the given documentation name and type.
|
||||||
|
*
|
||||||
|
* @param name the name for which to search.
|
||||||
|
* @param type the type of documentation to search for.
|
||||||
|
* @return the found documentation, or null if none was found.
|
||||||
|
*/
|
||||||
|
protected final Documentation documentationFor(String name, DocumentationType type){
|
||||||
|
return manager.documentationFor(name, type);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches the plugin manager for a Pi value for the given number implementation.
|
* Searches the plugin manager for a Pi value for the given number implementation.
|
||||||
* This is done so that number implementations with various degrees of precision
|
* This is done so that number implementations with various degrees of precision
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package org.nwapw.abacus.plugin;
|
package org.nwapw.abacus.plugin;
|
||||||
|
|
||||||
import org.nwapw.abacus.Abacus;
|
import org.nwapw.abacus.Abacus;
|
||||||
|
import org.nwapw.abacus.function.Documentation;
|
||||||
|
import org.nwapw.abacus.function.DocumentationType;
|
||||||
import org.nwapw.abacus.function.Function;
|
import org.nwapw.abacus.function.Function;
|
||||||
import org.nwapw.abacus.function.Operator;
|
import org.nwapw.abacus.function.Operator;
|
||||||
import org.nwapw.abacus.number.NumberInterface;
|
import org.nwapw.abacus.number.NumberInterface;
|
||||||
@@ -34,6 +36,10 @@ public class PluginManager {
|
|||||||
* The map of number implementations registered by the plugins.
|
* The map of number implementations registered by the plugins.
|
||||||
*/
|
*/
|
||||||
private Map<String, NumberImplementation> registeredNumberImplementations;
|
private Map<String, NumberImplementation> registeredNumberImplementations;
|
||||||
|
/**
|
||||||
|
* The map of documentation for functions registered by the plugins.
|
||||||
|
*/
|
||||||
|
private Set<Documentation> registeredDocumentation;
|
||||||
/**
|
/**
|
||||||
* The list of number implementations that have been
|
* The list of number implementations that have been
|
||||||
* found by their implementation class.
|
* found by their implementation class.
|
||||||
@@ -65,6 +71,7 @@ public class PluginManager {
|
|||||||
registeredFunctions = new HashMap<>();
|
registeredFunctions = new HashMap<>();
|
||||||
registeredOperators = new HashMap<>();
|
registeredOperators = new HashMap<>();
|
||||||
registeredNumberImplementations = new HashMap<>();
|
registeredNumberImplementations = new HashMap<>();
|
||||||
|
registeredDocumentation = new HashSet<>();
|
||||||
cachedInterfaceImplementations = new HashMap<>();
|
cachedInterfaceImplementations = new HashMap<>();
|
||||||
cachedPi = new HashMap<>();
|
cachedPi = new HashMap<>();
|
||||||
listeners = new HashSet<>();
|
listeners = new HashSet<>();
|
||||||
@@ -97,6 +104,15 @@ public class PluginManager {
|
|||||||
registeredNumberImplementations.put(name, implementation);
|
registeredNumberImplementations.put(name, implementation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the given documentation with the plugin manager,
|
||||||
|
* making it accessible to the plugin manager etc.
|
||||||
|
* @param documentation the documentation to register.
|
||||||
|
*/
|
||||||
|
public void registerDocumentation(Documentation documentation){
|
||||||
|
registeredDocumentation.add(documentation);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the function registered under the given name.
|
* Gets the function registered under the given name.
|
||||||
* @param name the name of the function.
|
* @param name the name of the function.
|
||||||
@@ -124,6 +140,27 @@ public class PluginManager {
|
|||||||
return registeredNumberImplementations.get(name);
|
return registeredNumberImplementations.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the documentation for the given entity of the given type.
|
||||||
|
* @param name the name of the entity to search for.
|
||||||
|
* @param type the type that this entity is, to filter out similarly named documentation.
|
||||||
|
* @return the documentation object.
|
||||||
|
*/
|
||||||
|
public Documentation documentationFor(String name, DocumentationType type){
|
||||||
|
Documentation toReturn = null;
|
||||||
|
for(Documentation entry : registeredDocumentation){
|
||||||
|
if(entry.getCodeName().equals(name) && entry.getType() == type) {
|
||||||
|
toReturn = entry;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(toReturn == null){
|
||||||
|
toReturn = new Documentation(name, "", "", "", type);
|
||||||
|
registerDocumentation(toReturn);
|
||||||
|
}
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the number implementation for the given implementation class.
|
* Gets the number implementation for the given implementation class.
|
||||||
*
|
*
|
||||||
@@ -212,6 +249,7 @@ public class PluginManager {
|
|||||||
registeredFunctions.clear();
|
registeredFunctions.clear();
|
||||||
registeredOperators.clear();
|
registeredOperators.clear();
|
||||||
registeredNumberImplementations.clear();
|
registeredNumberImplementations.clear();
|
||||||
|
registeredDocumentation.clear();
|
||||||
cachedInterfaceImplementations.clear();
|
cachedInterfaceImplementations.clear();
|
||||||
cachedPi.clear();
|
cachedPi.clear();
|
||||||
listeners.forEach(e -> e.onUnload(this));
|
listeners.forEach(e -> e.onUnload(this));
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
package org.nwapw.abacus.plugin;
|
package org.nwapw.abacus.plugin;
|
||||||
|
|
||||||
import org.nwapw.abacus.function.Function;
|
import org.nwapw.abacus.function.*;
|
||||||
import org.nwapw.abacus.function.Operator;
|
import org.nwapw.abacus.lexing.pattern.Match;
|
||||||
import org.nwapw.abacus.function.OperatorAssociativity;
|
|
||||||
import org.nwapw.abacus.function.OperatorType;
|
|
||||||
import org.nwapw.abacus.number.NaiveNumber;
|
import org.nwapw.abacus.number.NaiveNumber;
|
||||||
import org.nwapw.abacus.number.NumberInterface;
|
import org.nwapw.abacus.number.NumberInterface;
|
||||||
import org.nwapw.abacus.number.PreciseNumber;
|
import org.nwapw.abacus.number.PreciseNumber;
|
||||||
|
import org.nwapw.abacus.parsing.Parser;
|
||||||
|
import org.nwapw.abacus.parsing.ShuntingYardParser;
|
||||||
|
import org.nwapw.abacus.tree.TokenType;
|
||||||
|
import org.nwapw.abacus.tree.TreeNode;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -188,7 +191,7 @@ public class StandardPlugin extends Plugin {
|
|||||||
*/
|
*/
|
||||||
private NumberInterface getLogPartialSum(NumberInterface x) {
|
private NumberInterface getLogPartialSum(NumberInterface x) {
|
||||||
|
|
||||||
NumberInterface maxError = x.getMaxError();
|
NumberInterface maxError = getMaxError(x);
|
||||||
x = x.subtract(NaiveNumber.ONE.promoteTo(x.getClass())); //Terms used are for log(x+1).
|
x = x.subtract(NaiveNumber.ONE.promoteTo(x.getClass())); //Terms used are for log(x+1).
|
||||||
NumberInterface currentNumerator = x, currentTerm = x, sum = x;
|
NumberInterface currentNumerator = x, currentTerm = x, sum = x;
|
||||||
int n = 1;
|
int n = 1;
|
||||||
@@ -207,7 +210,7 @@ public class StandardPlugin extends Plugin {
|
|||||||
* @return the value of log(2) with the appropriate precision.
|
* @return the value of log(2) with the appropriate precision.
|
||||||
*/
|
*/
|
||||||
private NumberInterface getLog2(NumberInterface number) {
|
private NumberInterface getLog2(NumberInterface number) {
|
||||||
NumberInterface maxError = number.getMaxError();
|
NumberInterface maxError = getMaxError(number);
|
||||||
//NumberInterface errorBound = fromInt(number.getClass(), 1);
|
//NumberInterface errorBound = fromInt(number.getClass(), 1);
|
||||||
//We'll use the series \sigma_{n >= 1) ((1/3^n + 1/4^n) * 1/n)
|
//We'll use the series \sigma_{n >= 1) ((1/3^n + 1/4^n) * 1/n)
|
||||||
//In the following, a=1/3^n, b=1/4^n, c = 1/n.
|
//In the following, a=1/3^n, b=1/4^n, c = 1/n.
|
||||||
@@ -301,11 +304,16 @@ public class StandardPlugin extends Plugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||||
NumberInterface maxError = params[0].getMaxError();
|
NumberInterface maxError = getMaxError(params[0]);
|
||||||
int n = 0;
|
int n = 0;
|
||||||
if (params[0].signum() < 0) {
|
if (params[0].signum() <= 0) {
|
||||||
NumberInterface[] negatedParams = {params[0].negate()};
|
NumberInterface currentTerm = NaiveNumber.ONE.promoteTo(params[0].getClass()), sum = currentTerm;
|
||||||
return fromInt(params[0].getClass(), 1).divide(applyInternal(negatedParams));
|
while (FUNCTION_ABS.apply(currentTerm).compareTo(maxError) > 0) {
|
||||||
|
n++;
|
||||||
|
currentTerm = currentTerm.multiply(params[0]).divide((new NaiveNumber(n)).promoteTo(params[0].getClass()));
|
||||||
|
sum = sum.add(currentTerm);
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
} else {
|
} else {
|
||||||
//We need n such that x^(n+1) * 3^ceil(x) <= maxError * (n+1)!.
|
//We need n such that x^(n+1) * 3^ceil(x) <= maxError * (n+1)!.
|
||||||
//right and left refer to lhs and rhs in the above inequality.
|
//right and left refer to lhs and rhs in the above inequality.
|
||||||
@@ -347,7 +355,7 @@ public class StandardPlugin extends Plugin {
|
|||||||
return NaiveNumber.ONE.promoteTo(params[1].getClass());
|
return NaiveNumber.ONE.promoteTo(params[1].getClass());
|
||||||
//Detect integer bases:
|
//Detect integer bases:
|
||||||
if(params[0].fractionalPart().compareTo(fromInt(params[0].getClass(), 0)) == 0
|
if(params[0].fractionalPart().compareTo(fromInt(params[0].getClass(), 0)) == 0
|
||||||
&& FUNCTION_ABS.apply(params[1]).compareTo(fromInt(params[0].getClass(), Integer.MAX_VALUE)) < 0
|
&& FUNCTION_ABS.apply(params[0]).compareTo(fromInt(params[0].getClass(), Integer.MAX_VALUE)) < 0
|
||||||
&& FUNCTION_ABS.apply(params[1]).compareTo(fromInt(params[1].getClass(), 1)) >= 0){
|
&& FUNCTION_ABS.apply(params[1]).compareTo(fromInt(params[1].getClass(), 1)) >= 0){
|
||||||
NumberInterface[] newParams = {params[0], params[1].fractionalPart()};
|
NumberInterface[] newParams = {params[0], params[1].fractionalPart()};
|
||||||
return params[0].intPow(params[1].floor().intValue()).multiply(applyInternal(newParams));
|
return params[0].intPow(params[1].floor().intValue()).multiply(applyInternal(newParams));
|
||||||
@@ -471,6 +479,16 @@ public class StandardPlugin extends Plugin {
|
|||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the maximum error based on the precision of the class of number.
|
||||||
|
*
|
||||||
|
* @param number Any instance of the NumberInterface in question (should return an appropriate precision).
|
||||||
|
* @return the maximum error.
|
||||||
|
*/
|
||||||
|
private static NumberInterface getMaxError(NumberInterface number) {
|
||||||
|
return fromInt(number.getClass(), 10).intPow(-number.getMaxPrecision());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A factorial function that uses memoization for each number class; it efficiently
|
* A factorial function that uses memoization for each number class; it efficiently
|
||||||
* computes factorials of non-negative integers.
|
* computes factorials of non-negative integers.
|
||||||
@@ -502,7 +520,7 @@ public class StandardPlugin extends Plugin {
|
|||||||
*/
|
*/
|
||||||
private static NumberInterface sinTaylor(NumberInterface x) {
|
private static NumberInterface sinTaylor(NumberInterface x) {
|
||||||
NumberInterface power = x, multiplier = x.multiply(x).negate(), currentTerm = x, sum = x;
|
NumberInterface power = x, multiplier = x.multiply(x).negate(), currentTerm = x, sum = x;
|
||||||
NumberInterface maxError = x.getMaxError();
|
NumberInterface maxError = getMaxError(x);
|
||||||
int n = 1;
|
int n = 1;
|
||||||
do {
|
do {
|
||||||
n += 2;
|
n += 2;
|
||||||
@@ -568,6 +586,35 @@ public class StandardPlugin extends Plugin {
|
|||||||
registerFunction("sec", functionSec);
|
registerFunction("sec", functionSec);
|
||||||
registerFunction("csc", functionCsc);
|
registerFunction("csc", functionCsc);
|
||||||
registerFunction("cot", functionCot);
|
registerFunction("cot", functionCot);
|
||||||
|
|
||||||
|
registerDocumentation(new Documentation("abs", "Absolute Value", "Finds the distance " +
|
||||||
|
"from zero of a number.", "Given a number, this function finds the distance form " +
|
||||||
|
"zero of a number, effectively turning negative numbers into positive ones.\n\n" +
|
||||||
|
"Example: abs(-2) -> 2", DocumentationType.FUNCTION));
|
||||||
|
registerDocumentation(new Documentation("exp", "Exponentiate", "Brings e to the given power.",
|
||||||
|
"This function evaluates e to the power of the given value, and is the inverse " +
|
||||||
|
"of the natural logarithm.\n\n" +
|
||||||
|
"Example: exp(1) -> 2.718...", DocumentationType.FUNCTION));
|
||||||
|
registerDocumentation(new Documentation("ln", "Natural Logarithm", "Gets the natural " +
|
||||||
|
"logarithm of the given value.", "The natural logarithm of a number is " +
|
||||||
|
"the power that e has to be brought to to be equal to the number.\n\n" +
|
||||||
|
"Example: ln(2.718) -> 1", DocumentationType.FUNCTION));
|
||||||
|
registerDocumentation(new Documentation("sqrt", "Square Root", "Finds the square root " +
|
||||||
|
"of the number.", "A square root a of a number is defined such that a times a is equal " +
|
||||||
|
"to that number.\n\n" +
|
||||||
|
"Example: sqrt(4) -> 2", DocumentationType.FUNCTION));
|
||||||
|
registerDocumentation(new Documentation("sin", "Sine", "Computes the sine of the given angle, " +
|
||||||
|
"in radians.", "", DocumentationType.FUNCTION));
|
||||||
|
registerDocumentation(new Documentation("cos", "Cosine", "Computes the cosine of the given angle, " +
|
||||||
|
"in radians.", "", DocumentationType.FUNCTION));
|
||||||
|
registerDocumentation(new Documentation("tan", "Tangent", "Computes the tangent of the given angle, " +
|
||||||
|
"in radians.", "", DocumentationType.FUNCTION));
|
||||||
|
registerDocumentation(new Documentation("sec", "Secant", "Computes the secant of the given angle, " +
|
||||||
|
"in radians.", "", DocumentationType.FUNCTION));
|
||||||
|
registerDocumentation(new Documentation("csc", "Cosecant", "Computes the cosecant of the given angle, " +
|
||||||
|
"in radians.", "", DocumentationType.FUNCTION));
|
||||||
|
registerDocumentation(new Documentation("cot", "Cotangent", "Computes the cotangent of the given angle, " +
|
||||||
|
"in radians.", "", DocumentationType.FUNCTION));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
26
src/main/kotlin/org/nwapw/abacus/function/Documentation.kt
Normal file
26
src/main/kotlin/org/nwapw/abacus/function/Documentation.kt
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package org.nwapw.abacus.function
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A data class used for storing information about a function.
|
||||||
|
*
|
||||||
|
* The Documentation class holds the information necessary to display the information
|
||||||
|
* about a function to the user.
|
||||||
|
*
|
||||||
|
* @param codeName the name of the function as it occurs in code.
|
||||||
|
* @param name the name of the function in English.
|
||||||
|
* @param description the short description of this function.
|
||||||
|
* @param longDescription the full description of this function.
|
||||||
|
* @param type the things this documentation maps to.
|
||||||
|
*/
|
||||||
|
data class Documentation(val codeName: String, val name: String,
|
||||||
|
val description: String, val longDescription: String,
|
||||||
|
val type: DocumentationType) {
|
||||||
|
|
||||||
|
fun matches(other: String): Boolean {
|
||||||
|
return codeName.toLowerCase().contains(other.toLowerCase()) ||
|
||||||
|
name.toLowerCase().contains(other.toLowerCase()) ||
|
||||||
|
description.toLowerCase().contains(other.toLowerCase()) ||
|
||||||
|
longDescription.toLowerCase().contains(other.toLowerCase())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
package org.nwapw.abacus.fx
|
|
||||||
|
|
||||||
import javafx.beans.property.SimpleStringProperty
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A model representing an input / output in the calculator.
|
|
||||||
*
|
|
||||||
* The HistoryModel class stores a record of a single user-provided input,
|
|
||||||
* its parsed form as it was interpreted by the calculator, and the output
|
|
||||||
* that was provided by the calculator. These are represented as properties
|
|
||||||
* to allow easy access by JavaFX cells.
|
|
||||||
*
|
|
||||||
* @param input the user input
|
|
||||||
* @param parsed the parsed version of the input.
|
|
||||||
* @param output the output string.
|
|
||||||
*/
|
|
||||||
class HistoryModel(input: String, parsed: String, output: String){
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The property that holds the input.
|
|
||||||
*/
|
|
||||||
val inputProperty = SimpleStringProperty(input)
|
|
||||||
/**
|
|
||||||
* The property that holds the parsed input.
|
|
||||||
*/
|
|
||||||
val parsedProperty = SimpleStringProperty(parsed)
|
|
||||||
/**
|
|
||||||
* The property that holds the output.
|
|
||||||
*/
|
|
||||||
val outputProperty = SimpleStringProperty(output)
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
package org.nwapw.abacus.fx
|
|
||||||
|
|
||||||
import javafx.beans.property.SimpleBooleanProperty
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A model representing a plugin that can be disabled or enabled.
|
|
||||||
*
|
|
||||||
* ToggleablePlugin is a model that is used to present to the user the option
|
|
||||||
* of disabling / enabling plugins. The class name in this plugin is stored if
|
|
||||||
* its "enabledPropery" is false, essentially blacklisting the plugin.
|
|
||||||
*
|
|
||||||
* @param className the name of the class that this model concerns.
|
|
||||||
* @param enabled whether or not the model should start enabled.
|
|
||||||
*/
|
|
||||||
class ToggleablePlugin (val className: String, enabled: Boolean) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The property used to interact with JavaFX components.
|
|
||||||
*/
|
|
||||||
val enabledProperty = SimpleBooleanProperty(enabled)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether this plugin is currently enabled or not.
|
|
||||||
*
|
|
||||||
* @return true if it is enabled, false otherwise.
|
|
||||||
*/
|
|
||||||
fun isEnabled(): Boolean {
|
|
||||||
return enabledProperty.value
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
7
src/test/java/org/nwapw/abacus/tests/CalculationTests.java
Executable file → Normal file
7
src/test/java/org/nwapw/abacus/tests/CalculationTests.java
Executable file → Normal file
@@ -88,8 +88,8 @@ public class CalculationTests {
|
|||||||
public void testExp(){
|
public void testExp(){
|
||||||
testOutput("exp0", "exp(0)", "1");
|
testOutput("exp0", "exp(0)", "1");
|
||||||
testOutput("exp1", "exp(1)", "2.718281828459045235360287471352662497757247");
|
testOutput("exp1", "exp(1)", "2.718281828459045235360287471352662497757247");
|
||||||
testOutput("exp300", "exp(300)", "1.9424263952412559365842088360176992193662086");
|
testOutput("exp300", "exp(300)", "19424263952412559365842088360176992193662086");
|
||||||
testOutput("exp(-500)", "exp((500)`)", "7.1245764067412855315491573771227552469277568");
|
testOutput("exp300", "exp(300)", "19424263952412559365842088360176992193662086");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -99,9 +99,6 @@ public class CalculationTests {
|
|||||||
testOutput("2^1", "(2^1)", "2");
|
testOutput("2^1", "(2^1)", "2");
|
||||||
testOutput("2^-1", "(2^(1)`)", "0.5");
|
testOutput("2^-1", "(2^(1)`)", "0.5");
|
||||||
testOutput("2^50", "(2^50)", "112589990684262");
|
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)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user