Convert lisp parser to kotlin
This commit is contained in:
		
							parent
							
								
									61adaffd3c
								
							
						
					
					
						commit
						9064acd7ed
					
				@ -90,7 +90,7 @@ public class LOAD extends LispFunction {
 | 
			
		||||
    private boolean isSuccessfulEvaluation(LispParser parser) {
 | 
			
		||||
        while (!parser.isEof()) {
 | 
			
		||||
            try {
 | 
			
		||||
                eval(parser.getNextSExpression());
 | 
			
		||||
                eval(parser.nextSExpression());
 | 
			
		||||
            } catch (LispException e) {
 | 
			
		||||
                environment.getErrorManager().handle(e);
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,7 @@ public class LispInterpreter {
 | 
			
		||||
            LispParser languageParser = new LispParser(file.getInputStream(), file.getName());
 | 
			
		||||
 | 
			
		||||
            while (!languageParser.isEof())
 | 
			
		||||
                eval(languageParser.getNextSExpression());
 | 
			
		||||
                eval(languageParser.nextSExpression());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -56,7 +56,7 @@ public class LispInterpreter {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected SExpression evaluateNextSExpression() {
 | 
			
		||||
        SExpression sExpression = parser.getNextSExpression();
 | 
			
		||||
        SExpression sExpression = parser.nextSExpression();
 | 
			
		||||
 | 
			
		||||
        return eval(sExpression);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1,63 +0,0 @@
 | 
			
		||||
package parser;
 | 
			
		||||
 | 
			
		||||
import error.LispException;
 | 
			
		||||
import scanner.LispScanner;
 | 
			
		||||
import sexpression.SExpression;
 | 
			
		||||
import token.Eof;
 | 
			
		||||
import token.Token;
 | 
			
		||||
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Converts a stream of bytes into internal representations of Lisp s-expressions.
 | 
			
		||||
 */
 | 
			
		||||
public class LispParser {
 | 
			
		||||
 | 
			
		||||
    private LispScanner scanner;
 | 
			
		||||
    private Token nextToken;
 | 
			
		||||
    private LispException delayedException;
 | 
			
		||||
    private boolean isNextTokenStored;
 | 
			
		||||
 | 
			
		||||
    public LispParser(InputStream inputStream, String fileName) {
 | 
			
		||||
        scanner = new LispScanner(inputStream, fileName);
 | 
			
		||||
        nextToken = null;
 | 
			
		||||
        delayedException = null;
 | 
			
		||||
        isNextTokenStored = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isEof() {
 | 
			
		||||
        if (!isNextTokenStored)
 | 
			
		||||
            storeNextToken();
 | 
			
		||||
 | 
			
		||||
        return nextToken instanceof Eof;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void storeNextToken() {
 | 
			
		||||
        try {
 | 
			
		||||
            nextToken = scanner.getNextToken();
 | 
			
		||||
            isNextTokenStored = true;
 | 
			
		||||
        } catch (LispException e) {
 | 
			
		||||
            delayedException = e;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public SExpression getNextSExpression() {
 | 
			
		||||
        throwDelayedExceptionIfNecessary();
 | 
			
		||||
 | 
			
		||||
        if (!isNextTokenStored)
 | 
			
		||||
            nextToken = scanner.getNextToken();
 | 
			
		||||
 | 
			
		||||
        isNextTokenStored = false;
 | 
			
		||||
 | 
			
		||||
        return nextToken.parseSExpression(scanner::getNextToken);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void throwDelayedExceptionIfNecessary() {
 | 
			
		||||
        if (delayedException != null) {
 | 
			
		||||
            LispException exceptionToThrow = delayedException;
 | 
			
		||||
            delayedException = null;
 | 
			
		||||
 | 
			
		||||
            throw exceptionToThrow;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								src/main/kotlin/parser/LispParser.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/main/kotlin/parser/LispParser.kt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,55 @@
 | 
			
		||||
package parser
 | 
			
		||||
 | 
			
		||||
import error.LispException
 | 
			
		||||
import scanner.LispScanner
 | 
			
		||||
import sexpression.SExpression
 | 
			
		||||
import token.Eof
 | 
			
		||||
import token.Token
 | 
			
		||||
import java.io.InputStream
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Converts a stream of bytes into internal representations of Lisp s-expressions.
 | 
			
		||||
 */
 | 
			
		||||
class LispParser(inputStream: InputStream, fileName: String) {
 | 
			
		||||
 | 
			
		||||
    private val scanner: LispScanner = LispScanner(inputStream, fileName)
 | 
			
		||||
    private var nextToken: Token? = null
 | 
			
		||||
    private var delayedException: LispException? = null
 | 
			
		||||
    private var isNextTokenStored: Boolean = false
 | 
			
		||||
 | 
			
		||||
    fun isEof(): Boolean {
 | 
			
		||||
        if (!isNextTokenStored)
 | 
			
		||||
            storeNextToken()
 | 
			
		||||
 | 
			
		||||
        return nextToken is Eof
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun nextSExpression(): SExpression {
 | 
			
		||||
        throwDelayedExceptionIfNecessary()
 | 
			
		||||
 | 
			
		||||
        if (!isNextTokenStored)
 | 
			
		||||
            nextToken = scanner.nextToken
 | 
			
		||||
 | 
			
		||||
        isNextTokenStored = false
 | 
			
		||||
 | 
			
		||||
        return nextToken!!.parseSExpression({ scanner.nextToken })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun storeNextToken() {
 | 
			
		||||
        try {
 | 
			
		||||
            nextToken = scanner.nextToken
 | 
			
		||||
            isNextTokenStored = true
 | 
			
		||||
        } catch (e: LispException) {
 | 
			
		||||
            delayedException = e
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun throwDelayedExceptionIfNecessary() {
 | 
			
		||||
        if (delayedException != null) {
 | 
			
		||||
            val exceptionToThrow = delayedException!!
 | 
			
		||||
            delayedException = null
 | 
			
		||||
 | 
			
		||||
            throw exceptionToThrow
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -29,30 +29,29 @@ class FilePositionTrackerTest {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun noMovement_ReturnsInitialPosition() {
 | 
			
		||||
    fun `no movement returns the initial position`() {
 | 
			
		||||
        assertTrackerPositionEquals(createFilePosition(1, 0))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun advanceOneColumn_ReturnsCorrectPosition() {
 | 
			
		||||
    fun `advancing one column returns correct position`() {
 | 
			
		||||
        trackerUnderTest.incrementColumn()
 | 
			
		||||
 | 
			
		||||
        assertTrackerPositionEquals(createFilePosition(1, 1))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun advanceOneLine_ReturnsCorrectPosition() {
 | 
			
		||||
    fun `advancing one line returns correct position`() {
 | 
			
		||||
        trackerUnderTest.incrementLine()
 | 
			
		||||
 | 
			
		||||
        assertTrackerPositionEquals(createFilePosition(2, 0))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun advanceOneLine_ResetsColumn() {
 | 
			
		||||
    fun `advancing one line resets column number`() {
 | 
			
		||||
        trackerUnderTest.incrementColumn()
 | 
			
		||||
        trackerUnderTest.incrementLine()
 | 
			
		||||
 | 
			
		||||
        assertTrackerPositionEquals(createFilePosition(2, 0))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,381 +0,0 @@
 | 
			
		||||
package parser;
 | 
			
		||||
 | 
			
		||||
import error.LispException;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import scanner.LispScanner.UnterminatedStringException;
 | 
			
		||||
import stream.UncheckedIOException;
 | 
			
		||||
import token.Eof.EofEncounteredException;
 | 
			
		||||
import token.RightParenthesis.StartsWithRightParenthesisException;
 | 
			
		||||
import token.TokenFactory.BadCharacterException;
 | 
			
		||||
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
 | 
			
		||||
import static error.Severity.ERROR;
 | 
			
		||||
import static org.junit.Assert.assertEquals;
 | 
			
		||||
import static org.junit.Assert.assertFalse;
 | 
			
		||||
import static org.junit.Assert.assertNotNull;
 | 
			
		||||
import static org.junit.Assert.assertTrue;
 | 
			
		||||
import static org.junit.Assert.fail;
 | 
			
		||||
import static testutil.TestUtilities.createIOExceptionThrowingInputStream;
 | 
			
		||||
import static testutil.TestUtilities.createInputStreamFromString;
 | 
			
		||||
import static testutil.TypeAssertions.assertAtSignExpression;
 | 
			
		||||
import static testutil.TypeAssertions.assertBackTickExpression;
 | 
			
		||||
import static testutil.TypeAssertions.assertCommaExpression;
 | 
			
		||||
import static testutil.TypeAssertions.assertList;
 | 
			
		||||
import static testutil.TypeAssertions.assertNil;
 | 
			
		||||
import static testutil.TypeAssertions.assertNumber;
 | 
			
		||||
import static testutil.TypeAssertions.assertString;
 | 
			
		||||
import static testutil.TypeAssertions.assertSymbol;
 | 
			
		||||
 | 
			
		||||
public class LispParserTest {
 | 
			
		||||
 | 
			
		||||
    private LispParser createLispParser(String input) {
 | 
			
		||||
        InputStream stringInputStream = createInputStreamFromString(input);
 | 
			
		||||
        return new LispParser(stringInputStream, "testFile");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private LispParser createIOExceptionThrowingLispParser() {
 | 
			
		||||
        InputStream stringInputStream = createIOExceptionThrowingInputStream();
 | 
			
		||||
        return new LispParser(stringInputStream, "testFile");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void eofMethod_ReturnsTrueWithNoInput() {
 | 
			
		||||
        String input = "";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        assertTrue(parser.isEof());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void eofMethod_ReturnsFalseWithSomeInput() {
 | 
			
		||||
        String input = "abc";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        assertFalse(parser.isEof());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void eofMethod_ReturnsTrueAfterSomeInput() {
 | 
			
		||||
        String input = "(yyz 9 9 9)";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        parser.getNextSExpression();
 | 
			
		||||
        assertTrue(parser.isEof());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void eofMethod_ReturnsFalseAfterMultipleExpressions() {
 | 
			
		||||
        String input = "()()()";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        assertFalse(parser.isEof());
 | 
			
		||||
        parser.getNextSExpression();
 | 
			
		||||
        assertFalse(parser.isEof());
 | 
			
		||||
        parser.getNextSExpression();
 | 
			
		||||
        assertFalse(parser.isEof());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void eofMethod_ReturnsTrueAfterMultipleExpressions() {
 | 
			
		||||
        String input = "()()()";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        assertFalse(parser.isEof());
 | 
			
		||||
        parser.getNextSExpression();
 | 
			
		||||
        assertFalse(parser.isEof());
 | 
			
		||||
        parser.getNextSExpression();
 | 
			
		||||
        assertFalse(parser.isEof());
 | 
			
		||||
        parser.getNextSExpression();
 | 
			
		||||
        assertTrue(parser.isEof());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void givenNil_CreatesCorrectSExpression() {
 | 
			
		||||
        String input = "()";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        assertNil(parser.getNextSExpression());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void givenNumber_CreatesCorrectSExpression() {
 | 
			
		||||
        String input = "12";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        assertNumber(parser.getNextSExpression());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void givenIdentifier_CreatesCorrectSExpression() {
 | 
			
		||||
        String input = "identifier1";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        assertSymbol(parser.getNextSExpression());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void givenString_CreatesCorrectSExpression() {
 | 
			
		||||
        String input = "\"string\"";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        assertString(parser.getNextSExpression());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void givenList_CreatesCorrectSExpression() {
 | 
			
		||||
        String input = "(1 2)";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        assertList(parser.getNextSExpression());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void givenQuotedIdentifier_CreatesCorrectSExpression() {
 | 
			
		||||
        String input = "'quoted";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        assertList(parser.getNextSExpression());
 | 
			
		||||
        assertTrue(parser.isEof());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void givenComplexList_CreatesCorrectSExpression() {
 | 
			
		||||
        String input = "(defun f (x) \n (print \n (list \"x is \" x) \n ) \n )";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        assertList(parser.getNextSExpression());
 | 
			
		||||
        assertTrue(parser.isEof());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void givenMultipleComplexLists_CreatesCorrectSExpressions() {
 | 
			
		||||
        String input = "(defun f (x) \n (print \n (list \"x is \" x) \n ) \n )"
 | 
			
		||||
                       + "(defun f (x) \n (print \n (list \"x is \" x) \n ) \n )";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        assertList(parser.getNextSExpression());
 | 
			
		||||
        assertList(parser.getNextSExpression());
 | 
			
		||||
        assertTrue(parser.isEof());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void givenMultipleExpressions_CreatesCorrectSExpressions() {
 | 
			
		||||
        String input = "(setq x 2) x \"hi\" () 29";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        assertList(parser.getNextSExpression());
 | 
			
		||||
        assertSymbol(parser.getNextSExpression());
 | 
			
		||||
        assertString(parser.getNextSExpression());
 | 
			
		||||
        assertNil(parser.getNextSExpression());
 | 
			
		||||
        assertNumber(parser.getNextSExpression());
 | 
			
		||||
        assertTrue(parser.isEof());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void givenNil_CreatesCorrectSExpressionAfterEofCalls() {
 | 
			
		||||
        String input = "()";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        parser.isEof();
 | 
			
		||||
        parser.isEof();
 | 
			
		||||
 | 
			
		||||
        assertNil(parser.getNextSExpression());
 | 
			
		||||
        assertTrue(parser.isEof());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test(expected = BadCharacterException.class)
 | 
			
		||||
    public void givenBadToken_ThrowsException() {
 | 
			
		||||
        String input = "[";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        parser.getNextSExpression();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void givenBadToken_ExceptionHasCorrectAttributes() {
 | 
			
		||||
        String input = "[";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            parser.getNextSExpression();
 | 
			
		||||
        } catch (BadCharacterException e) {
 | 
			
		||||
            String message = e.getMessage();
 | 
			
		||||
 | 
			
		||||
            assertEquals(ERROR, e.getSeverity());
 | 
			
		||||
            assertNotNull(message);
 | 
			
		||||
            assertTrue(message.length() > 0);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test(expected = UnterminatedStringException.class)
 | 
			
		||||
    public void givenUnterminatedString_ThrowsException() {
 | 
			
		||||
        String input = "\"string";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        parser.getNextSExpression();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test(expected = EofEncounteredException.class)
 | 
			
		||||
    public void givenUnterminatedList_ThrowsException() {
 | 
			
		||||
        String input = "(bad list";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        parser.getNextSExpression();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void givenUnterminatedList_ExceptionHasCorrectAttributes() {
 | 
			
		||||
        String input = "(bad list";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            parser.getNextSExpression();
 | 
			
		||||
        } catch (EofEncounteredException e) {
 | 
			
		||||
            String message = e.getMessage();
 | 
			
		||||
 | 
			
		||||
            assertEquals(ERROR, e.getSeverity());
 | 
			
		||||
            assertNotNull(message);
 | 
			
		||||
            assertTrue(message.length() > 0);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test(expected = StartsWithRightParenthesisException.class)
 | 
			
		||||
    public void givenUnmatchedRightParenthesis_ThrowsException() {
 | 
			
		||||
        String input = ")";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        parser.getNextSExpression();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void givenUnmatchedRightParenthesis_ExceptionHasCorrectAttributes() {
 | 
			
		||||
        String input = ")";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            parser.getNextSExpression();
 | 
			
		||||
        } catch (StartsWithRightParenthesisException e) {
 | 
			
		||||
            String message = e.getMessage();
 | 
			
		||||
 | 
			
		||||
            assertEquals(ERROR, e.getSeverity());
 | 
			
		||||
            assertNotNull(message);
 | 
			
		||||
            assertTrue(message.length() > 0);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test(expected = BadCharacterException.class)
 | 
			
		||||
    public void givenBadCharacter_ThrowsExceptionAfterEofCalled() {
 | 
			
		||||
        String input = "[";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            parser.isEof();
 | 
			
		||||
        } catch (LispException e) {
 | 
			
		||||
            fail("Exception thrown too early");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        parser.getNextSExpression();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test(expected = BadCharacterException.class)
 | 
			
		||||
    public void givenBadCharacterAfterValidToken_ThrowsExceptionAtTheCorrectTime() {
 | 
			
		||||
        String input = "id[";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            parser.getNextSExpression();
 | 
			
		||||
            parser.isEof();
 | 
			
		||||
        } catch (LispException e) {
 | 
			
		||||
            fail("Exception thrown too early");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        parser.getNextSExpression();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void afterException_ReturnsEofCorrectly() {
 | 
			
		||||
        String input = "id[";
 | 
			
		||||
        LispParser parser = createLispParser(input);
 | 
			
		||||
        parser.getNextSExpression();
 | 
			
		||||
        parser.isEof();
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            parser.getNextSExpression();
 | 
			
		||||
            fail("Expected LispException");
 | 
			
		||||
        } catch (LispException e) {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        assertTrue(parser.isEof());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test(expected = UncheckedIOException.class)
 | 
			
		||||
    public void handlesIOExceptionCorrectly() {
 | 
			
		||||
        LispParser parser = createIOExceptionThrowingLispParser();
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            parser.isEof();
 | 
			
		||||
        } catch (LispException e) {
 | 
			
		||||
            fail("Exception thrown too early");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										376
									
								
								src/test/kotlin/parser/LispParserTest.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										376
									
								
								src/test/kotlin/parser/LispParserTest.kt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,376 @@
 | 
			
		||||
package parser
 | 
			
		||||
 | 
			
		||||
import error.LispException
 | 
			
		||||
import error.Severity.ERROR
 | 
			
		||||
import org.assertj.core.api.Assertions.assertThat
 | 
			
		||||
import org.junit.jupiter.api.Assertions.assertThrows
 | 
			
		||||
import org.junit.jupiter.api.Assertions.fail
 | 
			
		||||
import org.junit.jupiter.api.Test
 | 
			
		||||
import org.junit.jupiter.api.TestInstance
 | 
			
		||||
import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS
 | 
			
		||||
import scanner.LispScanner.UnterminatedStringException
 | 
			
		||||
import stream.UncheckedIOException
 | 
			
		||||
import testutil.TestUtilities.createIOExceptionThrowingInputStream
 | 
			
		||||
import testutil.TestUtilities.createInputStreamFromString
 | 
			
		||||
import testutil.TypeAssertions.assertAtSignExpression
 | 
			
		||||
import testutil.TypeAssertions.assertBackTickExpression
 | 
			
		||||
import testutil.TypeAssertions.assertCommaExpression
 | 
			
		||||
import testutil.TypeAssertions.assertList
 | 
			
		||||
import testutil.TypeAssertions.assertNil
 | 
			
		||||
import testutil.TypeAssertions.assertNumber
 | 
			
		||||
import testutil.TypeAssertions.assertString
 | 
			
		||||
import testutil.TypeAssertions.assertSymbol
 | 
			
		||||
import token.Eof.EofEncounteredException
 | 
			
		||||
import token.RightParenthesis.StartsWithRightParenthesisException
 | 
			
		||||
import token.TokenFactory.BadCharacterException
 | 
			
		||||
 | 
			
		||||
@TestInstance(PER_CLASS)
 | 
			
		||||
class LispParserTest {
 | 
			
		||||
 | 
			
		||||
    private fun createLispParser(input: String): LispParser {
 | 
			
		||||
        val stringInputStream = createInputStreamFromString(input)
 | 
			
		||||
        return LispParser(stringInputStream, "testFile")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun createIOExceptionThrowingLispParser(): LispParser {
 | 
			
		||||
        val stringInputStream = createIOExceptionThrowingInputStream()
 | 
			
		||||
        return LispParser(stringInputStream, "testFile")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `EOF check is true with no input`() {
 | 
			
		||||
        val input = ""
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertThat(parser.isEof())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `EOF check is false after some input`() {
 | 
			
		||||
        val input = "abc"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertThat(parser.isEof()).isFalse()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `EOF check is true after some input`() {
 | 
			
		||||
        val input = "(yyz 9 9 9)"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        parser.nextSExpression()
 | 
			
		||||
        assertThat(parser.isEof())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `EOF check is false after multiple expressions`() {
 | 
			
		||||
        val input = "()()()"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertThat(parser.isEof()).isFalse()
 | 
			
		||||
        parser.nextSExpression()
 | 
			
		||||
        assertThat(parser.isEof()).isFalse()
 | 
			
		||||
        parser.nextSExpression()
 | 
			
		||||
        assertThat(parser.isEof()).isFalse()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `EOF check is true after multiple expressions`() {
 | 
			
		||||
        val input = "()()()"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertThat(parser.isEof()).isFalse()
 | 
			
		||||
        parser.nextSExpression()
 | 
			
		||||
        assertThat(parser.isEof()).isFalse()
 | 
			
		||||
        parser.nextSExpression()
 | 
			
		||||
        assertThat(parser.isEof()).isFalse()
 | 
			
		||||
        parser.nextSExpression()
 | 
			
		||||
        assertThat(parser.isEof()).isTrue()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `nil is parsed correctly`() {
 | 
			
		||||
        val input = "()"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertNil(parser.nextSExpression())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `number is parsed correctly`() {
 | 
			
		||||
        val input = "12"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertNumber(parser.nextSExpression())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `identifier is parsed correctly`() {
 | 
			
		||||
        val input = "identifier1"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertSymbol(parser.nextSExpression())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `string is parsed correctly`() {
 | 
			
		||||
        val input = "\"string\""
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertString(parser.nextSExpression())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `list is parsed correctly`() {
 | 
			
		||||
        val input = "(1 2)"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertList(parser.nextSExpression())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `quoted identifier is parsed correctly`() {
 | 
			
		||||
        val input = "'quoted"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertList(parser.nextSExpression())
 | 
			
		||||
        assertThat(parser.isEof()).isTrue()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `complex list is parsed correctly`() {
 | 
			
		||||
        val input = "(defun f (x) \n (print \n (list \"x is \" x) \n ) \n )"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertList(parser.nextSExpression())
 | 
			
		||||
        assertThat(parser.isEof()).isTrue()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `multiple complex lists are parsed correctly`() {
 | 
			
		||||
        val input = "(defun f (x) \n (print \n (list \"x is \" x) \n ) \n )" +
 | 
			
		||||
                "(defun f (x) \n (print \n (list \"x is \" x) \n ) \n )"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertList(parser.nextSExpression())
 | 
			
		||||
        assertList(parser.nextSExpression())
 | 
			
		||||
        assertThat(parser.isEof()).isTrue()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `multiple expressions are parsed correctly`() {
 | 
			
		||||
        val input = "(setq x 2) x \"hi\" () 29"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertList(parser.nextSExpression())
 | 
			
		||||
        assertSymbol(parser.nextSExpression())
 | 
			
		||||
        assertString(parser.nextSExpression())
 | 
			
		||||
        assertNil(parser.nextSExpression())
 | 
			
		||||
        assertNumber(parser.nextSExpression())
 | 
			
		||||
        assertThat(parser.isEof()).isTrue()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `nil is parsed correctly after EOF checks`() {
 | 
			
		||||
        val input = "()"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        parser.isEof()
 | 
			
		||||
        parser.isEof()
 | 
			
		||||
 | 
			
		||||
        assertNil(parser.nextSExpression())
 | 
			
		||||
        assertThat(parser.isEof()).isTrue()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `throws exception for a bad token`() {
 | 
			
		||||
        val input = "["
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertThrows(BadCharacterException::class.java) { parser.nextSExpression() }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `bad token exception is cool`() {
 | 
			
		||||
        val input = "["
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            parser.nextSExpression()
 | 
			
		||||
        } catch (e: BadCharacterException) {
 | 
			
		||||
            val message = e.message
 | 
			
		||||
 | 
			
		||||
            assertThat(message).isNotEmpty();
 | 
			
		||||
            assertThat(e.severity).isEqualTo(ERROR)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `throws exception for unterminated string`() {
 | 
			
		||||
        val input = "\"string"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertThrows(UnterminatedStringException::class.java) { parser.nextSExpression() }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `throws exception for unterminated list`() {
 | 
			
		||||
        val input = "(bad list"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertThrows(EofEncounteredException::class.java) { parser.nextSExpression() }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `unterminated list exception is cool`() {
 | 
			
		||||
        val input = "(bad list"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            parser.nextSExpression()
 | 
			
		||||
        } catch (e: EofEncounteredException) {
 | 
			
		||||
            val message = e.message
 | 
			
		||||
 | 
			
		||||
            assertThat(message).isNotEmpty()
 | 
			
		||||
            assertThat(e.severity).isEqualTo(ERROR)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `throws exception for unmatched right parenthesis`() {
 | 
			
		||||
        val input = ")"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertThrows(StartsWithRightParenthesisException::class.java) { parser.nextSExpression() }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `unmatched right parenthesis exception is cool`() {
 | 
			
		||||
        val input = ")"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            parser.nextSExpression()
 | 
			
		||||
        } catch (e: StartsWithRightParenthesisException) {
 | 
			
		||||
            val message = e.message
 | 
			
		||||
 | 
			
		||||
            assertThat(message).isNotEmpty()
 | 
			
		||||
            assertThat(e.severity).isEqualTo(ERROR)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `bad character throws exception after an EOF check`() {
 | 
			
		||||
        val input = "["
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            parser.isEof()
 | 
			
		||||
        } catch (e: LispException) {
 | 
			
		||||
            fail<Unit>("Exception thrown too early")
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        assertThrows(BadCharacterException::class.java) { parser.nextSExpression() }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `bad character throws exception at the correct time`() {
 | 
			
		||||
        val input = "id["
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            parser.nextSExpression()
 | 
			
		||||
            parser.isEof()
 | 
			
		||||
        } catch (e: LispException) {
 | 
			
		||||
            fail<Unit>("Exception thrown too early")
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        assertThrows(BadCharacterException::class.java) { parser.nextSExpression() }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `EOF is returned after an exception`() {
 | 
			
		||||
        val input = "id["
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
        parser.nextSExpression()
 | 
			
		||||
        parser.isEof()
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            parser.nextSExpression()
 | 
			
		||||
            fail<Unit>("Expected LispException")
 | 
			
		||||
        } catch (e: LispException) {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        assertThat(parser.isEof()).isTrue()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `IOException is handled correctly`() {
 | 
			
		||||
        val parser = createIOExceptionThrowingLispParser()
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            parser.isEof()
 | 
			
		||||
        } catch (e: LispException) {
 | 
			
		||||
            fail<Unit>("Exception thrown too early")
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        assertThrows(UncheckedIOException::class.java) { parser.nextSExpression() }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `back tick is parsed correctly`() {
 | 
			
		||||
        val input = "`(list ,a ,@b)"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertBackTickExpression(parser.nextSExpression())
 | 
			
		||||
        assertThat(parser.isEof()).isTrue()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `comma is parsed correctly`() {
 | 
			
		||||
        val input = ",a"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertCommaExpression(parser.nextSExpression())
 | 
			
		||||
        assertThat(parser.isEof()).isTrue()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `at sign is parsed correctly`() {
 | 
			
		||||
        val input = "@b"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertAtSignExpression(parser.nextSExpression())
 | 
			
		||||
        assertThat(parser.isEof()).isTrue()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `back tick is not part of an identifier`() {
 | 
			
		||||
        val input = "id`ab"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertSymbol(parser.nextSExpression())
 | 
			
		||||
        assertBackTickExpression(parser.nextSExpression())
 | 
			
		||||
        assertThat(parser.isEof()).isTrue()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `comma is not part of an identifier`() {
 | 
			
		||||
        val input = "id,ab"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertSymbol(parser.nextSExpression())
 | 
			
		||||
        assertCommaExpression(parser.nextSExpression())
 | 
			
		||||
        assertThat(parser.isEof()).isTrue()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `at sign is not part of an identifier`() {
 | 
			
		||||
        val input = "id@ab"
 | 
			
		||||
        val parser = createLispParser(input)
 | 
			
		||||
 | 
			
		||||
        assertSymbol(parser.nextSExpression())
 | 
			
		||||
        assertAtSignExpression(parser.nextSExpression())
 | 
			
		||||
        assertThat(parser.isEof()).isTrue()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -72,7 +72,7 @@ public final class TestUtilities {
 | 
			
		||||
    public static SExpression parseString(String input) {
 | 
			
		||||
        InputStream stringInputStream = TestUtilities.createInputStreamFromString(input);
 | 
			
		||||
 | 
			
		||||
        return new LispParser(stringInputStream, "testFile").getNextSExpression();
 | 
			
		||||
        return new LispParser(stringInputStream, "testFile").nextSExpression();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Cons makeList(SExpression... expressionList) {
 | 
			
		||||
 | 
			
		||||
@ -1,129 +0,0 @@
 | 
			
		||||
package testutil;
 | 
			
		||||
 | 
			
		||||
import sexpression.SExpression;
 | 
			
		||||
 | 
			
		||||
import static org.hamcrest.Matchers.is;
 | 
			
		||||
import static org.junit.Assert.assertThat;
 | 
			
		||||
import static sexpression.Nil.NIL;
 | 
			
		||||
import static sexpression.Symbol.T;
 | 
			
		||||
 | 
			
		||||
public final class TypeAssertions {
 | 
			
		||||
 | 
			
		||||
    public static void assertList(SExpression sExpression) {
 | 
			
		||||
        assertThat(sExpression.isAtom(), is(false));
 | 
			
		||||
        assertThat(sExpression.isCons(), is(true));
 | 
			
		||||
        assertThat(sExpression.isFunction(), is(false));
 | 
			
		||||
        assertThat(sExpression.isList(), is(true));
 | 
			
		||||
        assertThat(sExpression.isNull(), is(false));
 | 
			
		||||
        assertThat(sExpression.isNumber(), is(false));
 | 
			
		||||
        assertThat(sExpression.isString(), is(false));
 | 
			
		||||
        assertThat(sExpression.isSymbol(), is(false));
 | 
			
		||||
        assertThat(sExpression.isBackquote(), is(false));
 | 
			
		||||
        assertThat(sExpression.isComma(), is(false));
 | 
			
		||||
        assertThat(sExpression.isAtSign(), is(false));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void assertNil(SExpression sExpression) {
 | 
			
		||||
        assertThat(sExpression, is(NIL));
 | 
			
		||||
 | 
			
		||||
        assertThat(sExpression.isAtom(), is(true));
 | 
			
		||||
        assertThat(sExpression.isCons(), is(false));
 | 
			
		||||
        assertThat(sExpression.isFunction(), is(false));
 | 
			
		||||
        assertThat(sExpression.isList(), is(true));
 | 
			
		||||
        assertThat(sExpression.isNull(), is(true));
 | 
			
		||||
        assertThat(sExpression.isNumber(), is(false));
 | 
			
		||||
        assertThat(sExpression.isString(), is(false));
 | 
			
		||||
        assertThat(sExpression.isSymbol(), is(true));
 | 
			
		||||
        assertThat(sExpression.isBackquote(), is(false));
 | 
			
		||||
        assertThat(sExpression.isComma(), is(false));
 | 
			
		||||
        assertThat(sExpression.isAtSign(), is(false));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void assertNumber(SExpression sExpression) {
 | 
			
		||||
        assertThat(sExpression.isAtom(), is(true));
 | 
			
		||||
        assertThat(sExpression.isCons(), is(false));
 | 
			
		||||
        assertThat(sExpression.isFunction(), is(false));
 | 
			
		||||
        assertThat(sExpression.isList(), is(false));
 | 
			
		||||
        assertThat(sExpression.isNull(), is(false));
 | 
			
		||||
        assertThat(sExpression.isNumber(), is(true));
 | 
			
		||||
        assertThat(sExpression.isString(), is(false));
 | 
			
		||||
        assertThat(sExpression.isSymbol(), is(false));
 | 
			
		||||
        assertThat(sExpression.isBackquote(), is(false));
 | 
			
		||||
        assertThat(sExpression.isComma(), is(false));
 | 
			
		||||
        assertThat(sExpression.isAtSign(), is(false));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void assertString(SExpression sExpression) {
 | 
			
		||||
        assertThat(sExpression.isAtom(), is(true));
 | 
			
		||||
        assertThat(sExpression.isCons(), is(false));
 | 
			
		||||
        assertThat(sExpression.isFunction(), is(false));
 | 
			
		||||
        assertThat(sExpression.isList(), is(false));
 | 
			
		||||
        assertThat(sExpression.isNull(), is(false));
 | 
			
		||||
        assertThat(sExpression.isNumber(), is(false));
 | 
			
		||||
        assertThat(sExpression.isString(), is(true));
 | 
			
		||||
        assertThat(sExpression.isSymbol(), is(false));
 | 
			
		||||
        assertThat(sExpression.isBackquote(), is(false));
 | 
			
		||||
        assertThat(sExpression.isComma(), is(false));
 | 
			
		||||
        assertThat(sExpression.isAtSign(), is(false));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void assertSymbol(SExpression sExpression) {
 | 
			
		||||
        assertThat(sExpression.isAtom(), is(true));
 | 
			
		||||
        assertThat(sExpression.isCons(), is(false));
 | 
			
		||||
        assertThat(sExpression.isFunction(), is(false));
 | 
			
		||||
        assertThat(sExpression.isList(), is(false));
 | 
			
		||||
        assertThat(sExpression.isNull(), is(false));
 | 
			
		||||
        assertThat(sExpression.isNumber(), is(false));
 | 
			
		||||
        assertThat(sExpression.isString(), is(false));
 | 
			
		||||
        assertThat(sExpression.isSymbol(), is(true));
 | 
			
		||||
        assertThat(sExpression.isBackquote(), is(false));
 | 
			
		||||
        assertThat(sExpression.isComma(), is(false));
 | 
			
		||||
        assertThat(sExpression.isAtSign(), is(false));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void assertT(SExpression sExpression) {
 | 
			
		||||
        assertThat(sExpression, is(T));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void assertBackTickExpression(SExpression sExpression) {
 | 
			
		||||
        assertThat(sExpression.isAtom(), is(false));
 | 
			
		||||
        assertThat(sExpression.isCons(), is(false));
 | 
			
		||||
        assertThat(sExpression.isFunction(), is(false));
 | 
			
		||||
        assertThat(sExpression.isList(), is(false));
 | 
			
		||||
        assertThat(sExpression.isNull(), is(false));
 | 
			
		||||
        assertThat(sExpression.isNumber(), is(false));
 | 
			
		||||
        assertThat(sExpression.isString(), is(false));
 | 
			
		||||
        assertThat(sExpression.isSymbol(), is(false));
 | 
			
		||||
        assertThat(sExpression.isBackquote(), is(true));
 | 
			
		||||
        assertThat(sExpression.isComma(), is(false));
 | 
			
		||||
        assertThat(sExpression.isAtSign(), is(false));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void assertCommaExpression(SExpression sExpression) {
 | 
			
		||||
        assertThat(sExpression.isAtom(), is(false));
 | 
			
		||||
        assertThat(sExpression.isCons(), is(false));
 | 
			
		||||
        assertThat(sExpression.isFunction(), is(false));
 | 
			
		||||
        assertThat(sExpression.isList(), is(false));
 | 
			
		||||
        assertThat(sExpression.isNull(), is(false));
 | 
			
		||||
        assertThat(sExpression.isNumber(), is(false));
 | 
			
		||||
        assertThat(sExpression.isString(), is(false));
 | 
			
		||||
        assertThat(sExpression.isSymbol(), is(false));
 | 
			
		||||
        assertThat(sExpression.isBackquote(), is(false));
 | 
			
		||||
        assertThat(sExpression.isComma(), is(true));
 | 
			
		||||
        assertThat(sExpression.isAtSign(), is(false));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void assertAtSignExpression(SExpression sExpression) {
 | 
			
		||||
        assertThat(sExpression.isAtom(), is(false));
 | 
			
		||||
        assertThat(sExpression.isCons(), is(false));
 | 
			
		||||
        assertThat(sExpression.isFunction(), is(false));
 | 
			
		||||
        assertThat(sExpression.isList(), is(false));
 | 
			
		||||
        assertThat(sExpression.isNull(), is(false));
 | 
			
		||||
        assertThat(sExpression.isNumber(), is(false));
 | 
			
		||||
        assertThat(sExpression.isString(), is(false));
 | 
			
		||||
        assertThat(sExpression.isSymbol(), is(false));
 | 
			
		||||
        assertThat(sExpression.isBackquote(), is(false));
 | 
			
		||||
        assertThat(sExpression.isComma(), is(false));
 | 
			
		||||
        assertThat(sExpression.isAtSign(), is(true));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										136
									
								
								src/test/kotlin/testutil/TypeAssertions.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								src/test/kotlin/testutil/TypeAssertions.kt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,136 @@
 | 
			
		||||
package testutil
 | 
			
		||||
 | 
			
		||||
import org.assertj.core.api.Assertions.assertThat
 | 
			
		||||
import sexpression.Nil.NIL
 | 
			
		||||
import sexpression.SExpression
 | 
			
		||||
import sexpression.Symbol.T
 | 
			
		||||
 | 
			
		||||
object TypeAssertions {
 | 
			
		||||
 | 
			
		||||
    @JvmStatic()
 | 
			
		||||
    fun assertList(sExpression: SExpression) {
 | 
			
		||||
        assertThat(sExpression.isAtom).isFalse()
 | 
			
		||||
        assertThat(sExpression.isCons).isTrue()
 | 
			
		||||
        assertThat(sExpression.isFunction).isFalse()
 | 
			
		||||
        assertThat(sExpression.isList).isTrue()
 | 
			
		||||
        assertThat(sExpression.isNull).isFalse()
 | 
			
		||||
        assertThat(sExpression.isNumber).isFalse()
 | 
			
		||||
        assertThat(sExpression.isString).isFalse()
 | 
			
		||||
        assertThat(sExpression.isSymbol).isFalse()
 | 
			
		||||
        assertThat(sExpression.isBackquote).isFalse()
 | 
			
		||||
        assertThat(sExpression.isComma).isFalse()
 | 
			
		||||
        assertThat(sExpression.isAtSign).isFalse()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @JvmStatic()
 | 
			
		||||
    fun assertNil(sExpression: SExpression) {
 | 
			
		||||
        assertThat(sExpression).isEqualTo(NIL)
 | 
			
		||||
 | 
			
		||||
        assertThat(sExpression.isAtom).isTrue()
 | 
			
		||||
        assertThat(sExpression.isCons).isFalse()
 | 
			
		||||
        assertThat(sExpression.isFunction).isFalse()
 | 
			
		||||
        assertThat(sExpression.isList).isTrue()
 | 
			
		||||
        assertThat(sExpression.isNull).isTrue()
 | 
			
		||||
        assertThat(sExpression.isNumber).isFalse()
 | 
			
		||||
        assertThat(sExpression.isString).isFalse()
 | 
			
		||||
        assertThat(sExpression.isSymbol).isTrue()
 | 
			
		||||
        assertThat(sExpression.isBackquote).isFalse()
 | 
			
		||||
        assertThat(sExpression.isComma).isFalse()
 | 
			
		||||
        assertThat(sExpression.isAtSign).isFalse()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @JvmStatic()
 | 
			
		||||
    fun assertNumber(sExpression: SExpression) {
 | 
			
		||||
        assertThat(sExpression.isAtom).isTrue()
 | 
			
		||||
        assertThat(sExpression.isCons).isFalse()
 | 
			
		||||
        assertThat(sExpression.isFunction).isFalse()
 | 
			
		||||
        assertThat(sExpression.isList).isFalse()
 | 
			
		||||
        assertThat(sExpression.isNull).isFalse()
 | 
			
		||||
        assertThat(sExpression.isNumber).isTrue()
 | 
			
		||||
        assertThat(sExpression.isString).isFalse()
 | 
			
		||||
        assertThat(sExpression.isSymbol).isFalse()
 | 
			
		||||
        assertThat(sExpression.isBackquote).isFalse()
 | 
			
		||||
        assertThat(sExpression.isComma).isFalse()
 | 
			
		||||
        assertThat(sExpression.isAtSign).isFalse()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @JvmStatic()
 | 
			
		||||
    fun assertString(sExpression: SExpression) {
 | 
			
		||||
        assertThat(sExpression.isAtom).isTrue()
 | 
			
		||||
        assertThat(sExpression.isCons).isFalse()
 | 
			
		||||
        assertThat(sExpression.isFunction).isFalse()
 | 
			
		||||
        assertThat(sExpression.isList).isFalse()
 | 
			
		||||
        assertThat(sExpression.isNull).isFalse()
 | 
			
		||||
        assertThat(sExpression.isNumber).isFalse()
 | 
			
		||||
        assertThat(sExpression.isString).isTrue()
 | 
			
		||||
        assertThat(sExpression.isSymbol).isFalse()
 | 
			
		||||
        assertThat(sExpression.isBackquote).isFalse()
 | 
			
		||||
        assertThat(sExpression.isComma).isFalse()
 | 
			
		||||
        assertThat(sExpression.isAtSign).isFalse()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @JvmStatic()
 | 
			
		||||
    fun assertSymbol(sExpression: SExpression) {
 | 
			
		||||
        assertThat(sExpression.isAtom).isTrue()
 | 
			
		||||
        assertThat(sExpression.isCons).isFalse()
 | 
			
		||||
        assertThat(sExpression.isFunction).isFalse()
 | 
			
		||||
        assertThat(sExpression.isList).isFalse()
 | 
			
		||||
        assertThat(sExpression.isNull).isFalse()
 | 
			
		||||
        assertThat(sExpression.isNumber).isFalse()
 | 
			
		||||
        assertThat(sExpression.isString).isFalse()
 | 
			
		||||
        assertThat(sExpression.isSymbol).isTrue()
 | 
			
		||||
        assertThat(sExpression.isBackquote).isFalse()
 | 
			
		||||
        assertThat(sExpression.isComma).isFalse()
 | 
			
		||||
        assertThat(sExpression.isAtSign).isFalse()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @JvmStatic()
 | 
			
		||||
    fun assertT(sExpression: SExpression) {
 | 
			
		||||
        assertThat(sExpression).isEqualTo(T)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @JvmStatic()
 | 
			
		||||
    fun assertBackTickExpression(sExpression: SExpression) {
 | 
			
		||||
        assertThat(sExpression.isAtom).isFalse()
 | 
			
		||||
        assertThat(sExpression.isCons).isFalse()
 | 
			
		||||
        assertThat(sExpression.isFunction).isFalse()
 | 
			
		||||
        assertThat(sExpression.isList).isFalse()
 | 
			
		||||
        assertThat(sExpression.isNull).isFalse()
 | 
			
		||||
        assertThat(sExpression.isNumber).isFalse()
 | 
			
		||||
        assertThat(sExpression.isString).isFalse()
 | 
			
		||||
        assertThat(sExpression.isSymbol).isFalse()
 | 
			
		||||
        assertThat(sExpression.isBackquote).isTrue()
 | 
			
		||||
        assertThat(sExpression.isComma).isFalse()
 | 
			
		||||
        assertThat(sExpression.isAtSign).isFalse()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @JvmStatic()
 | 
			
		||||
    fun assertCommaExpression(sExpression: SExpression) {
 | 
			
		||||
        assertThat(sExpression.isAtom).isFalse()
 | 
			
		||||
        assertThat(sExpression.isCons).isFalse()
 | 
			
		||||
        assertThat(sExpression.isFunction).isFalse()
 | 
			
		||||
        assertThat(sExpression.isList).isFalse()
 | 
			
		||||
        assertThat(sExpression.isNull).isFalse()
 | 
			
		||||
        assertThat(sExpression.isNumber).isFalse()
 | 
			
		||||
        assertThat(sExpression.isString).isFalse()
 | 
			
		||||
        assertThat(sExpression.isSymbol).isFalse()
 | 
			
		||||
        assertThat(sExpression.isBackquote).isFalse()
 | 
			
		||||
        assertThat(sExpression.isComma).isTrue()
 | 
			
		||||
        assertThat(sExpression.isAtSign).isFalse()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @JvmStatic()
 | 
			
		||||
    fun assertAtSignExpression(sExpression: SExpression) {
 | 
			
		||||
        assertThat(sExpression.isAtom).isFalse()
 | 
			
		||||
        assertThat(sExpression.isCons).isFalse()
 | 
			
		||||
        assertThat(sExpression.isFunction).isFalse()
 | 
			
		||||
        assertThat(sExpression.isList).isFalse()
 | 
			
		||||
        assertThat(sExpression.isNull).isFalse()
 | 
			
		||||
        assertThat(sExpression.isNumber).isFalse()
 | 
			
		||||
        assertThat(sExpression.isString).isFalse()
 | 
			
		||||
        assertThat(sExpression.isSymbol).isFalse()
 | 
			
		||||
        assertThat(sExpression.isBackquote).isFalse()
 | 
			
		||||
        assertThat(sExpression.isComma).isFalse()
 | 
			
		||||
        assertThat(sExpression.isAtSign).isTrue()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user