diff --git a/src/eval/LOAD.java b/src/eval/LOAD.java
index 4a94235..1ce3f57 100644
--- a/src/eval/LOAD.java
+++ b/src/eval/LOAD.java
@@ -72,10 +72,6 @@ public class LOAD extends LispFunction {
} catch (RuntimeException e) {
System.out.println("LOAD: " + e.getMessage());
- return Nil.getUniqueInstance();
- } catch (IOException e) {
- System.out.println("LOAD: " + e.getMessage());
-
return Nil.getUniqueInstance();
}
}
diff --git a/src/main/LispInterpreter.java b/src/main/LispInterpreter.java
index 154e1fe..abfbb26 100644
--- a/src/main/LispInterpreter.java
+++ b/src/main/LispInterpreter.java
@@ -9,6 +9,8 @@ package main;
import parser.*;
import eval.*;
import error.ErrorManager;
+import error.LispException;
+
import java.io.*;
import java.text.MessageFormat;
@@ -67,11 +69,12 @@ public class LispInterpreter {
LispInterpreter.erasePrompt(interactive);
System.out.println(result);
+ } catch (LispException e) {
+ LispInterpreter.erasePrompt(interactive);
+ ErrorManager.generateError(e);
} catch (RuntimeException e) {
LispInterpreter.erasePrompt(interactive);
- ErrorManager.generateError(e.getMessage(), 2);
- } catch (IOException e) {
- ErrorManager.generateError(e.getMessage(), ErrorManager.CRITICAL_LEVEL);
+ ErrorManager.generateError(e.getMessage(), 0);
}
if (interactive) {
diff --git a/src/parser/LispParser.java b/src/parser/LispParser.java
index f93e11a..ebd5be5 100644
--- a/src/parser/LispParser.java
+++ b/src/parser/LispParser.java
@@ -6,10 +6,10 @@
package parser;
-import scanner.*;
-import java.io.*;
+import java.io.InputStream;
import constructs.Token;
+import scanner.LispScanner;
/**
* A LispParser
converts a stream of bytes into internal
@@ -91,19 +91,12 @@ public class LispParser {
* @throws IOException
* Indicates that an I/O error has occurred.
*/
- public SExpression getSExpr() throws IOException {
+ public SExpression getSExpr() {
if (delayedException != null) {
// the 'eof' method has stored an exception for us to throw
// determine the type of the stored exception and throw it!
- if (delayedException instanceof IOException) {
- IOException e = (IOException) delayedException;
-
- // remove the exception from 'delayedException'
- delayedException = null;
-
- throw e;
- } else if (delayedException instanceof RuntimeException) {
+ if (delayedException instanceof RuntimeException) {
RuntimeException e = (RuntimeException) delayedException;
// remove the exception from 'delayedException'
@@ -136,7 +129,7 @@ public class LispParser {
// encountered in the underlying input stream.
// Throws: IOException - Indicates that an I/O error has occurred.
// Precondition: 'nextToken' is not null.
- private SExpression sExpr() throws IOException {
+ private SExpression sExpr() {
// determine the type of 'nextToken' and create the appropriate
// S-expression
switch (nextToken.getType()) {
@@ -174,7 +167,7 @@ public class LispParser {
// Returns: an S-expression that matches the rules given above
// Throws: IOException - Indicates that an I/O error has occurred.
// Precondition: 'scanner' is not null.
- private SExpression sExprTail() throws IOException {
+ private SExpression sExprTail() {
nextToken = scanner.getNextToken();
// determine the type of 'nextToken' and create the appropriate
diff --git a/src/scanner/LispScanner.java b/src/scanner/LispScanner.java
index 7a1b84e..ebc2910 100644
--- a/src/scanner/LispScanner.java
+++ b/src/scanner/LispScanner.java
@@ -83,7 +83,7 @@ public class LispScanner {
return retriever.retrieveToken();
}
- public class ComplexTokenTextRetriever {
+ private class ComplexTokenTextRetriever {
Function isPartOfToken;
StringBuilder text;
@@ -115,7 +115,7 @@ public class LispScanner {
addCharacterToToken();
- if (isStringToken() && isTerminatingDoubleQuote())
+ if (isTerminatingCharacter())
return text.toString();
previousCharacter = currentCharacter;
@@ -132,6 +132,10 @@ public class LispScanner {
positionTracker.incrementLine();
}
+ private boolean isTerminatingCharacter() {
+ return isStringToken() && isTerminatingDoubleQuote();
+ }
+
private boolean isStringToken() {
return firstCharacter == DOUBLE_QUOTE;
}
diff --git a/test/constructs/TokenFactoryTester.java b/test/constructs/TokenFactoryTester.java
new file mode 100644
index 0000000..38d25e1
--- /dev/null
+++ b/test/constructs/TokenFactoryTester.java
@@ -0,0 +1,70 @@
+package constructs;
+
+import static org.junit.Assert.*;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import file.FilePosition;
+
+public class TokenFactoryTester {
+
+ private TokenFactory tokenFactory;
+ private FilePosition testPosition;
+
+ @Before
+ public void setUp() throws Exception {
+ tokenFactory = new TokenFactoryImpl();
+ testPosition = new FilePosition("testFile");
+ testPosition.setLineNumber(0);
+ testPosition.setColumnNumber(0);
+ }
+
+ @Test
+ public void testEOFTokenCreation() {
+ assertEquals(Token.Type.EOF, tokenFactory.createEOFToken(testPosition).getType());
+ }
+
+ @Test
+ public void testLeftParenthesisCreation() {
+ String text = "(";
+ assertEquals(Token.Type.LEFT_PAREN, tokenFactory.createToken(text, testPosition).getType());
+ }
+
+ @Test
+ public void testRightParenthesisCreation() {
+ String text = ")";
+ assertEquals(Token.Type.RIGHT_PAREN, tokenFactory.createToken(text, testPosition).getType());
+ }
+
+ @Test
+ public void testQuoteMarkCreation() {
+ String text = "'";
+ assertEquals(Token.Type.QUOTE_MARK, tokenFactory.createToken(text, testPosition).getType());
+ }
+
+ @Test
+ public void testNumberCreation() {
+ String text = "987";
+ assertEquals(Token.Type.NUMBER, tokenFactory.createToken(text, testPosition).getType());
+ }
+
+ @Test
+ public void testIdentifierCreation() {
+ String text = "identifier";
+ assertEquals(Token.Type.IDENTIFIER, tokenFactory.createToken(text, testPosition).getType());
+ }
+
+ @Test
+ public void testStringCreation() {
+ String text = "\"string\"";
+ assertEquals(Token.Type.STRING, tokenFactory.createToken(text, testPosition).getType());
+ }
+
+ @Test(expected = TokenFactory.BadCharacterException.class)
+ public void testBadCharacter() {
+ String text = "[abc]";
+ tokenFactory.createToken(text, testPosition);
+ }
+
+}
diff --git a/test/scanner/LispScannerLineColumnTester.java b/test/scanner/LispScannerLineColumnTester.java
index fb922c9..7cc3c49 100644
--- a/test/scanner/LispScannerLineColumnTester.java
+++ b/test/scanner/LispScannerLineColumnTester.java
@@ -103,6 +103,14 @@ public class LispScannerLineColumnTester {
assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns);
}
+ @Test
+ public void givenCommentImmediatelyFollowingNumber_RecordsCorrectLocations() {
+ String input = "12;comment\n34";
+ LineColumn[] expectedLinesAndColumns = { LineColumn.create(1, 1), LineColumn.create(2, 1) };
+
+ assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns);
+ }
+
private void assertTokenLineAndColumnsMatch(String input, LineColumn[] expectedLineColumnList) {
InputStream stringInputStream = TestUtilities.createInputStreamFromString(input);
LispScanner lispScanner = new LispScanner(stringInputStream, "stringInputStream");
diff --git a/test/scanner/LispScannerTextTester.java b/test/scanner/LispScannerTextTester.java
index 7887df5..16f8138 100644
--- a/test/scanner/LispScannerTextTester.java
+++ b/test/scanner/LispScannerTextTester.java
@@ -32,11 +32,27 @@ public class LispScannerTextTester {
}
@Test
- public void givenEmptyStream_RecordsCorrectInputStreamName() {
+ public void givenEmptyStream_RecordsCorrectFileName() {
String input = "";
- String expectedInputStreamName = "testInputStream";
+ String expectedFileName = "testFileName";
- assertInputFileNameMatches(input, expectedInputStreamName);
+ assertInputFileNameMatches(input, expectedFileName);
+ }
+
+ @Test
+ public void givenNumberFollowedByComment_RecordsCorrectText() {
+ String input = "192837456;comment";
+ String expected = "192837456";
+
+ assertTokenTextMatches(input, expected);
+ }
+
+ @Test
+ public void givenIdentifiersWithCommentBetween_RecordsCorrectText() {
+ String input = "abc123;comment\nabc222";
+ String expected = "abc123";
+
+ assertTokenTextMatches(input, expected);
}
private void assertTokenTextMatches(String input, String expectedText) {
diff --git a/test/scanner/LispScannerTypeTester.java b/test/scanner/LispScannerTypeTester.java
index 5349f58..e514b18 100644
--- a/test/scanner/LispScannerTypeTester.java
+++ b/test/scanner/LispScannerTypeTester.java
@@ -30,6 +30,18 @@ public class LispScannerTypeTester {
assertTokenTypesMatch(input, expectedTypes);
}
+ @Test
+ public void givenBadCharacter_ExceptionContainsCorrectSeverity() {
+ String input = "abc\ndef[";
+ Token.Type[] expectedTypes = { Type.IDENTIFIER, Type.IDENTIFIER };
+
+ try {
+ assertTokenTypesMatch(input, expectedTypes);
+ } catch (TokenFactory.BadCharacterException e) {
+ assertTrue(e.getSeverity() < ErrorManager.CRITICAL_LEVEL);
+ }
+ }
+
@Test
public void givenNil_ReturnsCorrectTypes() {
String input = "()";