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; package org.nwapw.abacus.plugin;
import org.nwapw.abacus.function.*; import org.nwapw.abacus.function.*;
import org.nwapw.abacus.number.NaiveNumber;
import org.nwapw.abacus.number.NumberInterface; import org.nwapw.abacus.number.NumberInterface;
/** /**
@ -85,7 +86,7 @@ public abstract class Plugin {
* @param name the name of the operator. * @param name the name of the operator.
* @param operator the operator to register. * @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); manager.registerOperator(name, operator);
} }
@ -142,7 +143,7 @@ public abstract class Plugin {
* @param name the name for which to search * @param name the name for which to search
* @return the resulting operator, or null if none was found for that name. * @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); return manager.operatorFor(name);
} }

View File

@ -35,7 +35,7 @@ public class PluginManager {
/** /**
* The map of operators registered by the plugins * 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. * The map of number implementations registered by the plugins.
*/ */
@ -108,7 +108,7 @@ public class PluginManager {
* @param name the name of the operator. * @param name the name of the operator.
* @param operator the operator to register. * @param operator the operator to register.
*/ */
public void registerOperator(String name, Operator operator) { public void registerOperator(String name, NumberOperator operator) {
registeredOperators.put(name, operator); registeredOperators.put(name, operator);
} }
@ -158,7 +158,7 @@ public class PluginManager {
* @param name the name of the operator. * @param name the name of the operator.
* @return the operator, or null if it was not found. * @return the operator, or null if it was not found.
*/ */
public Operator operatorFor(String name) { public NumberOperator operatorFor(String name) {
return registeredOperators.get(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.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.tree.BinaryNode;
import org.nwapw.abacus.tree.Reducer;
import org.nwapw.abacus.tree.TreeNode;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -18,7 +21,7 @@ public class StandardPlugin extends Plugin {
/** /**
* The addition operator, + * 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 @Override
protected boolean matchesParams(NumberInterface[] params) { protected boolean matchesParams(NumberInterface[] params) {
return params.length >= 1; return params.length >= 1;
@ -32,11 +35,11 @@ public class StandardPlugin extends Plugin {
} }
return sum; return sum;
} }
}); };
/** /**
* The subtraction operator, - * 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 @Override
protected boolean matchesParams(NumberInterface[] params) { protected boolean matchesParams(NumberInterface[] params) {
return params.length == 2; return params.length == 2;
@ -47,11 +50,11 @@ public class StandardPlugin extends Plugin {
return params[0].subtract(params[1]); return params[0].subtract(params[1]);
} }
}); };
/** /**
* The negation operator, - * 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 @Override
protected boolean matchesParams(NumberInterface[] params) { protected boolean matchesParams(NumberInterface[] params) {
return params.length == 1; return params.length == 1;
@ -61,11 +64,11 @@ public class StandardPlugin extends Plugin {
protected NumberInterface applyInternal(NumberInterface[] params) { protected NumberInterface applyInternal(NumberInterface[] params) {
return params[0].negate(); return params[0].negate();
} }
}); };
/** /**
* The multiplication operator, * * 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 @Override
protected boolean matchesParams(NumberInterface[] params) { protected boolean matchesParams(NumberInterface[] params) {
return params.length >= 1; return params.length >= 1;
@ -79,11 +82,11 @@ public class StandardPlugin extends Plugin {
} }
return product; return product;
} }
}); };
/** /**
* The combination operator. * 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 @Override
protected boolean matchesParams(NumberInterface[] params) { protected boolean matchesParams(NumberInterface[] params) {
return params.length == 2 && params[0].fractionalPart().signum() == 0 return params.length == 2 && params[0].fractionalPart().signum() == 0
@ -92,9 +95,9 @@ public class StandardPlugin extends Plugin {
@Override @Override
protected NumberInterface applyInternal(NumberInterface[] params) { 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. * The implementation for double-based naive numbers.
*/ */
@ -152,7 +155,7 @@ public class StandardPlugin extends Plugin {
/** /**
* The division operator, / * 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 @Override
protected boolean matchesParams(NumberInterface[] params) { protected boolean matchesParams(NumberInterface[] params) {
return params.length == 2 && params[1].compareTo(fromInt(params[0].getClass(), 0)) != 0; 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) { protected NumberInterface applyInternal(NumberInterface[] params) {
return params[0].divide(params[1]); return params[0].divide(params[1]);
} }
}); };
/** /**
* The factorial operator, ! * 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>>(); //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) {
@ -194,11 +197,11 @@ 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()));
}*/ }*/
} }
}); };
/** /**
* The permutation operator. * 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 @Override
protected boolean matchesParams(NumberInterface[] params) { protected boolean matchesParams(NumberInterface[] params) {
return params.length == 2 && params[0].fractionalPart().signum() == 0 return params.length == 2 && params[0].fractionalPart().signum() == 0
@ -224,7 +227,7 @@ public class StandardPlugin extends Plugin {
} }
return total; return total;
} }
}); };
/** /**
* The absolute value function, abs(-3) = 3 * The absolute value function, abs(-3) = 3
*/ */
@ -336,7 +339,7 @@ public class StandardPlugin extends Plugin {
/** /**
* The caret / pow operator, ^ * 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 @Override
protected boolean matchesParams(NumberInterface[] params) { protected boolean matchesParams(NumberInterface[] params) {
NumberInterface zero = fromInt(params[0].getClass(), 0); 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])); return FUNCTION_EXP.apply(FUNCTION_LN.apply(FUNCTION_ABS.apply(params[0])).multiply(params[1]));
} }
}); };
/** /**
* The square root function. * The square root function.
*/ */
@ -374,7 +377,7 @@ public class StandardPlugin extends Plugin {
@Override @Override
protected NumberInterface applyInternal(NumberInterface[] params) { 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<>(); 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.Abacus;
import org.nwapw.abacus.function.Function; import org.nwapw.abacus.function.Function;
import org.nwapw.abacus.function.Operator;
import org.nwapw.abacus.function.TreeValueFunction; import org.nwapw.abacus.function.TreeValueFunction;
import org.nwapw.abacus.number.NumberInterface; import org.nwapw.abacus.number.NumberInterface;
import org.nwapw.abacus.plugin.NumberImplementation;
/** /**
* A reducer implementation that turns a tree into a single number. * 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) { } else if (node instanceof BinaryNode) {
NumberInterface left = (NumberInterface) children[0]; NumberInterface left = (NumberInterface) children[0];
NumberInterface right = (NumberInterface) children[1]; NumberInterface right = (NumberInterface) children[1];
Function function = abacus.getPluginManager().operatorFor(((BinaryNode) node).getOperation()).getFunction(); Operator<NumberInterface, NumberInterface> operator = abacus.getPluginManager().operatorFor(((BinaryNode) node).getOperation());
if (function == null) return null; return operator.apply(left, right);
return function.apply(left, right);
} else if (node instanceof UnaryNode) { } else if (node instanceof UnaryNode) {
NumberInterface child = (NumberInterface) children[0]; NumberInterface child = (NumberInterface) children[0];
Function functionn = abacus.getPluginManager().operatorFor(((UnaryNode) node).getOperation()).getFunction(); Operator<NumberInterface, NumberInterface> operator = abacus.getPluginManager().operatorFor(((UnaryNode) node).getOperation());
if (functionn == null) return null; return operator.apply(child);
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

@ -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. * 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 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 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 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, abstract class Operator<T: Any, O: Any>(val associativity: OperatorAssociativity, val type: OperatorType,
val precedence: Int, val function: Function) val precedence: Int) : Applicable<T, O>()

View File

@ -5,10 +5,7 @@ import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
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.Function; import org.nwapw.abacus.function.*;
import org.nwapw.abacus.function.Operator;
import org.nwapw.abacus.function.OperatorAssociativity;
import org.nwapw.abacus.function.OperatorType;
import org.nwapw.abacus.lexing.pattern.Match; import org.nwapw.abacus.lexing.pattern.Match;
import org.nwapw.abacus.number.NumberInterface; import org.nwapw.abacus.number.NumberInterface;
import org.nwapw.abacus.parsing.LexerTokenizer; import org.nwapw.abacus.parsing.LexerTokenizer;
@ -35,10 +32,32 @@ public class TokenizerTests {
private static Plugin testPlugin = new Plugin(abacus.getPluginManager()) { private static Plugin testPlugin = new Plugin(abacus.getPluginManager()) {
@Override @Override
public void onEnable() { public void onEnable() {
registerOperator("+", new Operator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX, registerOperator("+", new NumberOperator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX,
0, subtractFunction)); 0) {
registerOperator("-", new Operator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX,
0, subtractFunction)); @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); registerFunction("subtract", subtractFunction);
} }