Refactored the function table logic
This commit is contained in:
parent
5351168763
commit
d3fc8f9812
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.*;
|
||||||
|
@ -9,10 +10,30 @@ import function.builtin.predicate.*;
|
||||||
import function.builtin.special.*;
|
import function.builtin.special.*;
|
||||||
|
|
||||||
public class FunctionTable {
|
public class FunctionTable {
|
||||||
|
|
||||||
|
private static FunctionTable uniqueInstance = new FunctionTable();
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
public static final HashMap<String, LispFunction> functionTable = new HashMap<String, LispFunction>();
|
private FunctionTable() {
|
||||||
|
this.functionTable = new HashMap<>();
|
||||||
|
|
||||||
|
initializeFunctionTable();
|
||||||
|
}
|
||||||
|
|
||||||
static {
|
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());
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue