mirror of
https://github.com/DanilaFe/abacus
synced 2024-12-23 07:50:09 -08:00
Implement unary operators.
This commit is contained in:
parent
082b2f8783
commit
51f2c15542
|
@ -30,6 +30,7 @@ public class Operator {
|
||||||
*/
|
*/
|
||||||
public Operator(OperatorAssociativity associativity, OperatorType operatorType, int precedence, Function function){
|
public Operator(OperatorAssociativity associativity, OperatorType operatorType, int precedence, Function function){
|
||||||
this.associativity = associativity;
|
this.associativity = associativity;
|
||||||
|
this.type = operatorType;
|
||||||
this.precedence = precedence;
|
this.precedence = precedence;
|
||||||
this.function = function;
|
this.function = function;
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ public class StandardPlugin extends Plugin {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
registerFunction("!", new Function() {
|
registerOperator("!", new Operator(OperatorAssociativity.RIGHT, OperatorType.UNARY_POSTFIX, 0, new Function() {
|
||||||
//private HashMap<Class<? extends NumberInterface>, ArrayList<NumberInterface>> storedList = new HashMap<Class<? extends NumberInterface>, ArrayList<NumberInterface>>();
|
//private HashMap<Class<? extends NumberInterface>, ArrayList<NumberInterface>> storedList = new HashMap<Class<? extends NumberInterface>, ArrayList<NumberInterface>>();
|
||||||
@Override
|
@Override
|
||||||
protected boolean matchesParams(NumberInterface[] params) {
|
protected boolean matchesParams(NumberInterface[] params) {
|
||||||
|
@ -114,7 +114,7 @@ public class StandardPlugin extends Plugin {
|
||||||
storedList.get(params[0].getClass()).add(NaiveNumber.ONE.promoteTo(params[0].getClass()));
|
storedList.get(params[0].getClass()).add(NaiveNumber.ONE.promoteTo(params[0].getClass()));
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
|
|
||||||
registerFunction("abs", new Function() {
|
registerFunction("abs", new Function() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -33,6 +33,11 @@ public class NumberReducer implements Reducer<NumberInterface> {
|
||||||
Function function = manager.operatorFor(((OpNode) node).getOperation()).getFunction();
|
Function function = manager.operatorFor(((OpNode) node).getOperation()).getFunction();
|
||||||
if(function == null) return null;
|
if(function == null) return null;
|
||||||
return function.apply(left, right);
|
return function.apply(left, right);
|
||||||
|
} else if(node instanceof UnaryPrefixNode) {
|
||||||
|
NumberInterface child = (NumberInterface) children[0];
|
||||||
|
Function functionn = manager.operatorFor(((UnaryPrefixNode) node).getOperation()).getFunction();
|
||||||
|
if(functionn == null) return null;
|
||||||
|
return functionn.apply(child);
|
||||||
} else if(node instanceof FunctionNode){
|
} else if(node instanceof FunctionNode){
|
||||||
NumberInterface[] convertedChildren = new NumberInterface[children.length];
|
NumberInterface[] convertedChildren = new NumberInterface[children.length];
|
||||||
for(int i = 0; i < convertedChildren.length; i++){
|
for(int i = 0; i < convertedChildren.length; i++){
|
||||||
|
|
|
@ -101,9 +101,15 @@ public class TreeBuilder {
|
||||||
tokenStack.push(match);
|
tokenStack.push(match);
|
||||||
} else if(matchType == TokenType.OP){
|
} else if(matchType == TokenType.OP){
|
||||||
String tokenString = source.substring(match.getFrom(), match.getTo());
|
String tokenString = source.substring(match.getFrom(), match.getTo());
|
||||||
|
OperatorType type = typeMap.get(tokenString);
|
||||||
int precedence = precedenceMap.get(tokenString);
|
int precedence = precedenceMap.get(tokenString);
|
||||||
OperatorAssociativity associativity = associativityMap.get(tokenString);
|
OperatorAssociativity associativity = associativityMap.get(tokenString);
|
||||||
|
|
||||||
|
if(type == OperatorType.UNARY_POSTFIX){
|
||||||
|
output.add(match);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
while(!tokenStack.empty()) {
|
while(!tokenStack.empty()) {
|
||||||
Match<TokenType> otherMatch = tokenStack.peek();
|
Match<TokenType> otherMatch = tokenStack.peek();
|
||||||
TokenType otherMatchType = otherMatch.getType();
|
TokenType otherMatchType = otherMatch.getType();
|
||||||
|
@ -151,10 +157,18 @@ public class TreeBuilder {
|
||||||
Match<TokenType> match = matches.remove(0);
|
Match<TokenType> match = matches.remove(0);
|
||||||
TokenType matchType = match.getType();
|
TokenType matchType = match.getType();
|
||||||
if(matchType == TokenType.OP){
|
if(matchType == TokenType.OP){
|
||||||
TreeNode right = fromStringRecursive(source, matches);
|
String operator = source.substring(match.getFrom(), match.getTo());
|
||||||
TreeNode left = fromStringRecursive(source, matches);
|
OperatorType type = typeMap.get(operator);
|
||||||
if(left == null || right == null) return null;
|
if(type == OperatorType.BINARY_INFIX){
|
||||||
else return new OpNode(source.substring(match.getFrom(), match.getTo()), left, right);
|
TreeNode right = fromStringRecursive(source, matches);
|
||||||
|
TreeNode left = fromStringRecursive(source, matches);
|
||||||
|
if(left == null || right == null) return null;
|
||||||
|
else return new OpNode(operator, left, right);
|
||||||
|
} else {
|
||||||
|
TreeNode applyTo = fromStringRecursive(source, matches);
|
||||||
|
if(applyTo == null) return null;
|
||||||
|
else return new UnaryPrefixNode(operator, applyTo);
|
||||||
|
}
|
||||||
} else if(matchType == TokenType.NUM){
|
} else if(matchType == TokenType.NUM){
|
||||||
return new NumberNode(Double.parseDouble(source.substring(match.getFrom(), match.getTo())));
|
return new NumberNode(Double.parseDouble(source.substring(match.getFrom(), match.getTo())));
|
||||||
} else if(matchType == TokenType.FUNCTION){
|
} else if(matchType == TokenType.FUNCTION){
|
||||||
|
|
54
src/org/nwapw/abacus/tree/UnaryPrefixNode.java
Normal file
54
src/org/nwapw/abacus/tree/UnaryPrefixNode.java
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package org.nwapw.abacus.tree;
|
||||||
|
|
||||||
|
public class UnaryPrefixNode extends TreeNode {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The operation this node will apply.
|
||||||
|
*/
|
||||||
|
private String operation;
|
||||||
|
/**
|
||||||
|
* The tree node to apply the operation to.
|
||||||
|
*/
|
||||||
|
private TreeNode applyTo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new node with the given operation and no child.
|
||||||
|
* @param operation the operation for this node.
|
||||||
|
*/
|
||||||
|
public UnaryPrefixNode(String operation){
|
||||||
|
this(operation, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new node with the given operation and child.
|
||||||
|
* @param operation the operation for this node.
|
||||||
|
* @param applyTo the node to apply the function to.
|
||||||
|
*/
|
||||||
|
public UnaryPrefixNode(String operation, TreeNode applyTo){
|
||||||
|
this.operation = operation;
|
||||||
|
this.applyTo = applyTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T reduce(Reducer<T> reducer) {
|
||||||
|
Object reducedChild = applyTo.reduce(reducer);
|
||||||
|
if(reducedChild == null) return null;
|
||||||
|
return reducer.reduceNode(this, reducedChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the operation of this node.
|
||||||
|
* @return the operation this node performs.
|
||||||
|
*/
|
||||||
|
public String getOperation() {
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the node to which this node's operation applies.
|
||||||
|
* @return the tree node to which the operation will be applied.
|
||||||
|
*/
|
||||||
|
public TreeNode getApplyTo() {
|
||||||
|
return applyTo;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user