1
0
mirror of https://github.com/DanilaFe/abacus synced 2024-12-23 07:50:09 -08:00

Implement unary operators.

This commit is contained in:
Danila Fedorin 2017-07-28 11:14:45 -07:00
parent 082b2f8783
commit 51f2c15542
5 changed files with 80 additions and 6 deletions

View File

@ -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;
} }

View File

@ -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

View File

@ -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++){

View File

@ -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){

View 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;
}
}