201 lines
6.6 KiB
Java
201 lines
6.6 KiB
Java
package table;
|
|
|
|
import error.CriticalLispException;
|
|
import function.FunctionNames;
|
|
import function.LispFunction;
|
|
import function.builtin.APPLY;
|
|
import function.builtin.EVAL;
|
|
import function.builtin.EXIT;
|
|
import function.builtin.FUNCALL;
|
|
import function.builtin.FUSE;
|
|
import function.builtin.GENSYM;
|
|
import function.builtin.LOAD;
|
|
import function.builtin.PRINT;
|
|
import function.builtin.SET;
|
|
import function.builtin.SYMBOLS;
|
|
import function.builtin.SYMBOL_FUNCTION;
|
|
import function.builtin.cons.APPEND;
|
|
import function.builtin.cons.CONS;
|
|
import function.builtin.cons.FIRST;
|
|
import function.builtin.cons.LENGTH;
|
|
import function.builtin.cons.LIST;
|
|
import function.builtin.cons.REST;
|
|
import function.builtin.math.DIVIDE;
|
|
import function.builtin.math.MINUS;
|
|
import function.builtin.math.MODULO;
|
|
import function.builtin.math.MULTIPLY;
|
|
import function.builtin.math.PLUS;
|
|
import function.builtin.math.REMAINDER;
|
|
import function.builtin.predicate.ATOM;
|
|
import function.builtin.predicate.EQ;
|
|
import function.builtin.predicate.EQUAL;
|
|
import function.builtin.predicate.GENSYM_EQUAL;
|
|
import function.builtin.predicate.LISTP;
|
|
import function.builtin.predicate.NULL;
|
|
import function.builtin.predicate.NUMERIC_EQUAL;
|
|
import function.builtin.predicate.NUMERIC_GREATER;
|
|
import function.builtin.predicate.NUMERIC_LESS;
|
|
import function.builtin.special.AND;
|
|
import function.builtin.special.CASE;
|
|
import function.builtin.special.COND;
|
|
import function.builtin.special.DEFINE_SPECIAL;
|
|
import function.builtin.special.DEFMACRO;
|
|
import function.builtin.special.DEFUN;
|
|
import function.builtin.special.IF;
|
|
import function.builtin.special.LAMBDA;
|
|
import function.builtin.special.LET;
|
|
import function.builtin.special.LET_STAR;
|
|
import function.builtin.special.OR;
|
|
import function.builtin.special.PROGN;
|
|
import function.builtin.special.QUOTE;
|
|
import function.builtin.special.RECUR;
|
|
import function.builtin.special.SETQ;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
import static java.text.MessageFormat.format;
|
|
|
|
public class FunctionTable {
|
|
|
|
private static Set<Class<? extends LispFunction>> allBuiltIns = new HashSet<>();
|
|
|
|
static {
|
|
allBuiltIns.add(AND.class);
|
|
allBuiltIns.add(APPEND.class);
|
|
allBuiltIns.add(APPLY.class);
|
|
allBuiltIns.add(ATOM.class);
|
|
allBuiltIns.add(CASE.class);
|
|
allBuiltIns.add(COND.class);
|
|
allBuiltIns.add(CONS.class);
|
|
allBuiltIns.add(DEFINE_SPECIAL.class);
|
|
allBuiltIns.add(DEFMACRO.class);
|
|
allBuiltIns.add(DEFUN.class);
|
|
allBuiltIns.add(DIVIDE.class);
|
|
allBuiltIns.add(EQ.class);
|
|
allBuiltIns.add(EQUAL.class);
|
|
allBuiltIns.add(NUMERIC_EQUAL.class);
|
|
allBuiltIns.add(EVAL.class);
|
|
allBuiltIns.add(EXIT.class);
|
|
allBuiltIns.add(FIRST.class);
|
|
allBuiltIns.add(FUNCALL.class);
|
|
allBuiltIns.add(FUSE.class);
|
|
allBuiltIns.add(GENSYM.class);
|
|
allBuiltIns.add(GENSYM_EQUAL.class);
|
|
allBuiltIns.add(NUMERIC_GREATER.class);
|
|
allBuiltIns.add(IF.class);
|
|
allBuiltIns.add(LAMBDA.class);
|
|
allBuiltIns.add(LENGTH.class);
|
|
allBuiltIns.add(NUMERIC_LESS.class);
|
|
allBuiltIns.add(LET.class);
|
|
allBuiltIns.add(LET_STAR.class);
|
|
allBuiltIns.add(LIST.class);
|
|
allBuiltIns.add(LISTP.class);
|
|
allBuiltIns.add(LOAD.class);
|
|
allBuiltIns.add(MINUS.class);
|
|
allBuiltIns.add(MODULO.class);
|
|
allBuiltIns.add(MULTIPLY.class);
|
|
allBuiltIns.add(NULL.class);
|
|
allBuiltIns.add(OR.class);
|
|
allBuiltIns.add(PLUS.class);
|
|
allBuiltIns.add(PRINT.class);
|
|
allBuiltIns.add(PROGN.class);
|
|
allBuiltIns.add(QUOTE.class);
|
|
allBuiltIns.add(RECUR.class);
|
|
allBuiltIns.add(REMAINDER.class);
|
|
allBuiltIns.add(REST.class);
|
|
allBuiltIns.add(SET.class);
|
|
allBuiltIns.add(SETQ.class);
|
|
allBuiltIns.add(SYMBOL_FUNCTION.class);
|
|
allBuiltIns.add(SYMBOLS.class);
|
|
}
|
|
|
|
public static LispFunction lookupFunction(String functionName) {
|
|
return getTable().get(functionName);
|
|
}
|
|
|
|
public static boolean isAlreadyDefined(String functionName) {
|
|
return getTable().containsKey(functionName);
|
|
}
|
|
|
|
public static void defineFunction(String functionName, LispFunction function) {
|
|
getTable().put(functionName, function);
|
|
}
|
|
|
|
public static void resetFunctionTable() {
|
|
getUniqueInstance().initializeFunctionTable(allBuiltIns);
|
|
}
|
|
|
|
static void resetFunctionTable(Set<Class<? extends LispFunction>> builtIns) {
|
|
getUniqueInstance().initializeFunctionTable(builtIns);
|
|
}
|
|
|
|
private static FunctionTable uniqueInstance;
|
|
|
|
private static FunctionTable getUniqueInstance() {
|
|
if (uniqueInstance == null) {
|
|
uniqueInstance = new FunctionTable();
|
|
}
|
|
|
|
return uniqueInstance;
|
|
}
|
|
|
|
private static Map<String, LispFunction> getTable() {
|
|
return getUniqueInstance().table;
|
|
}
|
|
|
|
private Map<String, LispFunction> table;
|
|
|
|
private FunctionTable() {
|
|
initializeFunctionTable(allBuiltIns);
|
|
}
|
|
|
|
private void initializeFunctionTable(Set<Class<? extends LispFunction>> builtIns) {
|
|
table = new HashMap<>();
|
|
|
|
for (Class<? extends LispFunction> function : builtIns)
|
|
addBuiltInFunctionToTable(function);
|
|
}
|
|
|
|
private void addBuiltInFunctionToTable(Class<? extends LispFunction> function) {
|
|
FunctionNames functionNames = function.getAnnotation(FunctionNames.class);
|
|
|
|
if (functionNames != null)
|
|
addAllFunctionNamesToTable(function, functionNames.value());
|
|
}
|
|
|
|
private void addAllFunctionNamesToTable(Class<? extends LispFunction> function, String[] names) {
|
|
for (String name : names)
|
|
table.put(name, createInstance(function, name));
|
|
}
|
|
|
|
private LispFunction createInstance(Class<? extends LispFunction> function, String name) {
|
|
LispFunction instance = null;
|
|
|
|
try {
|
|
instance = function.getConstructor(String.class).newInstance(name);
|
|
} catch (Exception e) {
|
|
throw new LispFunctionInstantiationException(function.getName());
|
|
}
|
|
|
|
return instance;
|
|
}
|
|
|
|
public static class LispFunctionInstantiationException extends CriticalLispException {
|
|
|
|
private static final long serialVersionUID = 1L;
|
|
private String functionName;
|
|
|
|
public LispFunctionInstantiationException(String functionName) {
|
|
this.functionName = functionName;
|
|
}
|
|
|
|
@Override
|
|
public String getMessage() {
|
|
return format("Could not create an instance of ''{0}''", functionName);
|
|
}
|
|
}
|
|
}
|