parent
							
								
									655f49e612
								
							
						
					
					
						commit
						698305f07f
					
				@ -1,10 +0,0 @@
 | 
			
		||||
package function;
 | 
			
		||||
 | 
			
		||||
public abstract class LispMacro extends LispSpecialFunction {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean isMacro() {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										181
									
								
								src/function/builtin/BackTickEvaluator.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								src/function/builtin/BackTickEvaluator.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,181 @@
 | 
			
		||||
package function.builtin;
 | 
			
		||||
 | 
			
		||||
import static function.builtin.EVAL.eval;
 | 
			
		||||
import static sexpression.Nil.NIL;
 | 
			
		||||
 | 
			
		||||
import error.LispException;
 | 
			
		||||
import sexpression.*;
 | 
			
		||||
 | 
			
		||||
class BackTickEvaluator {
 | 
			
		||||
 | 
			
		||||
    private BackTickExpression backTick;
 | 
			
		||||
    private Cons resolvedList;
 | 
			
		||||
    private Cons leader;
 | 
			
		||||
    private Cons follower;
 | 
			
		||||
 | 
			
		||||
    public BackTickEvaluator(BackTickExpression backTick) {
 | 
			
		||||
        this.backTick = backTick;
 | 
			
		||||
        this.resolvedList = new Cons(NIL, NIL);
 | 
			
		||||
        this.leader = resolvedList;
 | 
			
		||||
        this.follower = resolvedList;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public SExpression evaluate() {
 | 
			
		||||
        SExpression expression = backTick.getExpression();
 | 
			
		||||
 | 
			
		||||
        if (expression.isCons())
 | 
			
		||||
            expression = resolveList((Cons) expression);
 | 
			
		||||
        else if (expression.isComma())
 | 
			
		||||
            expression = eval(((CommaExpression) expression).getExpression());
 | 
			
		||||
        else if (expression.isAtSign())
 | 
			
		||||
            throw new AtSignNotInCommaException();
 | 
			
		||||
 | 
			
		||||
        return expression;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public SExpression resolveList(Cons list) {
 | 
			
		||||
        createResolvedList(list);
 | 
			
		||||
 | 
			
		||||
        return resolvedList;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void createResolvedList(Cons list) {
 | 
			
		||||
        for (; list.isCons(); list = (Cons) list.getRest())
 | 
			
		||||
            resolveExpression(list.getFirst());
 | 
			
		||||
 | 
			
		||||
        follower.setRest(NIL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void resolveExpression(SExpression expression) {
 | 
			
		||||
        if (expression.isAtSign())
 | 
			
		||||
            throw new AtSignNotInCommaException();
 | 
			
		||||
        else if (expression.isComma())
 | 
			
		||||
            resolveCommaExpression(expression);
 | 
			
		||||
        else
 | 
			
		||||
            addResolvedExpression(expression);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void resolveCommaExpression(SExpression expression) {
 | 
			
		||||
        CommaEvaluationResult result = evaluateComma((CommaExpression) expression);
 | 
			
		||||
 | 
			
		||||
        if (result.isAtSign())
 | 
			
		||||
            unpackResolvedList((Cons) result.getResult());
 | 
			
		||||
        else
 | 
			
		||||
            addResolvedExpression(result.getResult());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private CommaEvaluationResult evaluateComma(CommaExpression comma) {
 | 
			
		||||
        SExpression expression = comma.getExpression();
 | 
			
		||||
        validateCommaExpression(expression);
 | 
			
		||||
 | 
			
		||||
        if (expression.isAtSign())
 | 
			
		||||
            return new CommaEvaluationAtSignResult(evaluateAtSign((AtSignExpression) expression));
 | 
			
		||||
        else
 | 
			
		||||
            return new CommaEvaluationResult(eval(expression));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void validateCommaExpression(SExpression expression) {
 | 
			
		||||
        if (expression.isComma())
 | 
			
		||||
            throw new NestedCommaException();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Cons evaluateAtSign(AtSignExpression atSign) {
 | 
			
		||||
        SExpression expression = atSign.getExpression();
 | 
			
		||||
        validateAtSignExpression(expression);
 | 
			
		||||
        SExpression result = eval(expression);
 | 
			
		||||
 | 
			
		||||
        if (!result.isList())
 | 
			
		||||
            throw new AtSignNotListException();
 | 
			
		||||
 | 
			
		||||
        return (Cons) result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void validateAtSignExpression(SExpression expression) {
 | 
			
		||||
        if (expression.isComma())
 | 
			
		||||
            throw new NestedCommaException();
 | 
			
		||||
        else if (expression.isAtSign())
 | 
			
		||||
            throw new NestedAtSignException();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void unpackResolvedList(Cons list) {
 | 
			
		||||
        for (; list.isCons(); list = (Cons) list.getRest())
 | 
			
		||||
            addResolvedExpression(list.getFirst());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void addResolvedExpression(SExpression expression) {
 | 
			
		||||
        leader.setFirst(expression);
 | 
			
		||||
        leader.setRest(new Cons(NIL, NIL));
 | 
			
		||||
        follower = leader;
 | 
			
		||||
        leader = (Cons) leader.getRest();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static class CommaEvaluationResult {
 | 
			
		||||
 | 
			
		||||
        private SExpression result;
 | 
			
		||||
 | 
			
		||||
        public CommaEvaluationResult(SExpression result) {
 | 
			
		||||
            this.result = result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public SExpression getResult() {
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public boolean isAtSign() {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static class CommaEvaluationAtSignResult extends CommaEvaluationResult {
 | 
			
		||||
 | 
			
		||||
        public CommaEvaluationAtSignResult(SExpression result) {
 | 
			
		||||
            super(result);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public boolean isAtSign() {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class NestedCommaException extends LispException {
 | 
			
		||||
 | 
			
		||||
        private static final long serialVersionUID = 1L;
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public String getMessage() {
 | 
			
		||||
            return "nested comma";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class NestedAtSignException extends LispException {
 | 
			
		||||
 | 
			
		||||
        private static final long serialVersionUID = 1L;
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public String getMessage() {
 | 
			
		||||
            return "nested at sign";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class AtSignNotInCommaException extends LispException {
 | 
			
		||||
 | 
			
		||||
        private static final long serialVersionUID = 1L;
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public String getMessage() {
 | 
			
		||||
            return "at sign not in comma";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class AtSignNotListException extends LispException {
 | 
			
		||||
 | 
			
		||||
        private static final long serialVersionUID = 1L;
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public String getMessage() {
 | 
			
		||||
            return "at sign did not evaluate to a list";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -68,9 +68,14 @@ public class EVAL extends LispFunction {
 | 
			
		||||
    private SExpression evaluateExpression(SExpression argument) {
 | 
			
		||||
        if (argument.isList())
 | 
			
		||||
            return evaluateList(argument);
 | 
			
		||||
 | 
			
		||||
        if (argument.isSymbol())
 | 
			
		||||
        else if (argument.isSymbol())
 | 
			
		||||
            return evaluateSymbol(argument);
 | 
			
		||||
        else if (argument.isBackTick())
 | 
			
		||||
            return evaluateBackTick(argument);
 | 
			
		||||
        else if (argument.isComma())
 | 
			
		||||
            throw new UnmatchedCommaException();
 | 
			
		||||
        else if (argument.isAtSign())
 | 
			
		||||
            throw new UnmatchedAtSignException();
 | 
			
		||||
 | 
			
		||||
        return argument; // NUMBER or STRING
 | 
			
		||||
    }
 | 
			
		||||
@ -127,6 +132,12 @@ public class EVAL extends LispFunction {
 | 
			
		||||
        throw new UndefinedSymbolException(argument);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private SExpression evaluateBackTick(SExpression argument) {
 | 
			
		||||
        BackTickEvaluator evaluator = new BackTickEvaluator((BackTickExpression) argument);
 | 
			
		||||
 | 
			
		||||
        return evaluator.evaluate();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class UndefinedFunctionException extends LispException {
 | 
			
		||||
 | 
			
		||||
        private static final long serialVersionUID = 1L;
 | 
			
		||||
@ -157,4 +168,24 @@ public class EVAL extends LispFunction {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class UnmatchedCommaException extends LispException {
 | 
			
		||||
 | 
			
		||||
        private static final long serialVersionUID = 1L;
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public String getMessage() {
 | 
			
		||||
            return "unmatched comma";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class UnmatchedAtSignException extends LispException {
 | 
			
		||||
 | 
			
		||||
        private static final long serialVersionUID = 1L;
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public String getMessage() {
 | 
			
		||||
            return "unmatched at sign";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										23
									
								
								src/sexpression/AtSignExpression.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/sexpression/AtSignExpression.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
			
		||||
package sexpression;
 | 
			
		||||
 | 
			
		||||
public class AtSignExpression extends SExpression {
 | 
			
		||||
 | 
			
		||||
    private SExpression expression;
 | 
			
		||||
 | 
			
		||||
    public AtSignExpression(SExpression expression) {
 | 
			
		||||
        this.expression = expression;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public SExpression getExpression() {
 | 
			
		||||
        return expression;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isAtSign() {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return "@" + expression;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								src/sexpression/BackTickExpression.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/sexpression/BackTickExpression.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
			
		||||
package sexpression;
 | 
			
		||||
 | 
			
		||||
public class BackTickExpression extends SExpression {
 | 
			
		||||
 | 
			
		||||
    private SExpression expression;
 | 
			
		||||
 | 
			
		||||
    public BackTickExpression(SExpression expression) {
 | 
			
		||||
        this.expression = expression;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public SExpression getExpression() {
 | 
			
		||||
        return expression;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isBackTick() {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return "`" + expression;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								src/sexpression/CommaExpression.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/sexpression/CommaExpression.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
			
		||||
package sexpression;
 | 
			
		||||
 | 
			
		||||
public class CommaExpression extends SExpression {
 | 
			
		||||
 | 
			
		||||
    private SExpression expression;
 | 
			
		||||
 | 
			
		||||
    public CommaExpression(SExpression expression) {
 | 
			
		||||
        this.expression = expression;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public SExpression getExpression() {
 | 
			
		||||
        return expression;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isComma() {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return "," + expression;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -35,4 +35,16 @@ public abstract class SExpression {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isBackTick() {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isComma() {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isAtSign() {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										22
									
								
								src/token/AtSign.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/token/AtSign.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
package token;
 | 
			
		||||
 | 
			
		||||
import java.util.function.Supplier;
 | 
			
		||||
 | 
			
		||||
import file.FilePosition;
 | 
			
		||||
import sexpression.*;
 | 
			
		||||
 | 
			
		||||
public class AtSign extends Token {
 | 
			
		||||
 | 
			
		||||
    public AtSign(String text, FilePosition position) {
 | 
			
		||||
        super(text, position);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public SExpression parseSExpression(Supplier<Token> getNextToken) {
 | 
			
		||||
        Token nextToken = getNextToken.get();
 | 
			
		||||
        SExpression argument = nextToken.parseSExpression(getNextToken);
 | 
			
		||||
 | 
			
		||||
        return new AtSignExpression(argument);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								src/token/BackTick.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/token/BackTick.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
package token;
 | 
			
		||||
 | 
			
		||||
import java.util.function.Supplier;
 | 
			
		||||
 | 
			
		||||
import file.FilePosition;
 | 
			
		||||
import sexpression.*;
 | 
			
		||||
 | 
			
		||||
public class BackTick extends Token {
 | 
			
		||||
 | 
			
		||||
    public BackTick(String text, FilePosition position) {
 | 
			
		||||
        super(text, position);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public SExpression parseSExpression(Supplier<Token> getNextToken) {
 | 
			
		||||
        Token nextToken = getNextToken.get();
 | 
			
		||||
        SExpression argument = nextToken.parseSExpression(getNextToken);
 | 
			
		||||
 | 
			
		||||
        return new BackTickExpression(argument);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								src/token/Comma.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/token/Comma.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
package token;
 | 
			
		||||
 | 
			
		||||
import java.util.function.Supplier;
 | 
			
		||||
 | 
			
		||||
import file.FilePosition;
 | 
			
		||||
import sexpression.*;
 | 
			
		||||
 | 
			
		||||
public class Comma extends Token {
 | 
			
		||||
 | 
			
		||||
    public Comma(String text, FilePosition position) {
 | 
			
		||||
        super(text, position);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public SExpression parseSExpression(Supplier<Token> getNextToken) {
 | 
			
		||||
        Token nextToken = getNextToken.get();
 | 
			
		||||
        SExpression argument = nextToken.parseSExpression(getNextToken);
 | 
			
		||||
 | 
			
		||||
        return new CommaExpression(argument);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -22,6 +22,12 @@ public class TokenFactoryImpl implements TokenFactory {
 | 
			
		||||
            return new QuoteMark(text, position);
 | 
			
		||||
        case DOUBLE_QUOTE:
 | 
			
		||||
            return new QuotedString(text, position);
 | 
			
		||||
        case BACK_TICK:
 | 
			
		||||
            return new BackTick(text, position);
 | 
			
		||||
        case AT_SIGN:
 | 
			
		||||
            return new AtSign(text, position);
 | 
			
		||||
        case COMMA:
 | 
			
		||||
            return new Comma(text, position);
 | 
			
		||||
        default:
 | 
			
		||||
            if (isNumeric(firstCharacter, text)) {
 | 
			
		||||
                return new Number(text, position);
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,10 @@ public final class Characters {
 | 
			
		||||
 | 
			
		||||
    public static final int EOF = -1;
 | 
			
		||||
 | 
			
		||||
    public static final char AT_SIGN = '@';
 | 
			
		||||
    public static final char BACKSLASH = '\\';
 | 
			
		||||
    public static final char BACK_TICK = '`';
 | 
			
		||||
    public static final char COMMA = ',';
 | 
			
		||||
    public static final char DASH = '-';
 | 
			
		||||
    public static final char DOUBLE_QUOTE = '\"';
 | 
			
		||||
    public static final char HASH = '#';
 | 
			
		||||
@ -21,22 +24,23 @@ public final class Characters {
 | 
			
		||||
    public static final char RIGHT_SQUARE_BRACKET = ']';
 | 
			
		||||
    public static final char SEMICOLON = ';';
 | 
			
		||||
    public static final char SINGLE_QUOTE = '\'';
 | 
			
		||||
    public static final char TICK_MARK = '`';
 | 
			
		||||
 | 
			
		||||
    public static final Set<Character> illegalIdentifierCharacters = new HashSet<>();
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
        illegalIdentifierCharacters.add(DOUBLE_QUOTE);
 | 
			
		||||
        illegalIdentifierCharacters.add(SINGLE_QUOTE);
 | 
			
		||||
        illegalIdentifierCharacters.add(AT_SIGN);
 | 
			
		||||
        illegalIdentifierCharacters.add(BACKSLASH);
 | 
			
		||||
        illegalIdentifierCharacters.add(TICK_MARK);
 | 
			
		||||
        illegalIdentifierCharacters.add(LEFT_PARENTHESIS);
 | 
			
		||||
        illegalIdentifierCharacters.add(RIGHT_PARENTHESIS);
 | 
			
		||||
        illegalIdentifierCharacters.add(LEFT_SQUARE_BRACKET);
 | 
			
		||||
        illegalIdentifierCharacters.add(RIGHT_SQUARE_BRACKET);
 | 
			
		||||
        illegalIdentifierCharacters.add(BACK_TICK);
 | 
			
		||||
        illegalIdentifierCharacters.add(COMMA);
 | 
			
		||||
        illegalIdentifierCharacters.add(DOUBLE_QUOTE);
 | 
			
		||||
        illegalIdentifierCharacters.add(HASH);
 | 
			
		||||
        illegalIdentifierCharacters.add(LEFT_PARENTHESIS);
 | 
			
		||||
        illegalIdentifierCharacters.add(LEFT_SQUARE_BRACKET);
 | 
			
		||||
        illegalIdentifierCharacters.add(PERIOD);
 | 
			
		||||
        illegalIdentifierCharacters.add(RIGHT_PARENTHESIS);
 | 
			
		||||
        illegalIdentifierCharacters.add(RIGHT_SQUARE_BRACKET);
 | 
			
		||||
        illegalIdentifierCharacters.add(SEMICOLON);
 | 
			
		||||
        illegalIdentifierCharacters.add(SINGLE_QUOTE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean isLegalIdentifierCharacter(char c) {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										135
									
								
								test/function/builtin/BackTickEvaluatorTester.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								test/function/builtin/BackTickEvaluatorTester.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,135 @@
 | 
			
		||||
package function.builtin;
 | 
			
		||||
 | 
			
		||||
import static sexpression.Nil.NIL;
 | 
			
		||||
import static testutil.TestUtilities.*;
 | 
			
		||||
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
 | 
			
		||||
import function.builtin.BackTickEvaluator.*;
 | 
			
		||||
import sexpression.*;
 | 
			
		||||
 | 
			
		||||
public class BackTickEvaluatorTester {
 | 
			
		||||
 | 
			
		||||
    private BackTickEvaluator createBackTickEvaluator(SExpression expression) {
 | 
			
		||||
        return new BackTickEvaluator(new BackTickExpression(expression));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void evaluateNil() {
 | 
			
		||||
        BackTickEvaluator evaluator = createBackTickEvaluator(NIL);
 | 
			
		||||
 | 
			
		||||
        assertSExpressionsMatch(NIL, evaluator.evaluate());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void evaluateNumber() {
 | 
			
		||||
        SExpression input = new LispNumber("99");
 | 
			
		||||
        BackTickEvaluator evaluator = createBackTickEvaluator(input);
 | 
			
		||||
 | 
			
		||||
        assertSExpressionsMatch(input, evaluator.evaluate());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void evaluateList() {
 | 
			
		||||
        SExpression input = makeList(new LispNumber("1"), new LispNumber("99"));
 | 
			
		||||
        BackTickEvaluator evaluator = createBackTickEvaluator(input);
 | 
			
		||||
 | 
			
		||||
        assertSExpressionsMatch(input, evaluator.evaluate());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void evaluateComma() {
 | 
			
		||||
        SExpression input = new CommaExpression(makeList(new Symbol("+"), new LispNumber("1"), new LispNumber("9")));
 | 
			
		||||
        BackTickEvaluator evaluator = createBackTickEvaluator(input);
 | 
			
		||||
 | 
			
		||||
        assertSExpressionsMatch(new LispNumber("10"), evaluator.evaluate());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void evaluateListWithComma() {
 | 
			
		||||
        SExpression input = makeList(new CommaExpression(makeList(new Symbol("+"), new LispNumber("1"),
 | 
			
		||||
                                                                  new LispNumber("9"))));
 | 
			
		||||
        BackTickEvaluator evaluator = createBackTickEvaluator(input);
 | 
			
		||||
 | 
			
		||||
        assertSExpressionsMatch(makeList(new LispNumber("10")), evaluator.evaluate());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test(expected = NestedCommaException.class)
 | 
			
		||||
    public void evaluateListWithNestedComma() {
 | 
			
		||||
        SExpression input = makeList(new CommaExpression(new CommaExpression(new Symbol("+"))));
 | 
			
		||||
        BackTickEvaluator evaluator = createBackTickEvaluator(input);
 | 
			
		||||
 | 
			
		||||
        evaluator.evaluate();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test(expected = AtSignNotInCommaException.class)
 | 
			
		||||
    public void evaluateListWithNoCommaPrecedingAtSign() {
 | 
			
		||||
        SExpression input = makeList(new AtSignExpression(makeList(new Symbol("+"))));
 | 
			
		||||
        BackTickEvaluator evaluator = createBackTickEvaluator(input);
 | 
			
		||||
 | 
			
		||||
        evaluator.evaluate();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test(expected = AtSignNotInCommaException.class)
 | 
			
		||||
    public void evaluateAtSign() {
 | 
			
		||||
        SExpression input = new AtSignExpression(makeList(new Symbol("+")));
 | 
			
		||||
        BackTickEvaluator evaluator = createBackTickEvaluator(input);
 | 
			
		||||
 | 
			
		||||
        evaluator.evaluate();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test(expected = NestedAtSignException.class)
 | 
			
		||||
    public void evaluateListWithNestedAtSigns() {
 | 
			
		||||
        SExpression input = makeList(new CommaExpression(new AtSignExpression(new AtSignExpression(makeList(new Symbol("+"))))));
 | 
			
		||||
        BackTickEvaluator evaluator = createBackTickEvaluator(input);
 | 
			
		||||
 | 
			
		||||
        evaluator.evaluate();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test(expected = NestedCommaException.class)
 | 
			
		||||
    public void evaluateListWithCommaAfterAtSign() {
 | 
			
		||||
        SExpression input = makeList(new CommaExpression(new AtSignExpression(new CommaExpression(makeList(new Symbol("+"))))));
 | 
			
		||||
        BackTickEvaluator evaluator = createBackTickEvaluator(input);
 | 
			
		||||
 | 
			
		||||
        evaluator.evaluate();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void evaluateListWithAtSign() {
 | 
			
		||||
        SExpression input = makeList(new CommaExpression(new AtSignExpression(makeList(new Symbol("LIST"),
 | 
			
		||||
                                                                                       new LispNumber("1"),
 | 
			
		||||
                                                                                       new LispNumber("9")))));
 | 
			
		||||
        SExpression expected = makeList(new LispNumber("1"), new LispNumber("9"));
 | 
			
		||||
        BackTickEvaluator evaluator = createBackTickEvaluator(input);
 | 
			
		||||
 | 
			
		||||
        assertSExpressionsMatch(expected, evaluator.evaluate());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test(expected = AtSignNotListException.class)
 | 
			
		||||
    public void atSignDoesNotEvaluateToList() {
 | 
			
		||||
        SExpression input = makeList(new CommaExpression(new AtSignExpression(new LispNumber("1"))));
 | 
			
		||||
        BackTickEvaluator evaluator = createBackTickEvaluator(input);
 | 
			
		||||
 | 
			
		||||
        evaluator.evaluate();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void evaluateListWithCommasAndAtSign() {
 | 
			
		||||
        SExpression input = makeList(new LispNumber("78"),
 | 
			
		||||
                                     new CommaExpression(new AtSignExpression(makeList(new Symbol("LIST"),
 | 
			
		||||
                                                                                       new LispNumber("1"),
 | 
			
		||||
                                                                                       new LispNumber("9")))),
 | 
			
		||||
                                     new CommaExpression(makeList(new Symbol("+"), new LispNumber("20"),
 | 
			
		||||
                                                                  new LispNumber("5"))),
 | 
			
		||||
                                     new CommaExpression(makeList(new Symbol("LIST"), new LispNumber("7"),
 | 
			
		||||
                                                                  new LispNumber("6"))),
 | 
			
		||||
                                     new LispString("\"sky\""));
 | 
			
		||||
        SExpression expected = makeList(new LispNumber("78"), new LispNumber("1"), new LispNumber("9"),
 | 
			
		||||
                                        new LispNumber("25"), makeList(new LispNumber("7"), new LispNumber("6")),
 | 
			
		||||
                                        new LispString("\"sky\""));
 | 
			
		||||
        BackTickEvaluator evaluator = createBackTickEvaluator(input);
 | 
			
		||||
 | 
			
		||||
        assertSExpressionsMatch(expected, evaluator.evaluate());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -9,6 +9,7 @@ import static testutil.TestUtilities.*;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
 | 
			
		||||
import function.ArgumentValidator.*;
 | 
			
		||||
import function.builtin.BackTickEvaluator.AtSignNotInCommaException;
 | 
			
		||||
import function.builtin.EVAL.*;
 | 
			
		||||
 | 
			
		||||
public class EVALTester {
 | 
			
		||||
@ -99,4 +100,46 @@ public class EVALTester {
 | 
			
		||||
        assertTrue(e.getMessage().length() > 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test(expected = UnmatchedCommaException.class)
 | 
			
		||||
    public void evalComma() {
 | 
			
		||||
        String input = ",a";
 | 
			
		||||
 | 
			
		||||
        evaluateString(input);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test(expected = UnmatchedAtSignException.class)
 | 
			
		||||
    public void evalAtSign() {
 | 
			
		||||
        String input = "@a";
 | 
			
		||||
 | 
			
		||||
        evaluateString(input);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void evalBackTick() {
 | 
			
		||||
        String input = "`(a b c)";
 | 
			
		||||
 | 
			
		||||
        assertSExpressionsMatch(parseString("(a b c)"), evaluateString(input));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void evalBackTickWithCommasAndAtSigns() {
 | 
			
		||||
        String input = "(let ((x '(1 2 3)) (y '(4 5 6)) (z 'apple)) `(start ,x ,@y ,z end))";
 | 
			
		||||
 | 
			
		||||
        assertSExpressionsMatch(parseString("(start (1 2 3) 4 5 6 apple end)"), evaluateString(input));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void evalBackTickOnComma() {
 | 
			
		||||
        String input = "`,9";
 | 
			
		||||
 | 
			
		||||
        assertSExpressionsMatch(parseString("9"), evaluateString(input));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test(expected = AtSignNotInCommaException.class)
 | 
			
		||||
    public void evalBackTickOnAtSign() {
 | 
			
		||||
        String input = "`@9";
 | 
			
		||||
 | 
			
		||||
        assertSExpressionsMatch(parseString("9"), evaluateString(input));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -310,4 +310,61 @@ public class LispParserTester {
 | 
			
		||||
        parser.getNextSExpression();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void givenBackTickExpression_CreatesCorrectSExpression() {
 | 
			
		||||
        String input = "`(list ,a ,@b)";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        assertBackTickExpression(parser.getNextSExpression());
 | 
			
		||||
        assertTrue(parser.isEof());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void givenComma_CreatesCorrectSExpression() {
 | 
			
		||||
        String input = ",a";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        assertCommaExpression(parser.getNextSExpression());
 | 
			
		||||
        assertTrue(parser.isEof());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void givenAtSignExpression_CreatesCorrectSExpression() {
 | 
			
		||||
        String input = "@b";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        assertAtSignExpression(parser.getNextSExpression());
 | 
			
		||||
        assertTrue(parser.isEof());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void backTickIsNotPartOfIdentifier() {
 | 
			
		||||
        String input = "id`ab";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        assertSymbol(parser.getNextSExpression());
 | 
			
		||||
        assertBackTickExpression(parser.getNextSExpression());
 | 
			
		||||
        assertTrue(parser.isEof());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void commaIsNotPartOfIdentifier() {
 | 
			
		||||
        String input = "id,ab";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        assertSymbol(parser.getNextSExpression());
 | 
			
		||||
        assertCommaExpression(parser.getNextSExpression());
 | 
			
		||||
        assertTrue(parser.isEof());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void atSignIsNotPartOfIdentifier() {
 | 
			
		||||
        String input = "id@ab";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        assertSymbol(parser.getNextSExpression());
 | 
			
		||||
        assertAtSignExpression(parser.getNextSExpression());
 | 
			
		||||
        assertTrue(parser.isEof());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -107,4 +107,12 @@ public class LispScannerTextTester {
 | 
			
		||||
        assertTokenTextMatches(input, expected);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void givenBackTickExpression_RecordsCorrectText() {
 | 
			
		||||
        String input = "`(list ,a ,@b)";
 | 
			
		||||
        String[] expected = { "`", "(", "list", ",", "a", ",", "@", "b", ")" };
 | 
			
		||||
 | 
			
		||||
        assertTokenTextMatches(input, expected);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -278,4 +278,20 @@ public class LispScannerTypeTester {
 | 
			
		||||
        assertTokenTypesMatch(input);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void givenBackTickExpression_ReturnsCorrectTypes() {
 | 
			
		||||
        String input = "`(list ,a ,@b)";
 | 
			
		||||
        expectedTypes.add(BackTick.class);
 | 
			
		||||
        expectedTypes.add(LeftParenthesis.class);
 | 
			
		||||
        expectedTypes.add(Identifier.class);
 | 
			
		||||
        expectedTypes.add(Comma.class);
 | 
			
		||||
        expectedTypes.add(Identifier.class);
 | 
			
		||||
        expectedTypes.add(Comma.class);
 | 
			
		||||
        expectedTypes.add(AtSign.class);
 | 
			
		||||
        expectedTypes.add(Identifier.class);
 | 
			
		||||
        expectedTypes.add(RightParenthesis.class);
 | 
			
		||||
 | 
			
		||||
        assertTokenTypesMatch(input);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,7 @@ package sexpression;
 | 
			
		||||
import static error.ErrorManager.Severity.ERROR;
 | 
			
		||||
import static org.junit.Assert.*;
 | 
			
		||||
import static sexpression.Nil.NIL;
 | 
			
		||||
import static testutil.TestUtilities.*;
 | 
			
		||||
 | 
			
		||||
import java.math.BigInteger;
 | 
			
		||||
 | 
			
		||||
@ -21,59 +22,58 @@ public class SExpressionTester {
 | 
			
		||||
    public void setUp() throws Exception {}
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void nilToString() {
 | 
			
		||||
    public void nil_ToString() {
 | 
			
		||||
        String input = "NIL";
 | 
			
		||||
 | 
			
		||||
        assertSExpressionMatchesString(input, NIL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void numberToString() {
 | 
			
		||||
    public void number_ToString() {
 | 
			
		||||
        String input = "12";
 | 
			
		||||
 | 
			
		||||
        assertSExpressionMatchesString(input, new LispNumber(input));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void numberValueToString() {
 | 
			
		||||
    public void numberValue_ToString() {
 | 
			
		||||
        String expected = "12";
 | 
			
		||||
 | 
			
		||||
        assertSExpressionMatchesString(expected, new LispNumber("12"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void stringToString() {
 | 
			
		||||
    public void string_ToString() {
 | 
			
		||||
        String input = "\"hi\"";
 | 
			
		||||
 | 
			
		||||
        assertSExpressionMatchesString(input, new LispString(input));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void symbolToString() {
 | 
			
		||||
    public void symbol_ToString() {
 | 
			
		||||
        String input = "symbol";
 | 
			
		||||
 | 
			
		||||
        assertSExpressionMatchesString(input.toUpperCase(), new Symbol(input));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void simpleConsToString() {
 | 
			
		||||
    public void simpleCons_ToString() {
 | 
			
		||||
        String expected = "(1)";
 | 
			
		||||
        Cons cons = new Cons(new LispNumber("1"), NIL);
 | 
			
		||||
        Cons cons = makeList(new LispNumber("1"));
 | 
			
		||||
 | 
			
		||||
        assertSExpressionMatchesString(expected, cons);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void complexConsToString() {
 | 
			
		||||
    public void complexCons_ToString() {
 | 
			
		||||
        String expected = "(1 A \"string\")";
 | 
			
		||||
        Cons list = new Cons(new LispNumber("1"),
 | 
			
		||||
                             new Cons(new Symbol("a"), new Cons(new LispString("\"string\""), NIL)));
 | 
			
		||||
        Cons list = makeList(new LispNumber("1"), new Symbol("a"), new LispString("\"string\""));
 | 
			
		||||
 | 
			
		||||
        assertSExpressionMatchesString(expected, list);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void improperListToString() {
 | 
			
		||||
    public void improperList_ToString() {
 | 
			
		||||
        String expected = "(A . B)";
 | 
			
		||||
        Cons list = new Cons(new Symbol("A"), new Symbol("B"));
 | 
			
		||||
 | 
			
		||||
@ -81,26 +81,26 @@ public class SExpressionTester {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void lambdaExpressionToString() {
 | 
			
		||||
    public void lambdaExpression_ToString() {
 | 
			
		||||
        String expected = "(LAMBDA)";
 | 
			
		||||
        LambdaExpression lambda = new LambdaExpression(new Cons(new Symbol("lambda"), NIL), null);
 | 
			
		||||
        LambdaExpression lambda = new LambdaExpression(makeList(new Symbol("lambda")), null);
 | 
			
		||||
 | 
			
		||||
        assertSExpressionMatchesString(expected, lambda);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void lambdaExpressionGetLambdaExpression() {
 | 
			
		||||
    public void lambdaExpression_GetLambdaExpression() {
 | 
			
		||||
        String expected = "(LAMBDA)";
 | 
			
		||||
        LambdaExpression lambda = new LambdaExpression(new Cons(new Symbol("lambda"), NIL), null);
 | 
			
		||||
        LambdaExpression lambda = new LambdaExpression(makeList(new Symbol("lambda")), null);
 | 
			
		||||
 | 
			
		||||
        assertSExpressionMatchesString(expected, lambda.getLambdaExpression());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void lambdaExpressionGetFunction() {
 | 
			
		||||
    public void lambdaExpression_GetFunction() {
 | 
			
		||||
        String expected = "(LAMBDA)";
 | 
			
		||||
        UserDefinedFunction function = new UserDefinedFunction(expected, NIL, NIL);
 | 
			
		||||
        LambdaExpression lambda = new LambdaExpression(new Cons(new Symbol("lambda"), NIL), function);
 | 
			
		||||
        LambdaExpression lambda = new LambdaExpression(makeList(new Symbol("lambda")), function);
 | 
			
		||||
 | 
			
		||||
        assertEquals(function, lambda.getFunction());
 | 
			
		||||
    }
 | 
			
		||||
@ -163,4 +163,61 @@ public class SExpressionTester {
 | 
			
		||||
        assertEquals(BigInteger.ONE, LispNumber.ONE.getValue());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void backTickExpression_ToString() {
 | 
			
		||||
        String expected = "`(TEST)";
 | 
			
		||||
        SExpression backTick = new BackTickExpression(makeList(new Symbol("TEST")));
 | 
			
		||||
 | 
			
		||||
        assertSExpressionMatchesString(expected, backTick);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void commaExpression_ToString() {
 | 
			
		||||
        String expected = ",A";
 | 
			
		||||
        SExpression comma = new CommaExpression(new Symbol("A"));
 | 
			
		||||
 | 
			
		||||
        assertSExpressionMatchesString(expected, comma);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void atSignExpression_ToString() {
 | 
			
		||||
        String expected = "@A";
 | 
			
		||||
        SExpression atSign = new AtSignExpression(new Symbol("A"));
 | 
			
		||||
 | 
			
		||||
        assertSExpressionMatchesString(expected, atSign);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void complexBackTickExpression_ToString() {
 | 
			
		||||
        String expected = "`(LIST ,A ,@B)";
 | 
			
		||||
        SExpression backTick = new BackTickExpression(makeList(new Symbol("LIST"), new CommaExpression(new Symbol("A")),
 | 
			
		||||
                                                               new CommaExpression(new AtSignExpression(new Symbol("B")))));
 | 
			
		||||
 | 
			
		||||
        assertSExpressionMatchesString(expected, backTick);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void backTickExpression_GetExpression() {
 | 
			
		||||
        SExpression expression = makeList(new Symbol("TEST"));
 | 
			
		||||
        BackTickExpression backTick = new BackTickExpression(expression);
 | 
			
		||||
 | 
			
		||||
        assertSExpressionsMatch(expression, backTick.getExpression());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void commaExpression_GetExpression() {
 | 
			
		||||
        SExpression expression = new Symbol("A");
 | 
			
		||||
        CommaExpression comma = new CommaExpression(expression);
 | 
			
		||||
 | 
			
		||||
        assertSExpressionsMatch(expression, comma.getExpression());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void atSignExpression_GetExpression() {
 | 
			
		||||
        SExpression expression = new Symbol("A");
 | 
			
		||||
        AtSignExpression atSign = new AtSignExpression(expression);
 | 
			
		||||
 | 
			
		||||
        assertSExpressionsMatch(expression, atSign.getExpression());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2,11 +2,13 @@ package testutil;
 | 
			
		||||
 | 
			
		||||
import static function.builtin.EVAL.eval;
 | 
			
		||||
import static org.junit.Assert.*;
 | 
			
		||||
import static sexpression.Nil.NIL;
 | 
			
		||||
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
 | 
			
		||||
import parser.LispParser;
 | 
			
		||||
import sexpression.SExpression;
 | 
			
		||||
import sexpression.*;
 | 
			
		||||
 | 
			
		||||
public final class TestUtilities {
 | 
			
		||||
 | 
			
		||||
@ -41,4 +43,13 @@ public final class TestUtilities {
 | 
			
		||||
        assertNotEquals(one.toString(), two.toString());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Cons makeList(SExpression... expressionList) {
 | 
			
		||||
        if (expressionList.length == 0)
 | 
			
		||||
            return NIL;
 | 
			
		||||
 | 
			
		||||
        Cons rest = makeList(Arrays.copyOfRange(expressionList, 1, expressionList.length));
 | 
			
		||||
 | 
			
		||||
        return new Cons(expressionList[0], rest);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,9 @@ public final class TypeAssertions {
 | 
			
		||||
        assertFalse(sExpression.isNumber());
 | 
			
		||||
        assertFalse(sExpression.isString());
 | 
			
		||||
        assertFalse(sExpression.isSymbol());
 | 
			
		||||
        assertFalse(sExpression.isBackTick());
 | 
			
		||||
        assertFalse(sExpression.isComma());
 | 
			
		||||
        assertFalse(sExpression.isAtSign());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void assertNil(SExpression sExpression) {
 | 
			
		||||
@ -30,7 +33,9 @@ public final class TypeAssertions {
 | 
			
		||||
        assertFalse(sExpression.isNumber());
 | 
			
		||||
        assertFalse(sExpression.isString());
 | 
			
		||||
        assertTrue(sExpression.isSymbol());
 | 
			
		||||
 | 
			
		||||
        assertFalse(sExpression.isBackTick());
 | 
			
		||||
        assertFalse(sExpression.isComma());
 | 
			
		||||
        assertFalse(sExpression.isAtSign());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void assertNumber(SExpression sExpression) {
 | 
			
		||||
@ -42,6 +47,9 @@ public final class TypeAssertions {
 | 
			
		||||
        assertTrue(sExpression.isNumber());
 | 
			
		||||
        assertFalse(sExpression.isString());
 | 
			
		||||
        assertFalse(sExpression.isSymbol());
 | 
			
		||||
        assertFalse(sExpression.isBackTick());
 | 
			
		||||
        assertFalse(sExpression.isComma());
 | 
			
		||||
        assertFalse(sExpression.isAtSign());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void assertString(SExpression sExpression) {
 | 
			
		||||
@ -53,6 +61,9 @@ public final class TypeAssertions {
 | 
			
		||||
        assertFalse(sExpression.isNumber());
 | 
			
		||||
        assertTrue(sExpression.isString());
 | 
			
		||||
        assertFalse(sExpression.isSymbol());
 | 
			
		||||
        assertFalse(sExpression.isBackTick());
 | 
			
		||||
        assertFalse(sExpression.isComma());
 | 
			
		||||
        assertFalse(sExpression.isAtSign());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void assertSymbol(SExpression sExpression) {
 | 
			
		||||
@ -64,10 +75,55 @@ public final class TypeAssertions {
 | 
			
		||||
        assertFalse(sExpression.isNumber());
 | 
			
		||||
        assertFalse(sExpression.isString());
 | 
			
		||||
        assertTrue(sExpression.isSymbol());
 | 
			
		||||
        assertFalse(sExpression.isBackTick());
 | 
			
		||||
        assertFalse(sExpression.isComma());
 | 
			
		||||
        assertFalse(sExpression.isAtSign());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void assertT(SExpression sExpression) {
 | 
			
		||||
        assertEquals(T, sExpression);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void assertBackTickExpression(SExpression sExpression) {
 | 
			
		||||
        assertFalse(sExpression.isAtom());
 | 
			
		||||
        assertFalse(sExpression.isCons());
 | 
			
		||||
        assertFalse(sExpression.isFunction());
 | 
			
		||||
        assertFalse(sExpression.isList());
 | 
			
		||||
        assertFalse(sExpression.isNull());
 | 
			
		||||
        assertFalse(sExpression.isNumber());
 | 
			
		||||
        assertFalse(sExpression.isString());
 | 
			
		||||
        assertFalse(sExpression.isSymbol());
 | 
			
		||||
        assertTrue(sExpression.isBackTick());
 | 
			
		||||
        assertFalse(sExpression.isComma());
 | 
			
		||||
        assertFalse(sExpression.isAtSign());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void assertCommaExpression(SExpression sExpression) {
 | 
			
		||||
        assertFalse(sExpression.isAtom());
 | 
			
		||||
        assertFalse(sExpression.isCons());
 | 
			
		||||
        assertFalse(sExpression.isFunction());
 | 
			
		||||
        assertFalse(sExpression.isList());
 | 
			
		||||
        assertFalse(sExpression.isNull());
 | 
			
		||||
        assertFalse(sExpression.isNumber());
 | 
			
		||||
        assertFalse(sExpression.isString());
 | 
			
		||||
        assertFalse(sExpression.isSymbol());
 | 
			
		||||
        assertFalse(sExpression.isBackTick());
 | 
			
		||||
        assertTrue(sExpression.isComma());
 | 
			
		||||
        assertFalse(sExpression.isAtSign());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void assertAtSignExpression(SExpression sExpression) {
 | 
			
		||||
        assertFalse(sExpression.isAtom());
 | 
			
		||||
        assertFalse(sExpression.isCons());
 | 
			
		||||
        assertFalse(sExpression.isFunction());
 | 
			
		||||
        assertFalse(sExpression.isList());
 | 
			
		||||
        assertFalse(sExpression.isNull());
 | 
			
		||||
        assertFalse(sExpression.isNumber());
 | 
			
		||||
        assertFalse(sExpression.isString());
 | 
			
		||||
        assertFalse(sExpression.isSymbol());
 | 
			
		||||
        assertFalse(sExpression.isBackTick());
 | 
			
		||||
        assertFalse(sExpression.isComma());
 | 
			
		||||
        assertTrue(sExpression.isAtSign());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -84,22 +84,14 @@ public class TokenFactoryTester {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void emptyTokenTextException_ContainsCorrectSeverity() {
 | 
			
		||||
        try {
 | 
			
		||||
            createToken("");
 | 
			
		||||
        } catch (EmptyTokenTextException e) {
 | 
			
		||||
            assertEquals(CRITICAL, e.getSeverity());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void emptyTokenTextException_ContainsMessage() {
 | 
			
		||||
    public void emptyTokenTextException_ContainsCorrectAttributes() {
 | 
			
		||||
        try {
 | 
			
		||||
            createToken("");
 | 
			
		||||
        } catch (EmptyTokenTextException e) {
 | 
			
		||||
            String message = e.getMessage();
 | 
			
		||||
            assertNotNull(message);
 | 
			
		||||
            assertTrue(message.length() > 0);
 | 
			
		||||
            assertEquals(CRITICAL, e.getSeverity());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -108,4 +100,22 @@ public class TokenFactoryTester {
 | 
			
		||||
        createToken("[abc]");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void backTickCreation() {
 | 
			
		||||
        String text = "`";
 | 
			
		||||
        assertTrue(createToken(text) instanceof BackTick);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void commaCreation() {
 | 
			
		||||
        String text = ",";
 | 
			
		||||
        assertTrue(createToken(text) instanceof Comma);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void atSignCreation() {
 | 
			
		||||
        String text = "@";
 | 
			
		||||
        assertTrue(createToken(text) instanceof AtSign);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user