1
0
mirror of https://github.com/DanilaFe/abacus synced 2026-01-26 00:25:20 +00:00

Compare commits

..

2 Commits

Author SHA1 Message Date
d964fbfb6f Implement the negation operator. 2017-08-02 11:26:59 -07:00
9713f24ed2 Rename nodes to more general names. 2017-08-02 10:41:52 -07:00
10 changed files with 47 additions and 87 deletions

View File

@@ -9,7 +9,7 @@ import org.nwapw.abacus.parsing.ShuntingYardParser;
import org.nwapw.abacus.parsing.TreeBuilder;
import org.nwapw.abacus.plugin.ClassFinder;
import org.nwapw.abacus.plugin.PluginManager;
//import org.nwapw.abacus.plugin.StandardPlugin;
import org.nwapw.abacus.plugin.StandardPlugin;
import org.nwapw.abacus.tree.NumberReducer;
import org.nwapw.abacus.tree.TreeNode;
@@ -67,22 +67,16 @@ public class Abacus {
pluginManager.addListener(lexerTokenizer);
pluginManager.addListener(shuntingYardParser);
//pluginManager.addInstantiated(new StandardPlugin(pluginManager));
/*
pluginManager.addInstantiated(new StandardPlugin(pluginManager));
try {
ClassFinder.loadJars("plugins")
.forEach(plugin -> pluginManager.addClass(plugin));
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}//*/
}
pluginManager.load();
}
public void loadClass(Class<?> newClass){
pluginManager.addClass(newClass);
}
public void unloadClass(Class<?> newClass){
pluginManager.removeClass(newClass);
}
public static void main(String[] args) {
AbacusApplication.launch(AbacusApplication.class, args);
}

View File

@@ -4,5 +4,5 @@ package org.nwapw.abacus.function;
* The type of an operator, describing how it should behave.
*/
public enum OperatorType {
BINARY_INFIX, UNARY_POSTFIX
BINARY_INFIX, UNARY_POSTFIX, UNARY_PREFIX
}

View File

