package function.builtin; import java.text.MessageFormat; import error.LispException; import function.*; import sexpression.*; import table.FunctionTable; @FunctionNames({ "SYMBOL-FUNCTION" }) public class SYMBOL_FUNCTION extends LispFunction { private ArgumentValidator argumentValidator; public SYMBOL_FUNCTION() { this.argumentValidator = new ArgumentValidator("SYMBOL-FUNCTION"); this.argumentValidator.setExactNumberOfArguments(1); this.argumentValidator.setEveryArgumentExpectedType(Symbol.class); } public SExpression call(Cons argumentList) { argumentValidator.validate(argumentList); SExpression symbol = argumentList.getFirst(); LispFunction function = FunctionTable.lookupFunction(symbol.toString()); if (function != null) return createRepresentation(symbol, function); throw new UndefinedSymbolFunctionException(symbol); } private SExpression createRepresentation(SExpression symbol, LispFunction function) { if (function instanceof UserDefinedFunction) return ((UserDefinedFunction) function).getLambdaExpression(); String typeIndicator = function instanceof LispSpecialFunction ? "SPECIAL-FUNCTION" : "FUNCTION"; return new Symbol(MessageFormat.format("#<{0} {1}>", typeIndicator, symbol)); } public static class UndefinedSymbolFunctionException extends LispException { private static final long serialVersionUID = 1L; private SExpression function; public UndefinedSymbolFunctionException(SExpression function) { this.function = function; } @Override public String getMessage() { return MessageFormat.format("SYMBOL-FUNCTION: undefined function: {0}", function); } } }