Update argument validation and added unit tests
Fixed some bugs in LET and LAMBDA Refactored the code in UserDefinedFunction
This commit is contained in:
		
							parent
							
								
									d7ca5d09da
								
							
						
					
					
						commit
						0a5228d5a7
					
				@ -124,16 +124,16 @@ public class ArgumentValidator {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        private static final long serialVersionUID = 1L;
 | 
					        private static final long serialVersionUID = 1L;
 | 
				
			||||||
        private String functionName;
 | 
					        private String functionName;
 | 
				
			||||||
        private Cons originalSExpression;
 | 
					        private Cons argumentList;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public TooFewArgumentsException(String functionName, Cons argumentList) {
 | 
					        public TooFewArgumentsException(String functionName, Cons argumentList) {
 | 
				
			||||||
            this.functionName = functionName;
 | 
					            this.functionName = functionName;
 | 
				
			||||||
            this.originalSExpression = new Cons(new Symbol(this.functionName), argumentList);
 | 
					            this.argumentList = argumentList;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @Override
 | 
					        @Override
 | 
				
			||||||
        public String getMessage() {
 | 
					        public String getMessage() {
 | 
				
			||||||
            return MessageFormat.format("too few arguments given to {0}: {1}", functionName, originalSExpression);
 | 
					            return MessageFormat.format("too few arguments given to {0}: {1}", functionName, argumentList);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -141,16 +141,16 @@ public class ArgumentValidator {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        private static final long serialVersionUID = 1L;
 | 
					        private static final long serialVersionUID = 1L;
 | 
				
			||||||
        private String functionName;
 | 
					        private String functionName;
 | 
				
			||||||
        private Cons originalSExpression;
 | 
					        private Cons argumentList;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public TooManyArgumentsException(String functionName, Cons argumentList) {
 | 
					        public TooManyArgumentsException(String functionName, Cons argumentList) {
 | 
				
			||||||
            this.functionName = functionName;
 | 
					            this.functionName = functionName;
 | 
				
			||||||
            this.originalSExpression = new Cons(new Symbol(this.functionName), argumentList);
 | 
					            this.argumentList = argumentList;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @Override
 | 
					        @Override
 | 
				
			||||||
        public String getMessage() {
 | 
					        public String getMessage() {
 | 
				
			||||||
            return MessageFormat.format("too many arguments given to {0}: {1}", functionName, originalSExpression);
 | 
					            return MessageFormat.format("too many arguments given to {0}: {1}", functionName, argumentList);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -158,16 +158,16 @@ public class ArgumentValidator {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        private static final long serialVersionUID = 1L;
 | 
					        private static final long serialVersionUID = 1L;
 | 
				
			||||||
        private String functionName;
 | 
					        private String functionName;
 | 
				
			||||||
        private Cons originalSExpression;
 | 
					        private Cons argumentList;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public DottedArgumentListException(String functionName, Cons argumentList) {
 | 
					        public DottedArgumentListException(String functionName, Cons argumentList) {
 | 
				
			||||||
            this.functionName = functionName;
 | 
					            this.functionName = functionName;
 | 
				
			||||||
            this.originalSExpression = new Cons(new Symbol(this.functionName), argumentList);
 | 
					            this.argumentList = argumentList;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @Override
 | 
					        @Override
 | 
				
			||||||
        public String getMessage() {
 | 
					        public String getMessage() {
 | 
				
			||||||
            return MessageFormat.format("dotted argument list given to {0}: {1}", functionName, originalSExpression);
 | 
					            return MessageFormat.format("dotted argument list given to {0}: {1}", functionName, argumentList);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -12,7 +12,7 @@ public class UserDefinedFunction extends LispFunction {
 | 
				
			|||||||
    private Cons body;
 | 
					    private Cons body;
 | 
				
			||||||
    private Cons lambdaExpression;
 | 
					    private Cons lambdaExpression;
 | 
				
			||||||
    private ExecutionContext executionContext;
 | 
					    private ExecutionContext executionContext;
 | 
				
			||||||
    private SymbolTable scope;
 | 
					    private SymbolTable functionScope;
 | 
				
			||||||
    private ArrayList<String> formalParameters;
 | 
					    private ArrayList<String> formalParameters;
 | 
				
			||||||
    private ArgumentValidator argumentValidator;
 | 
					    private ArgumentValidator argumentValidator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -21,7 +21,7 @@ public class UserDefinedFunction extends LispFunction {
 | 
				
			|||||||
        this.body = body;
 | 
					        this.body = body;
 | 
				
			||||||
        this.lambdaExpression = new Cons(new Symbol(name), new Cons(lambdaList, body));
 | 
					        this.lambdaExpression = new Cons(new Symbol(name), new Cons(lambdaList, body));
 | 
				
			||||||
        this.executionContext = ExecutionContext.getInstance();
 | 
					        this.executionContext = ExecutionContext.getInstance();
 | 
				
			||||||
        this.scope = executionContext.getScope();
 | 
					        this.functionScope = executionContext.getScope();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (this.formalParameters = new ArrayList<>(); lambdaList.consp(); lambdaList = (Cons) lambdaList.getCdr())
 | 
					        for (this.formalParameters = new ArrayList<>(); lambdaList.consp(); lambdaList = (Cons) lambdaList.getCdr())
 | 
				
			||||||
            this.formalParameters.add(lambdaList.getCar().toString());
 | 
					            this.formalParameters.add(lambdaList.getCar().toString());
 | 
				
			||||||
@ -33,49 +33,33 @@ public class UserDefinedFunction extends LispFunction {
 | 
				
			|||||||
    public SExpression call(Cons argumentList) {
 | 
					    public SExpression call(Cons argumentList) {
 | 
				
			||||||
        argumentValidator.validate(argumentList);
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // bind the values of the arguments to the formal parameter names
 | 
					 | 
				
			||||||
        bindParameterValues(argumentList);
 | 
					        bindParameterValues(argumentList);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        // store the environment of the S-expression that called this function
 | 
					 | 
				
			||||||
        // (the current environment)
 | 
					 | 
				
			||||||
        SymbolTable callingScope = executionContext.getScope();
 | 
					        SymbolTable callingScope = executionContext.getScope();
 | 
				
			||||||
 | 
					        executionContext.setScope(functionScope);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // replace the current environment with the environment of this
 | 
					        SExpression lastEvaluation = null;
 | 
				
			||||||
        // function
 | 
					 | 
				
			||||||
        executionContext.setScope(scope);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Cons currentSExpression = body;
 | 
					        for (Cons expression = body; expression.consp(); expression = (Cons) expression.getCdr())
 | 
				
			||||||
        SExpression lastValue = null;
 | 
					            lastEvaluation = EVAL.eval(expression.getCar());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // evaluate all the S-expressions making up this function's body
 | 
					 | 
				
			||||||
        while (currentSExpression.consp()) {
 | 
					 | 
				
			||||||
            lastValue = EVAL.eval(currentSExpression.getCar());
 | 
					 | 
				
			||||||
            currentSExpression = (Cons) currentSExpression.getCdr();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // replace the environment of the S-expression that called this
 | 
					 | 
				
			||||||
        // function
 | 
					 | 
				
			||||||
        executionContext.setScope(callingScope);
 | 
					        executionContext.setScope(callingScope);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        // remove the bindings of the arguments to the formal parameter names
 | 
					 | 
				
			||||||
        // in the environment of this function
 | 
					 | 
				
			||||||
        releaseParameterValues();
 | 
					        releaseParameterValues();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return lastValue;
 | 
					        return lastEvaluation;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void bindParameterValues(Cons argumentList) {
 | 
					    private void bindParameterValues(Cons argumentList) {
 | 
				
			||||||
        scope = new SymbolTable(scope);
 | 
					        functionScope = new SymbolTable(functionScope);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (String parameter : formalParameters) {
 | 
					        for (String parameter : formalParameters) {
 | 
				
			||||||
            SExpression currentArg = argumentList.getCar();
 | 
					            SExpression currentArg = argumentList.getCar();
 | 
				
			||||||
            scope.put(parameter, currentArg);
 | 
					            functionScope.put(parameter, currentArg);
 | 
				
			||||||
            argumentList = (Cons) argumentList.getCdr();
 | 
					            argumentList = (Cons) argumentList.getCdr();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void releaseParameterValues() {
 | 
					    private void releaseParameterValues() {
 | 
				
			||||||
        scope = new SymbolTable(scope.getParent());
 | 
					        functionScope = new SymbolTable(functionScope.getParent());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public Cons getLambdaExpression() {
 | 
					    public Cons getLambdaExpression() {
 | 
				
			||||||
 | 
				
			|||||||
@ -20,10 +20,10 @@ public class DEFUN extends LispFunction {
 | 
				
			|||||||
        this.argumentValidator.setMinimumNumberOfArguments(3);
 | 
					        this.argumentValidator.setMinimumNumberOfArguments(3);
 | 
				
			||||||
        this.argumentValidator.setFirstArgumentExpectedType(Symbol.class);
 | 
					        this.argumentValidator.setFirstArgumentExpectedType(Symbol.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.lambdaListIsListValidator = new ArgumentValidator("DEFUN|lambda_list|");
 | 
					        this.lambdaListIsListValidator = new ArgumentValidator("DEFUN|lambda-list|");
 | 
				
			||||||
        this.lambdaListIsListValidator.setEveryArgumentExpectedType(Cons.class);
 | 
					        this.lambdaListIsListValidator.setEveryArgumentExpectedType(Cons.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.lambdaListValidator = new ArgumentValidator("DEFUN|lambda_list|");
 | 
					        this.lambdaListValidator = new ArgumentValidator("DEFUN|parameter|");
 | 
				
			||||||
        this.lambdaListValidator.setEveryArgumentExpectedType(Symbol.class);
 | 
					        this.lambdaListValidator.setEveryArgumentExpectedType(Symbol.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.environment = Environment.getInstance();
 | 
					        this.environment = Environment.getInstance();
 | 
				
			||||||
 | 
				
			|||||||
@ -19,7 +19,7 @@ public class LAMBDA extends LispFunction {
 | 
				
			|||||||
    public static UserDefinedFunction createFunction(Cons lambdaExpression) {
 | 
					    public static UserDefinedFunction createFunction(Cons lambdaExpression) {
 | 
				
			||||||
        SExpression cdr = lambdaExpression.getCdr();
 | 
					        SExpression cdr = lambdaExpression.getCdr();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ArgumentValidator lambdaValidator = new ArgumentValidator(":LAMBDA");
 | 
					        ArgumentValidator lambdaValidator = new ArgumentValidator("LAMBDA|create|");
 | 
				
			||||||
        lambdaValidator.setEveryArgumentExpectedType(Cons.class);
 | 
					        lambdaValidator.setEveryArgumentExpectedType(Cons.class);
 | 
				
			||||||
        lambdaValidator.validate(LIST.makeList(cdr));
 | 
					        lambdaValidator.validate(LIST.makeList(cdr));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -29,11 +29,15 @@ public class LAMBDA extends LispFunction {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private ArgumentValidator argumentValidator;
 | 
					    private ArgumentValidator argumentValidator;
 | 
				
			||||||
 | 
					    private ArgumentValidator lambdaListValidator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public LAMBDA() {
 | 
					    public LAMBDA() {
 | 
				
			||||||
        this.argumentValidator = new ArgumentValidator("LAMBDA");
 | 
					        this.argumentValidator = new ArgumentValidator("LAMBDA");
 | 
				
			||||||
        this.argumentValidator.setFirstArgumentExpectedType(Cons.class);
 | 
					        this.argumentValidator.setFirstArgumentExpectedType(Cons.class);
 | 
				
			||||||
        this.argumentValidator.setMinimumNumberOfArguments(2);
 | 
					        this.argumentValidator.setMinimumNumberOfArguments(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.lambdaListValidator = new ArgumentValidator("LAMBDA|lambda-list|");
 | 
				
			||||||
 | 
					        this.lambdaListValidator.setEveryArgumentExpectedType(Symbol.class);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public LambdaExpression call(Cons argumentList) {
 | 
					    public LambdaExpression call(Cons argumentList) {
 | 
				
			||||||
@ -43,6 +47,8 @@ public class LAMBDA extends LispFunction {
 | 
				
			|||||||
        Cons lambdaList = (Cons) car;
 | 
					        Cons lambdaList = (Cons) car;
 | 
				
			||||||
        Cons body = (Cons) argumentList.getCdr();
 | 
					        Cons body = (Cons) argumentList.getCdr();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        lambdaListValidator.validate(lambdaList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        UserDefinedFunction function = new UserDefinedFunction(":LAMBDA", lambdaList, body);
 | 
					        UserDefinedFunction function = new UserDefinedFunction(":LAMBDA", lambdaList, body);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return new LambdaExpression(makeOriginalLambdaExpression(argumentList), function);
 | 
					        return new LambdaExpression(makeOriginalLambdaExpression(argumentList), function);
 | 
				
			||||||
 | 
				
			|||||||
@ -8,13 +8,22 @@ import table.*;
 | 
				
			|||||||
public class LET extends LispFunction {
 | 
					public class LET extends LispFunction {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private ArgumentValidator argumentValidator;
 | 
					    private ArgumentValidator argumentValidator;
 | 
				
			||||||
 | 
					    private ArgumentValidator variableDefinitionListValidator;
 | 
				
			||||||
 | 
					    private ArgumentValidator pairValidator;
 | 
				
			||||||
    private ExecutionContext executionContext;
 | 
					    private ExecutionContext executionContext;
 | 
				
			||||||
    private SymbolTable localScope;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public LET() {
 | 
					    public LET() {
 | 
				
			||||||
        this.argumentValidator = new ArgumentValidator("LET");
 | 
					        this.argumentValidator = new ArgumentValidator("LET");
 | 
				
			||||||
        this.argumentValidator.setMinimumNumberOfArguments(1);
 | 
					        this.argumentValidator.setMinimumNumberOfArguments(1);
 | 
				
			||||||
        this.argumentValidator.setFirstArgumentExpectedType(Cons.class);
 | 
					        this.argumentValidator.setFirstArgumentExpectedType(Cons.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.variableDefinitionListValidator = new ArgumentValidator("LET|pair-list|");
 | 
				
			||||||
 | 
					        this.variableDefinitionListValidator.setEveryArgumentExpectedType(Cons.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.pairValidator = new ArgumentValidator("LET|pair|");
 | 
				
			||||||
 | 
					        this.pairValidator.setExactNumberOfArguments(2);
 | 
				
			||||||
 | 
					        this.pairValidator.setFirstArgumentExpectedType(Symbol.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.executionContext = ExecutionContext.getInstance();
 | 
					        this.executionContext = ExecutionContext.getInstance();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -27,15 +36,15 @@ public class LET extends LispFunction {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private SExpression evaluateInScope(Cons variableDefinitions, Cons body) {
 | 
					    private SExpression evaluateInScope(Cons variableDefinitions, Cons body) {
 | 
				
			||||||
        createLocalScope(variableDefinitions);
 | 
					        SymbolTable localScope = createLocalScope(variableDefinitions);
 | 
				
			||||||
        SExpression lastEvaluation = evaluateBody(body);
 | 
					        SExpression lastEvaluation = evaluateBody(body);
 | 
				
			||||||
        restorePreviousScope();
 | 
					        restorePreviousScope(localScope);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return lastEvaluation;
 | 
					        return lastEvaluation;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private SymbolTable createLocalScope(Cons variableDefinitions) {
 | 
					    private SymbolTable createLocalScope(Cons variableDefinitions) {
 | 
				
			||||||
        localScope = new SymbolTable(executionContext.getScope());
 | 
					        SymbolTable localScope = new SymbolTable(executionContext.getScope());
 | 
				
			||||||
        addVariablesToScope(localScope, variableDefinitions);
 | 
					        addVariablesToScope(localScope, variableDefinitions);
 | 
				
			||||||
        executionContext.setScope(localScope);
 | 
					        executionContext.setScope(localScope);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -43,12 +52,14 @@ public class LET extends LispFunction {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void addVariablesToScope(SymbolTable scope, Cons variableDefinitions) {
 | 
					    private void addVariablesToScope(SymbolTable scope, Cons variableDefinitions) {
 | 
				
			||||||
        validateAllPairsAreLists(variableDefinitions);
 | 
					        variableDefinitionListValidator.validate(variableDefinitions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (; variableDefinitions.consp(); variableDefinitions = (Cons) variableDefinitions.getCdr()) {
 | 
					        for (; variableDefinitions.consp(); variableDefinitions = (Cons) variableDefinitions.getCdr())
 | 
				
			||||||
            Cons symbolValuePair = (Cons) variableDefinitions.getCar();
 | 
					            addPairToScope((Cons) variableDefinitions.getCar(), scope);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            validatePair(symbolValuePair);
 | 
					    private void addPairToScope(Cons symbolValuePair, SymbolTable scope) {
 | 
				
			||||||
 | 
					        pairValidator.validate(symbolValuePair);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Cons restOfPair = (Cons) symbolValuePair.getCdr();
 | 
					        Cons restOfPair = (Cons) symbolValuePair.getCdr();
 | 
				
			||||||
        SExpression symbol = symbolValuePair.getCar();
 | 
					        SExpression symbol = symbolValuePair.getCar();
 | 
				
			||||||
@ -56,20 +67,6 @@ public class LET extends LispFunction {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        scope.put(symbol.toString(), EVAL.eval(value));
 | 
					        scope.put(symbol.toString(), EVAL.eval(value));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private void validateAllPairsAreLists(Cons variableDefinitions) {
 | 
					 | 
				
			||||||
        ArgumentValidator variableDefinitionListValidator = new ArgumentValidator("LET|argumentList|");
 | 
					 | 
				
			||||||
        variableDefinitionListValidator.setEveryArgumentExpectedType(Cons.class);
 | 
					 | 
				
			||||||
        variableDefinitionListValidator.validate(variableDefinitions);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private void validatePair(Cons symbolValuePair) {
 | 
					 | 
				
			||||||
        ArgumentValidator pairValidator = new ArgumentValidator("LET|pair|");
 | 
					 | 
				
			||||||
        pairValidator.setExactNumberOfArguments(2);
 | 
					 | 
				
			||||||
        pairValidator.setFirstArgumentExpectedType(Symbol.class);
 | 
					 | 
				
			||||||
        pairValidator.validate((Cons) symbolValuePair);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private SExpression evaluateBody(Cons body) {
 | 
					    private SExpression evaluateBody(Cons body) {
 | 
				
			||||||
        SExpression lastEvaluation = Nil.getInstance();
 | 
					        SExpression lastEvaluation = Nil.getInstance();
 | 
				
			||||||
@ -80,7 +77,7 @@ public class LET extends LispFunction {
 | 
				
			|||||||
        return lastEvaluation;
 | 
					        return lastEvaluation;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void restorePreviousScope() {
 | 
					    private void restorePreviousScope(SymbolTable localScope) {
 | 
				
			||||||
        executionContext.setScope(localScope.getParent());
 | 
					        executionContext.setScope(localScope.getParent());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -37,6 +37,12 @@ public class EVALTester {
 | 
				
			|||||||
        assertSExpressionsMatch(parseString(symbol), EVAL.lookupSymbol(symbol));
 | 
					        assertSExpressionsMatch(parseString(symbol), EVAL.lookupSymbol(symbol));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void testLookupNil() {
 | 
				
			||||||
 | 
					        String symbol = "NIL";
 | 
				
			||||||
 | 
					        assertSExpressionsMatch(parseString(symbol), EVAL.lookupSymbol(symbol));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    public void testLookupUndefinedSymbol() {
 | 
					    public void testLookupUndefinedSymbol() {
 | 
				
			||||||
        assertNull(EVAL.lookupSymbol("undefined"));
 | 
					        assertNull(EVAL.lookupSymbol("undefined"));
 | 
				
			||||||
 | 
				
			|||||||
@ -46,6 +46,13 @@ public class LAMBDATester {
 | 
				
			|||||||
        evaluateString(input);
 | 
					        evaluateString(input);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test(expected = DottedArgumentListException.class)
 | 
				
			||||||
 | 
					    public void testLambdaWithDottedLambdaList() {
 | 
				
			||||||
 | 
					        String input = "(funcall 'lambda (cons 'a 'b) ())";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        evaluateString(input);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test(expected = DottedArgumentListException.class)
 | 
					    @Test(expected = DottedArgumentListException.class)
 | 
				
			||||||
    public void testCreateFunctionWithDottedArgumentList() {
 | 
					    public void testCreateFunctionWithDottedArgumentList() {
 | 
				
			||||||
        Cons lambdaExpression = new Cons(new Symbol("LAMBDA"), new Cons(Nil.getInstance(), LispNumber.ONE));
 | 
					        Cons lambdaExpression = new Cons(new Symbol("LAMBDA"), new Cons(Nil.getInstance(), LispNumber.ONE));
 | 
				
			||||||
@ -60,9 +67,38 @@ public class LAMBDATester {
 | 
				
			|||||||
        LAMBDA.createFunction(lambdaExpression);
 | 
					        LAMBDA.createFunction(lambdaExpression);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test(expected = BadArgumentTypeException.class)
 | 
				
			||||||
 | 
					    public void testLambdaWithNonSymbolParameter() {
 | 
				
			||||||
 | 
					        evaluateString("(lambda (1) ())");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test(expected = TooFewArgumentsException.class)
 | 
					    @Test(expected = TooFewArgumentsException.class)
 | 
				
			||||||
    public void testLambdaWithTooFewArguments() {
 | 
					    public void testLambdaWithTooFewArguments() {
 | 
				
			||||||
        evaluateString("(lambda ())");
 | 
					        evaluateString("(lambda ())");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void anonymousLambdaCall() {
 | 
				
			||||||
 | 
					        String input = "((lambda (x) x) 203)";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertSExpressionsMatch(new LispNumber("203"), evaluateString(input));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void anonymousLambdaCallWithMultipleArguments() {
 | 
				
			||||||
 | 
					        String input = "((lambda (x y) (+ x y)) 203 2)";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertSExpressionsMatch(new LispNumber("205"), evaluateString(input));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test(expected = TooFewArgumentsException.class)
 | 
				
			||||||
 | 
					    public void anonymousLambdaCallWithTooFewArguments() {
 | 
				
			||||||
 | 
					        evaluateString("((lambda (x) x))");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test(expected = TooManyArgumentsException.class)
 | 
				
			||||||
 | 
					    public void anonymousLambdaCallWithTooManyArguments() {
 | 
				
			||||||
 | 
					        evaluateString("((lambda (x y) x) 1 2 3)");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -65,6 +65,17 @@ public class LETTester {
 | 
				
			|||||||
        assertSExpressionsMatch(new LispNumber("2"), evaluateString(input));
 | 
					        assertSExpressionsMatch(new LispNumber("2"), evaluateString(input));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void nestedLetWithGlobals() {
 | 
				
			||||||
 | 
					        String before = "(setf x 92)";
 | 
				
			||||||
 | 
					        String input = "(let ((x 1)) (let ((y (+ 1 x))) y))";
 | 
				
			||||||
 | 
					        String after = "x";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertSExpressionsMatch(new LispNumber("92"), evaluateString(before));
 | 
				
			||||||
 | 
					        assertSExpressionsMatch(new LispNumber("2"), evaluateString(input));
 | 
				
			||||||
 | 
					        assertSExpressionsMatch(new LispNumber("92"), evaluateString(after));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    public void alterGlobalVariableFromLet() {
 | 
					    public void alterGlobalVariableFromLet() {
 | 
				
			||||||
        String before = "(setf x 1)";
 | 
					        String before = "(setf x 1)";
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user