@@ -8,11 +8,8 @@ import javafx.scene.text.Text;
import javafx.util.Callback;
import org.nwapw.abacus.Abacus;
import org.nwapw.abacus.number.NumberInterface;
import org.nwapw.abacus.plugin.ClassFinder;
import org.nwapw.abacus.tree.TreeNode;
import java.io.IOException;
/**
* The controller for the abacus FX UI, responsible
@@ -45,12 +42,6 @@ public class AbacusController {
private Button inputButton;
@FXML
private ComboBox<String> numberImplementationBox;
@FXML
private Button loadButton;
@FXML
private Button unloadButton;
@FXML
private TextField loadField;
/**
* The list of history entries, created by the users.
@@ -115,38 +106,5 @@ public class AbacusController {
inputButton.setDisable(false);
inputField.setText("");
}
@FXML
private void loadClass(){
try {
for(Class<?> plugin :ClassFinder.loadJars("plugins")){
String name = "";
//String name = plugin.getName();
while(!(name.indexOf('/') ==-1)){
name=name.substring(name.indexOf('/')+1);
}
if(loadField.getText().equals("")||loadField.getText().equals(name)||(loadField.getText()+".class").equals(name)){
//abacus.loadClass(plugin);
}
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
@FXML
private void unloadClass(){
try {
for(Class<?> plugin :ClassFinder.loadJars("plugins")){
String name = plugin.getName();
while(!(name.indexOf('/') ==-1)){
name=name.substring(name.indexOf('/')+1);
}
if(loadField.getText().equals("")||loadField.getText().equals(name)||(loadField.getText()+".class").equals(name)){
//abacus.unloadClass(plugin);
}
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}

View File

@@ -55,9 +55,12 @@ public class ShuntingYardParser implements Parser<Match<TokenType>>, PluginListe
public List<Match<TokenType>> intoPostfix(List<Match<TokenType>> from) {
ArrayList<Match<TokenType>> output = new ArrayList<>();
Stack<Match<TokenType>> tokenStack = new Stack<>();
TokenType previousType;
TokenType matchType = null;
while (!from.isEmpty()) {
Match<TokenType> match = from.remove(0);
TokenType matchType = match.getType();
previousType = matchType;
matchType = match.getType();
if (matchType == TokenType.NUM) {
output.add(match);
} else if (matchType == TokenType.FUNCTION) {
@@ -74,7 +77,13 @@ public class ShuntingYardParser implements Parser<Match<TokenType>>, PluginListe
continue;
}
while (!tokenStack.empty()) {
if(tokenString.equals("-") && (previousType == null || previousType == TokenType.OP ||
previousType == TokenType.OPEN_PARENTH)){
from.add(0, new Match<>("`", TokenType.OP));
continue;
}
while (!tokenStack.empty() && type == OperatorType.BINARY_INFIX) {
Match<TokenType> otherMatch = tokenStack.peek();
TokenType otherMatchType = otherMatch.getType();
if (!(otherMatchType == TokenType.OP || otherMatchType == TokenType.FUNCTION)) break;
@@ -103,8 +112,8 @@ public class ShuntingYardParser implements Parser<Match<TokenType>>, PluginListe
}
while (!tokenStack.empty()) {
Match<TokenType> match = tokenStack.peek();
TokenType matchType = match.getType();
if (!(matchType == TokenType.OP || matchType == TokenType.FUNCTION)) return null;
TokenType newMatchType = match.getType();
if (!(newMatchType == TokenType.OP || newMatchType == TokenType.FUNCTION)) return null;
output.add(tokenStack.pop());
}
return output;
@@ -127,11 +136,11 @@ public class ShuntingYardParser implements Parser<Match<TokenType>>, PluginListe
TreeNode right = constructRecursive(matches);
TreeNode left = constructRecursive(matches);
if (left == null || right == null) return null;
else return new BinaryInfixNode(operator, left, right);
else return new BinaryNode(operator, left, right);
} else {
TreeNode applyTo = constructRecursive(matches);
if (applyTo == null) return null;
else return new UnaryPrefixNode(operator, applyTo);
else return new UnaryNode(operator, applyTo);
}
} else if (matchType == TokenType.NUM) {
return new NumberNode(abacus.numberFromString(match.getContent()));

View File

@@ -140,11 +140,6 @@ public class PluginManager {
plugins.add(plugin);
loadedPluginClasses.add(plugin.getClass());
}
public void removeInstantiated(Plugin plugin){
if (loadedPluginClasses.contains(plugin.getClass())) return;
plugins.remove(plugin);
loadedPluginClasses.remove(plugin.getClass());
}
/**
* Instantiates a class of plugin, and adds it to this
@@ -160,14 +155,6 @@ public class PluginManager {
e.printStackTrace();
}
}
public void removeClass(Class<?> newClass){
if (!Plugin.class.isAssignableFrom(newClass) || newClass == Plugin.class) return;
try {
removeInstantiated((Plugin) newClass.getConstructor(PluginManager.class).newInstance(this));
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
e.printStackTrace();
}
}
/**
* Loads all the plugins in the PluginManager.

View File

@@ -52,6 +52,20 @@ public class StandardPlugin extends Plugin {
return params[0].subtract(params[1]);
}
});
/**
* The negation operator, -
*/
public static final Operator OP_NEGATE = new Operator(OperatorAssociativity.LEFT, OperatorType.UNARY_PREFIX, 0, new Function() {
@Override
protected boolean matchesParams(NumberInterface[] params) {
return params.length == 1;
}
@Override
protected NumberInterface applyInternal(NumberInterface[] params) {
return params[0].negate();
}
});
/**
* The multiplication operator, *
*/
@@ -317,6 +331,7 @@ public class StandardPlugin extends Plugin {
registerOperator("+", OP_ADD);
registerOperator("-", OP_SUBTRACT);
registerOperator("`", OP_NEGATE);
registerOperator("*", OP_MULTIPLY);
registerOperator("/", OP_DIVIDE);
registerOperator("^", OP_CARET);
@@ -335,7 +350,7 @@ public class StandardPlugin extends Plugin {
public static NumberInterface factorial(Class<? extends NumberInterface> numberClass, int n){
if(!factorialLists.containsKey(numberClass)){
factorialLists.put(numberClass, new ArrayList<NumberInterface>());
factorialLists.put(numberClass, new ArrayList<>());
factorialLists.get(numberClass).add(NaiveNumber.ONE.promoteTo(numberClass));
factorialLists.get(numberClass).add(NaiveNumber.ONE.promoteTo(numberClass));
}

View File

@@ -3,7 +3,7 @@ package org.nwapw.abacus.tree;
/**
* A tree node that represents an operation being applied to two operands.
*/
public class BinaryInfixNode extends TreeNode {
public class BinaryNode extends TreeNode {
/**
* The operation being applied.
@@ -18,7 +18,7 @@ public class BinaryInfixNode extends TreeNode {
*/
private TreeNode right;
private BinaryInfixNode() {
private BinaryNode() {
}
/**
@@ -27,7 +27,7 @@ public class BinaryInfixNode extends TreeNode {
*
* @param operation the operation.
*/
public BinaryInfixNode(String operation) {
public BinaryNode(String operation) {
this(operation, null, null);
}
@@ -39,7 +39,7 @@ public class BinaryInfixNode extends TreeNode {
* @param left the left node of the expression.
* @param right the right node of the expression.
*/
public BinaryInfixNode(String operation, TreeNode left, TreeNode right) {
public BinaryNode(String operation, TreeNode left, TreeNode right) {
this.operation = operation;
this.left = left;
this.right = right;

View File

@@ -28,15 +28,15 @@ public class NumberReducer implements Reducer<NumberInterface> {
public NumberInterface reduceNode(TreeNode node, Object... children) {
if (node instanceof NumberNode) {
return ((NumberNode) node).getNumber();
} else if (node instanceof BinaryInfixNode) {
} else if (node instanceof BinaryNode) {
NumberInterface left = (NumberInterface) children[0];
NumberInterface right = (NumberInterface) children[1];
Function function = abacus.getPluginManager().operatorFor(((BinaryInfixNode) node).getOperation()).getFunction();
Function function = abacus.getPluginManager().operatorFor(((BinaryNode) node).getOperation()).getFunction();
if (function == null) return null;
return function.apply(left, right);
} else if (node instanceof UnaryPrefixNode) {
} else if (node instanceof UnaryNode) {
NumberInterface child = (NumberInterface) children[0];
Function functionn = abacus.getPluginManager().operatorFor(((UnaryPrefixNode) node).getOperation()).getFunction();
Function functionn = abacus.getPluginManager().operatorFor(((UnaryNode) node).getOperation()).getFunction();
if (functionn == null) return null;
return functionn.apply(child);
} else if (node instanceof FunctionNode) {

View File

@@ -1,6 +1,6 @@
package org.nwapw.abacus.tree;
public class UnaryPrefixNode extends TreeNode {
public class UnaryNode extends TreeNode {
/**
* The operation this node will apply.
@@ -16,7 +16,7 @@ public class UnaryPrefixNode extends TreeNode {
*
* @param operation the operation for this node.
*/
public UnaryPrefixNode(String operation) {
public UnaryNode(String operation) {
this(operation, null);
}
@@ -26,7 +26,7 @@ public class UnaryPrefixNode extends TreeNode {
* @param operation the operation for this node.
* @param applyTo the node to apply the function to.
*/
public UnaryPrefixNode(String operation, TreeNode applyTo) {
public UnaryNode(String operation, TreeNode applyTo) {
this.operation = operation;
this.applyTo = applyTo;
}

View File

@@ -46,9 +46,6 @@
<padding><Insets left="10" right="10" top="10" bottom="10"/></padding>
<Label text="Number Implementation" GridPane.columnIndex="0" GridPane.rowIndex="0"/>
<ComboBox fx:id="numberImplementationBox" GridPane.columnIndex="1" GridPane.rowIndex="0"/>
<Button fx:id="loadButton" text="Load" GridPane.rowIndex="1" GridPane.columnIndex="0" maxWidth = "Infinity" onAction="#loadClass"/>
<Button fx:id="unloadButton" text="Unload" GridPane.rowIndex="1" GridPane.columnIndex="1" maxWidth = "Infinity" onAction="#unloadClass"/>
<TextField fx:id="loadField" GridPane.rowIndex="1" GridPane.columnIndex="2"/>
</GridPane>
</Tab>
</TabPane>