Add Applicable to Operator, therby removing the need for Functions in it

This commit is contained in:
Danila Fedorin 2017-08-25 14:55:05 -07:00
parent 1f0addccea
commit d04adf4da5
7 changed files with 80 additions and 43 deletions

View File

@ -1,6 +1,7 @@
package org.nwapw.abacus.plugin;
import org.nwapw.abacus.function.*;
import org.nwapw.abacus.number.NaiveNumber;
import org.nwapw.abacus.number.NumberInterface;
/**
@ -85,7 +86,7 @@ public abstract class Plugin {
* @param name the name of the operator.
* @param operator the operator to register.
*/
protected final void registerOperator(String name, Operator operator) {
protected final void registerOperator(String name, NumberOperator operator) {
manager.registerOperator(name, operator);
}
@ -142,7 +143,7 @@ public abstract class Plugin {
* @param name the name for which to search
* @return the resulting operator, or null if none was found for that name.
*/
protected final Operator operatorFor(String name) {
protected final NumberOperator operatorFor(String name) {
return manager.operatorFor(name);
}

View File

@ -35,7 +35,7 @@ public class PluginManager {
/**
* The map of operators registered by the plugins
*/
private Map<String, Operator> registeredOperators;
private Map<String, NumberOperator> registeredOperators;
/**
* The map of number implementations registered by the plugins.
*/
@ -108,7 +108,7 @@ public class PluginManager {
* @param name the name of the operator.
* @param operator the operator to register.
*/
public void registerOperator(String name, Operator operator) {
public void registerOperator(String name, NumberOperator operator) {
registeredOperators.put(name, operator);
}
@ -158,7 +158,7 @@ public class PluginManager {
* @param name the name of the operator.
* @return the operator, or null if it was not found.
*/
public Operator operatorFor(String name) {
public NumberOperator operatorFor(String name) {
return registeredOperators.get(name);
}

View File

@ -4,6 +4,9 @@ import org.nwapw.abacus.function.*;
import org.nwapw.abacus.number.NaiveNumber;
import org.nwapw.abacus.number.NumberInterface;
import org.nwapw.abacus.number.PreciseNumber;
import org.nwapw.abacus.tree.BinaryNode;
import org.nwapw.abacus.tree.Reducer;
import org.nwapw.abacus.tree.TreeNode;
import java.util.ArrayList;
import java.util.HashMap;
@ -18,7 +21,7 @@ public class StandardPlugin extends Plugin {
/**
* The addition operator, +
*/
public static final Operator OP_ADD = new Operator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX, 0, new Function() {
public static final NumberOperator OP_ADD = new NumberOperator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX, 0) {
@Override
protected boolean matchesParams(NumberInterface[] params) {
return params.length >= 1;
@ -32,11 +35,11 @@ public class StandardPlugin extends Plugin {
}
return sum;
}
});
};
/**
* The subtraction operator, -
*/
public static final Operator OP_SUBTRACT = new Operator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX, 0, new Function() {
public static final NumberOperator OP_SUBTRACT = new NumberOperator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX, 0) {
@Override
protected boolean matchesParams(NumberInterface[] params) {
return params.length == 2;
@ -47,11 +50,11 @@ 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() {
public static final NumberOperator OP_NEGATE = new NumberOperator(OperatorAssociativity.LEFT, OperatorType.UNARY_PREFIX, 0) {
@Override
protected boolean matchesParams(NumberInterface[] params) {
return params.length == 1;
@ -61,11 +64,11 @@ public class StandardPlugin extends Plugin {
protected NumberInterface applyInternal(NumberInterface[] params) {
return params[0].negate();
}
});
};
/**
* The multiplication operator, *
*/
public static final Operator OP_MULTIPLY = new Operator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX, 1, new Function() {
public static final NumberOperator OP_MULTIPLY = new NumberOperator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX, 1) {
@Override
protected boolean matchesParams(NumberInterface[] params) {
return params.length >= 1;
@ -79,11 +82,11 @@ public class StandardPlugin extends Plugin {
}
return product;
}
});
};
/**
* The combination operator.
*/
public static final Operator OP_NCR = new Operator(OperatorAssociativity.RIGHT, OperatorType.BINARY_INFIX, 0, new Function() {
public static final NumberOperator OP_NCR = new NumberOperator(OperatorAssociativity.RIGHT, OperatorType.BINARY_INFIX, 0) {
@Override
protected boolean matchesParams(NumberInterface[] params) {
return params.length == 2 && params[0].fractionalPart().signum() == 0
@ -92,9 +95,9 @@ public class StandardPlugin extends Plugin {
@Override
protected NumberInterface applyInternal(NumberInterface[] params) {
return OP_NPR.getFunction().apply(params).divide(OP_FACTORIAL.getFunction().apply(params[1]));
return OP_NPR.apply(params).divide(OP_FACTORIAL.apply(params[1]));
}
});
};
/**
* The implementation for double-based naive numbers.
*/
@ -152,7 +155,7 @@ public class StandardPlugin extends Plugin {
/**
* The division operator, /
*/
public static final Operator OP_DIVIDE = new Operator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX, 1, new Function() {
public static final NumberOperator OP_DIVIDE = new NumberOperator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX, 1) {
@Override
protected boolean matchesParams(NumberInterface[] params) {
return params.length == 2 && params[1].compareTo(fromInt(params[0].getClass(), 0)) != 0;
@ -162,11 +165,11 @@ public class StandardPlugin extends Plugin {
protected NumberInterface applyInternal(NumberInterface[] params) {
return params[0].divide(params[1]);
}
});
};
/**
* The factorial operator, !
*/
public static final Operator OP_FACTORIAL = new Operator(OperatorAssociativity.RIGHT, OperatorType.UNARY_POSTFIX, 0, new Function() {
public static final NumberOperator OP_FACTORIAL = new NumberOperator(OperatorAssociativity.RIGHT, OperatorType.UNARY_POSTFIX, 0) {
//private HashMap<Class<? extends NumberInterface>, ArrayList<NumberInterface>> storedList = new HashMap<Class<? extends NumberInterface>, ArrayList<NumberInterface>>();
@Override
protected boolean matchesParams(NumberInterface[] params) {
@ -194,11 +197,11 @@ public class StandardPlugin extends Plugin {
storedList.get(params[0].getClass()).add(NaiveNumber.ONE.promoteTo(params[0].getClass()));
}*/
}
});
};
/**
* The permutation operator.
*/
public static final Operator OP_NPR = new Operator(OperatorAssociativity.RIGHT, OperatorType.BINARY_INFIX, 0, new Function() {
public static final NumberOperator OP_NPR = new NumberOperator(OperatorAssociativity.RIGHT, OperatorType.BINARY_INFIX, 0) {
@Override
protected boolean matchesParams(NumberInterface[] params) {
return params.length == 2 && params[0].fractionalPart().signum() == 0
@ -224,7 +227,7 @@ public class StandardPlugin extends Plugin {
}
return total;
}
});
};
/**
* The absolute value function, abs(-3) = 3
*/
@ -336,7 +339,7 @@ public class StandardPlugin extends Plugin {
/**
* The caret / pow operator, ^
*/
public static final Operator OP_CARET = new Operator(OperatorAssociativity.RIGHT, OperatorType.BINARY_INFIX, 2, new Function() {
public static final NumberOperator OP_CARET = new NumberOperator(OperatorAssociativity.RIGHT, OperatorType.BINARY_INFIX, 2) {
@Override
protected boolean matchesParams(NumberInterface[] params) {
NumberInterface zero = fromInt(params[0].getClass(), 0);
@ -362,7 +365,7 @@ public class StandardPlugin extends Plugin {
}
return FUNCTION_EXP.apply(FUNCTION_LN.apply(FUNCTION_ABS.apply(params[0])).multiply(params[1]));
}
});
};
/**
* The square root function.
*/
@ -374,7 +377,7 @@ public class StandardPlugin extends Plugin {
@Override
protected NumberInterface applyInternal(NumberInterface[] params) {
return OP_CARET.getFunction().apply(params[0], ((new NaiveNumber(0.5)).promoteTo(params[0].getClass())));
return OP_CARET.apply(params[0], ((new NaiveNumber(0.5)).promoteTo(params[0].getClass())));
}
};
private static final HashMap<Class<? extends NumberInterface>, ArrayList<NumberInterface>> FACTORIAL_LISTS = new HashMap<>();

View File

@ -2,8 +2,10 @@ package org.nwapw.abacus.tree;
import org.nwapw.abacus.Abacus;
import org.nwapw.abacus.function.Function;
import org.nwapw.abacus.function.Operator;
import org.nwapw.abacus.function.TreeValueFunction;
import org.nwapw.abacus.number.NumberInterface;
import org.nwapw.abacus.plugin.NumberImplementation;
/**
* A reducer implementation that turns a tree into a single number.
@ -34,14 +36,12 @@ public class NumberReducer implements Reducer<NumberInterface> {
} else if (node instanceof BinaryNode) {
NumberInterface left = (NumberInterface) children[0];
NumberInterface right = (NumberInterface) children[1];
Function function = abacus.getPluginManager().operatorFor(((BinaryNode) node).getOperation()).getFunction();
if (function == null) return null;
return function.apply(left, right);
Operator<NumberInterface, NumberInterface> operator = abacus.getPluginManager().operatorFor(((BinaryNode) node).getOperation());
return operator.apply(left, right);
} else if (node instanceof UnaryNode) {
NumberInterface child = (NumberInterface) children[0];
Function functionn = abacus.getPluginManager().operatorFor(((UnaryNode) node).getOperation()).getFunction();
if (functionn == null) return null;
return functionn.apply(child);
Operator<NumberInterface, NumberInterface> operator = abacus.getPluginManager().operatorFor(((UnaryNode) node).getOperation());
return operator.apply(child);
} else if (node instanceof FunctionNode) {
NumberInterface[] convertedChildren = new NumberInterface[children.length];
for (int i = 0; i < convertedChildren.length; i++) {

View File

@ -0,0 +1,15 @@
package org.nwapw.abacus.function
import org.nwapw.abacus.number.NumberInterface
/**
* An operator that operates on NumberImplementations.
*
* This is simply an alias for Operator<NumberInterface, NumberInterface>.
* @param associativity the associativity of the operator.
* @param type the type of the operator (binary, unary, etc)
* @param precedence the precedence of the operator.
*/
abstract class NumberOperator(associativity: OperatorAssociativity, type: OperatorType,
precedence: Int) :
Operator<NumberInterface, NumberInterface>(associativity, type, precedence)

View File

@ -3,12 +3,11 @@ package org.nwapw.abacus.function
/**
* A single operator that can be used by Abacus.
*
* This is a data class that holds the information about a single operator, such as a plus or minus.
* This is a class that holds the information about a single operator, such as a plus or minus.
*
* @param associativity the associativity of this operator, used for order of operations;.
* @param type the type of this operator, used for parsing (infix / prefix / postfix and binary / unary)
* @param precedence the precedence of this operator, used for order of operations.
* @param function the function this operator applies to its arguments.
*/
data class Operator(val associativity: OperatorAssociativity, val type: OperatorType,
val precedence: Int, val function: Function)
abstract class Operator<T: Any, O: Any>(val associativity: OperatorAssociativity, val type: OperatorType,
val precedence: Int) : Applicable<T, O>()

View File

@ -5,10 +5,7 @@ import org.junit.BeforeClass;
import org.junit.Test;
import org.nwapw.abacus.Abacus;
import org.nwapw.abacus.config.Configuration;
import org.nwapw.abacus.function.Function;
import org.nwapw.abacus.function.Operator;
import org.nwapw.abacus.function.OperatorAssociativity;
import org.nwapw.abacus.function.OperatorType;
import org.nwapw.abacus.function.*;
import org.nwapw.abacus.lexing.pattern.Match;
import org.nwapw.abacus.number.NumberInterface;
import org.nwapw.abacus.parsing.LexerTokenizer;
@ -35,10 +32,32 @@ public class TokenizerTests {
private static Plugin testPlugin = new Plugin(abacus.getPluginManager()) {
@Override
public void onEnable() {
registerOperator("+", new Operator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX,
0, subtractFunction));
registerOperator("-", new Operator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX,
0, subtractFunction));
registerOperator("+", new NumberOperator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX,
0) {
@Override
protected boolean matchesParams(NumberInterface[] params) {
return true;
}
@Override
protected NumberInterface applyInternal(NumberInterface[] params) {
return subtractFunction.apply(params);
}
});
registerOperator("-", new NumberOperator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX,
0) {
@Override
protected boolean matchesParams(NumberInterface[] params) {
return true;
}
@Override
protected NumberInterface applyInternal(NumberInterface[] params) {
return subtractFunction.apply(params);
}
});
registerFunction("subtract", subtractFunction);
}