Refactored the function table logic

This commit is contained in:
Mike Cifelli 2017-01-29 14:33:46 -05:00
parent 5351168763
commit d3fc8f9812
5 changed files with 34 additions and 35 deletions

View File

@ -1,24 +1,18 @@
package function.builtin; package function.builtin;
import static function.FunctionTable.functionTable;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.HashMap;
import error.LispException; import error.LispException;
import function.*; import function.*;
import function.builtin.cons.LIST; import function.builtin.cons.LIST;
import function.builtin.special.*; import function.builtin.special.*;
import sexpression.*; import sexpression.*;
import table.FunctionTable;
public class EVAL extends LispFunction { public class EVAL extends LispFunction {
public static HashMap<String, LispFunction> getFunctionTable() {
return functionTable;
}
public static LispFunction lookupFunctionOrLambda(SExpression functionExpression) { public static LispFunction lookupFunctionOrLambda(SExpression functionExpression) {
LispFunction function = lookupFunction(functionExpression.toString()); LispFunction function = FunctionTable.lookupFunction(functionExpression.toString());
if (function == null) if (function == null)
function = createLambdaFunction(functionExpression); function = createLambdaFunction(functionExpression);
@ -26,10 +20,6 @@ public class EVAL extends LispFunction {
return function; return function;
} }
public static LispFunction lookupFunction(String functionName) {
return functionTable.get(functionName);
}
private static LispFunction createLambdaFunction(SExpression lambdaExpression) { private static LispFunction createLambdaFunction(SExpression lambdaExpression) {
if (lambdaExpression.functionp()) if (lambdaExpression.functionp())
return ((LambdaExpression) lambdaExpression).getFunction(); return ((LambdaExpression) lambdaExpression).getFunction();
@ -40,13 +30,12 @@ public class EVAL extends LispFunction {
} }
public static SExpression lookupSymbol(String symbolName) { public static SExpression lookupSymbol(String symbolName) {
if (symbolName.equals("NIL")) { if (symbolName.equals("NIL"))
return Nil.getInstance(); return Nil.getInstance();
} else if (symbolName.equals("T")) { else if (symbolName.equals("T"))
return Symbol.T; return Symbol.T;
} else if (symbolName.startsWith(":")) { else if (symbolName.startsWith(":"))
return new Symbol(symbolName); return new Symbol(symbolName);
}
return SETF.lookupSymbolValue(symbolName); return SETF.lookupSymbolValue(symbolName);
} }

View File

@ -5,6 +5,7 @@ import java.text.MessageFormat;
import error.LispException; import error.LispException;
import function.*; import function.*;
import sexpression.*; import sexpression.*;
import table.FunctionTable;
public class SYMBOL_FUNCTION extends LispFunction { public class SYMBOL_FUNCTION extends LispFunction {
@ -20,7 +21,7 @@ public class SYMBOL_FUNCTION extends LispFunction {
argumentValidator.validate(argumentList); argumentValidator.validate(argumentList);
SExpression symbol = argumentList.getCar(); SExpression symbol = argumentList.getCar();
LispFunction function = EVAL.lookupFunction(symbol.toString()); LispFunction function = FunctionTable.lookupFunction(symbol.toString());
if (function != null) { if (function != null) {
if (function instanceof UserDefinedFunction) if (function instanceof UserDefinedFunction)

View File

@ -1,13 +1,12 @@
package function.builtin.special; package function.builtin.special;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.HashMap;
import environment.Environment; import environment.Environment;
import function.*; import function.*;
import function.builtin.EVAL;
import function.builtin.cons.LIST; import function.builtin.cons.LIST;
import sexpression.*; import sexpression.*;
import table.FunctionTable;
public class DEFUN extends LispFunction { public class DEFUN extends LispFunction {
@ -43,20 +42,15 @@ public class DEFUN extends LispFunction {
Cons functionBody = (Cons) remainingArguments.getCdr(); Cons functionBody = (Cons) remainingArguments.getCdr();
UserDefinedFunction function = new UserDefinedFunction(functionName.toString(), lambdaList, functionBody); UserDefinedFunction function = new UserDefinedFunction(functionName.toString(), lambdaList, functionBody);
HashMap<String, LispFunction> functionTable = EVAL.getFunctionTable();
if (isAlreadyDefined(functionName, functionTable)) if (FunctionTable.isAlreadyDefined(functionName.toString()))
printWarning(functionName); printWarning(functionName);
functionTable.put(functionName.toString(), function); FunctionTable.defineFunction(functionName.toString(), function);
return functionName; return functionName;
} }
private boolean isAlreadyDefined(SExpression functionName, HashMap<String, LispFunction> functionTable) {
return functionTable.containsKey(functionName.toString());
}
private void printWarning(SExpression functionName) { private void printWarning(SExpression functionName) {
String message = MessageFormat.format("WARNING: redefining function {0}", functionName.toString()); String message = MessageFormat.format("WARNING: redefining function {0}", functionName.toString());
environment.getOutput().println(message); environment.getOutput().println(message);

View File

@ -1,7 +1,8 @@
package function; package table;
import java.util.HashMap; import java.util.HashMap;
import function.LispFunction;
import function.builtin.*; import function.builtin.*;
import function.builtin.cons.*; import function.builtin.cons.*;
import function.builtin.math.*; import function.builtin.math.*;
@ -10,9 +11,29 @@ import function.builtin.special.*;
public class FunctionTable { public class FunctionTable {
public static final HashMap<String, LispFunction> functionTable = new HashMap<String, LispFunction>(); private static FunctionTable uniqueInstance = new FunctionTable();
static { public static LispFunction lookupFunction(String functionName) {
return uniqueInstance.functionTable.get(functionName);
}
public static boolean isAlreadyDefined(String functionName) {
return uniqueInstance.functionTable.containsKey(functionName);
}
public static void defineFunction(String functionName, LispFunction function) {
uniqueInstance.functionTable.put(functionName, function);
}
private HashMap<String, LispFunction> functionTable;
private FunctionTable() {
this.functionTable = new HashMap<>();
initializeFunctionTable();
}
private void initializeFunctionTable() {
functionTable.put("*", new MULTIPLY()); functionTable.put("*", new MULTIPLY());
functionTable.put("+", new PLUS()); functionTable.put("+", new PLUS());
functionTable.put("-", new MINUS()); functionTable.put("-", new MINUS());

View File

@ -9,16 +9,10 @@ public class SymbolTable {
private HashMap<String, SExpression> table; private HashMap<String, SExpression> table;
private SymbolTable parent; private SymbolTable parent;
/**
* Create a new symbol table with no parent.
*/
public SymbolTable() { public SymbolTable() {
this(null); this(null);
} }
/**
* Create a new symbol table with the specified parent.
*/
public SymbolTable(SymbolTable parent) { public SymbolTable(SymbolTable parent) {
this.table = new HashMap<String, SExpression>(); this.table = new HashMap<String, SExpression>();
this.parent = parent; this.parent = parent;