Created a package for s-expressions and continued refactoring the parser

This commit is contained in:
Mike Cifelli 2016-12-14 13:09:41 -05:00
parent 10fdbf3b75
commit 930c8137df
44 changed files with 215 additions and 78 deletions

View File

@ -7,6 +7,9 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
/**
* <code>APPLY</code> represents the APPLY function in Lisp.

View File

@ -7,6 +7,10 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
/**
* <code>ATOM</code> represents the ATOM function in Lisp.

View File

@ -7,6 +7,9 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
/**
* <code>CAR</code> represents the CAR function in Lisp.

View File

@ -7,6 +7,9 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
/**
* <code>CDR</code> represents the CDR function in Lisp.

View File

@ -7,6 +7,9 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
/**
* <code>COND</code> represents the COND form in Lisp.

View File

@ -7,6 +7,9 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
/**
* <code>CONS</code> represents the CONS function in Lisp.

View File

@ -7,6 +7,10 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
import java.util.HashMap;
/**

View File

@ -7,6 +7,10 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.LispNumber;
import sexpression.SExpression;
import sexpression.Symbol;
/**
* <code>DIVIDE</code> represents the '/' function in Lisp.

View File

@ -7,6 +7,10 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
/**
* <code>EQ</code> represents the EQ function in Lisp.

View File

@ -7,6 +7,10 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
/**
* <code>EQUAL</code> represents the EQUAL function in Lisp.

View File

@ -7,6 +7,11 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.LispNumber;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
/**
* <code>EQUALSP</code> represents the '=' function in Lisp.

View File

@ -7,6 +7,11 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
import java.util.HashMap;
/**

View File

@ -1,6 +1,9 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
public class EXIT extends LispFunction {

View File

@ -7,6 +7,9 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
/**
* <code>FUNCALL</code> represents the FUNCALL function in Lisp.

View File

@ -7,6 +7,11 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.LispNumber;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
/**
* <code>GREATERP</code> represents the '&gt;' function in Lisp.

View File

@ -7,6 +7,9 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
/**
* <code>LAMBDA</code> represents the LAMBDA form in Lisp.

View File

@ -7,6 +7,10 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.LispNumber;
import sexpression.SExpression;
import sexpression.Symbol;
/**
* <code>LENGTH</code> represents the LENGTH function in Lisp.

View File

@ -7,6 +7,11 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.LispNumber;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
/**
* <code>LESSP</code> represents the '&lt;' function in Lisp.

View File

@ -7,6 +7,9 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
/**
* <code>LET</code> represents the LET form in Lisp.

View File

@ -7,6 +7,9 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
/**
* <code>LIST</code> represents the LIST function in Lisp.

View File

@ -7,6 +7,10 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
/**
* <code>LISTP</code> represents the LISTP function in Lisp.

View File

@ -7,6 +7,12 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.LispString;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
import java.io.*;
/**
@ -64,9 +70,9 @@ public class LOAD extends LispFunction {
}
// attempt to evaluate all the S-expressions contained in the file
while (! parser.eof()) {
while (! parser.isEof()) {
try {
SExpression sexpr = parser.getSExpr();
SExpression sexpr = parser.getNextSExpression();
EVAL.eval(sexpr);
} catch (RuntimeException e) {

View File

@ -7,6 +7,8 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
/**
* This class represents a Lisp FUNCTION in the PL-Lisp implementation.

View File

@ -7,6 +7,8 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
/**
* A <code>LispFunction</code> is an internal representation of a built-in

View File

@ -7,6 +7,10 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.LispNumber;
import sexpression.SExpression;
import sexpression.Symbol;
/**
* <code>MINUS</code> represents the '-' function in Lisp.

View File

@ -7,6 +7,9 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.LispNumber;
import sexpression.SExpression;
/**
* <code>MULTIPLY</code> represents the '*' function in Lisp.

View File

@ -7,6 +7,10 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
/**
* <code>NULL</code> represents the NULL function in Lisp.

View File

@ -7,6 +7,9 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.LispNumber;
import sexpression.SExpression;
/**
* <code>PLUS</code> represents the '+' function in Lisp.

View File

@ -7,6 +7,9 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
/**
* <code>PRINT</code> represents the PRINT function in Lisp.

View File

@ -7,6 +7,9 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
/**
* <code>QUOTE</code> represents the QUOTE form in Lisp.

View File

@ -7,6 +7,9 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
/**
* <code>SETF</code> represents the SETF form in Lisp.

View File

@ -7,6 +7,9 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
/**
* <code>SYMBOL_FUNCTION</code> represents the SYMBOL-FUNCTION function in

View File

@ -7,6 +7,8 @@
package eval;
import parser.*;
import sexpression.SExpression;
import java.util.HashMap;
/**

View File

@ -7,6 +7,10 @@
package eval;
import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
import java.util.ArrayList;
/**

View File

@ -7,6 +7,7 @@
package main;
import parser.*;
import sexpression.SExpression;
import eval.*;
import error.ErrorManager;
import error.LispException;
@ -62,9 +63,9 @@ public class LispInterpreter {
System.out.print(PROMPT);
}
while (! parser.eof()) {
while (! parser.isEof()) {
try {
SExpression sexpr = parser.getSExpr();
SExpression sexpr = parser.getNextSExpression();
String result = MessageFormat.format("{0}{1}{2}", ANSI_GREEN, EVAL.eval(sexpr), ANSI_RESET);
LispInterpreter.erasePrompt(interactive);

View File

@ -3,10 +3,9 @@ package parser;
import java.io.InputStream;
import error.LispException;
import parser.MalformedSExpressionException.EofEncounteredException;
import parser.MalformedSExpressionException.StartsWithRightParenthesisException;
import parser.MalformedSExpressionException.UnrecognizedTokenException;
import parser.MalformedSExpressionException.*;
import scanner.LispScanner;
import sexpression.*;
import token.Eof;
import token.Token;
@ -18,37 +17,37 @@ public class LispParser {
private LispScanner scanner;
private Token nextToken;
private boolean nextTokenStored;
private boolean isNextTokenStored;
public LispParser(InputStream inputStream, String fileName) {
scanner = new LispScanner(inputStream, fileName);
nextToken = null;
nextTokenStored = false;
isNextTokenStored = false;
}
public boolean eof() {
if (!nextTokenStored) {
try {
nextToken = scanner.getNextToken();
nextTokenStored = true;
} catch (LispException e) {
// this method should give the illusion of not actually reading
// a token, so we ignore any exceptions (they will be thrown
// the next time the 'getSExpr' method is called)
if (nextToken == null)
return false;
}
}
public boolean isEof() {
if (!isNextTokenStored)
storeNextToken();
return nextToken instanceof Eof;
}
public SExpression getSExpr() {
if (!nextTokenStored)
private void storeNextToken() {
try {
nextToken = scanner.getNextToken();
isNextTokenStored = true;
} catch (LispException e) {
// This method should give the illusion of not actually reading
// a token, so we ignore any exception. It will be thrown when we
// return the next sExpression.
}
}
public SExpression getNextSExpression() {
if (!isNextTokenStored)
nextToken = scanner.getNextToken();
else
nextTokenStored = false;
isNextTokenStored = false;
return sExpr();
}

View File

@ -4,7 +4,7 @@
* Assignment: Lisp Parser
*/
package parser;
package sexpression;
/**
* This class represents an ATOM in the PL-Lisp implementation.

View File

@ -4,7 +4,7 @@
* Assignment: Lisp Parser
*/
package parser;
package sexpression;
/**
* This class represents a Lisp CONS cell in the PL-Lisp implementation.

View File

@ -4,7 +4,7 @@
* Assignment: Lisp Parser
*/
package parser;
package sexpression;
/**
* This class represents a NUMBER in the PL-Lisp implementation.

View File

@ -4,7 +4,7 @@
* Assignment: Lisp Parser
*/
package parser;
package sexpression;
/**
* This class represents a STRING in the PL-Lisp implementation.

View File

@ -4,7 +4,7 @@
* Assignment: Lisp Parser
*/
package parser;
package sexpression;
/**
* This class represents NIL in the PL-Lisp implementation.

View File

@ -4,7 +4,7 @@
* Assignment: Lisp Parser
*/
package parser;
package sexpression;
/**
* This is the base class for memory in the PL-Lisp implementation.

View File

@ -4,7 +4,7 @@
* Assignment: Lisp Parser
*/
package parser;
package sexpression;
/**
* This class represents a SYMBOL in the PL-Lisp implementation.

View File

@ -7,6 +7,8 @@ import java.io.InputStream;
import org.junit.Test;
import error.LispException;
import sexpression.Nil;
import sexpression.SExpression;
import testutils.TestUtilities;
public class LispParserTester {
@ -79,7 +81,7 @@ public class LispParserTester {
String input = "";
LispParser parser = createLispParser(input);
assertTrue(parser.eof());
assertTrue(parser.isEof());
}
@Test
@ -87,40 +89,40 @@ public class LispParserTester {
String input = "abc";
LispParser parser = createLispParser(input);
assertFalse(parser.eof());
assertFalse(parser.isEof());
}
@Test
public void testEofMethod_ReturnsTrueAfterSomeInput() {
String input = "(yyz 9 9 9)";
LispParser parser = createLispParser(input);
parser.getSExpr();
parser.getNextSExpression();
assertTrue(parser.eof());
assertTrue(parser.isEof());
}
@Test
public void testEofMethod_ReturnsFalseAfterMultipleExpressions() {
String input = "()()()";
LispParser parser = createLispParser(input);
assertFalse(parser.eof());
parser.getSExpr();
assertFalse(parser.eof());
parser.getSExpr();
assertFalse(parser.eof());
assertFalse(parser.isEof());
parser.getNextSExpression();
assertFalse(parser.isEof());
parser.getNextSExpression();
assertFalse(parser.isEof());
}
@Test
public void testEofMethod_ReturnsTrueAfterMultipleExpressions() {
String input = "()()()";
LispParser parser = createLispParser(input);
assertFalse(parser.eof());
parser.getSExpr();
assertFalse(parser.eof());
parser.getSExpr();
assertFalse(parser.eof());
parser.getSExpr();
assertTrue(parser.eof());
assertFalse(parser.isEof());
parser.getNextSExpression();
assertFalse(parser.isEof());
parser.getNextSExpression();
assertFalse(parser.isEof());
parser.getNextSExpression();
assertTrue(parser.isEof());
}
@Test
@ -128,7 +130,7 @@ public class LispParserTester {
String input = "()";
LispParser parser = createLispParser(input);
assertNil(parser.getSExpr());
assertNil(parser.getNextSExpression());
}
@Test
@ -136,7 +138,7 @@ public class LispParserTester {
String input = "12";
LispParser parser = createLispParser(input);
assertNumber(parser.getSExpr());
assertNumber(parser.getNextSExpression());
}
@Test
@ -144,7 +146,7 @@ public class LispParserTester {
String input = "identifier1";
LispParser parser = createLispParser(input);
assertSymbol(parser.getSExpr());
assertSymbol(parser.getNextSExpression());
}
@Test
@ -152,7 +154,7 @@ public class LispParserTester {
String input = "\"string\"";
LispParser parser = createLispParser(input);
assertString(parser.getSExpr());
assertString(parser.getNextSExpression());
}
@Test
@ -160,7 +162,7 @@ public class LispParserTester {
String input = "(1 2)";
LispParser parser = createLispParser(input);
assertList(parser.getSExpr());
assertList(parser.getNextSExpression());
}
@Test
@ -168,8 +170,8 @@ public class LispParserTester {
String input = "'quoted";
LispParser parser = createLispParser(input);
assertList(parser.getSExpr());
assertTrue(parser.eof());
assertList(parser.getNextSExpression());
assertTrue(parser.isEof());
}
@Test
@ -177,8 +179,8 @@ public class LispParserTester {
String input = "(defun f (x) \n (print \n (list \"x is \" x) \n ) \n )";
LispParser parser = createLispParser(input);
assertList(parser.getSExpr());
assertTrue(parser.eof());
assertList(parser.getNextSExpression());
assertTrue(parser.isEof());
}
@Test
@ -186,12 +188,12 @@ public class LispParserTester {
String input = "(setf x 2) x \"hi\" () 29";
LispParser parser = createLispParser(input);
assertList(parser.getSExpr());
assertSymbol(parser.getSExpr());
assertString(parser.getSExpr());
assertNil(parser.getSExpr());
assertNumber(parser.getSExpr());
assertTrue(parser.eof());
assertList(parser.getNextSExpression());
assertSymbol(parser.getNextSExpression());
assertString(parser.getNextSExpression());
assertNil(parser.getNextSExpression());
assertNumber(parser.getNextSExpression());
assertTrue(parser.isEof());
}
@Test
@ -199,11 +201,11 @@ public class LispParserTester {
String input = "()";
LispParser parser = createLispParser(input);
parser.eof();
parser.eof();
parser.isEof();
parser.isEof();
assertNil(parser.getSExpr());
assertTrue(parser.eof());
assertNil(parser.getNextSExpression());
assertTrue(parser.isEof());
}
@Test(expected = LispException.class)
@ -211,7 +213,7 @@ public class LispParserTester {
String input = "[";
LispParser parser = createLispParser(input);
parser.getSExpr();
parser.getNextSExpression();
}
@Test(expected = LispException.class)
@ -219,7 +221,7 @@ public class LispParserTester {
String input = "\"string";
LispParser parser = createLispParser(input);
parser.getSExpr();
parser.getNextSExpression();
}
@Test(expected = LispException.class)
@ -227,7 +229,7 @@ public class LispParserTester {
String input = "(bad list";
LispParser parser = createLispParser(input);
parser.getSExpr();
parser.getNextSExpression();
}
@Test(expected = LispException.class)
@ -235,7 +237,7 @@ public class LispParserTester {
String input = ")";
LispParser parser = createLispParser(input);
parser.getSExpr();
parser.getNextSExpression();
}
@Test(expected = LispException.class)
@ -244,27 +246,42 @@ public class LispParserTester {
LispParser parser = createLispParser(input);
try {
parser.eof();
parser.isEof();
} catch (LispException e) {
fail("Exception thrown too early");
}
parser.getSExpr();
parser.getNextSExpression();
}
@Test(expected = LispException.class)
public void givenBadCharacterAfterValidToken_ThrowsExceptionAtTheCorrectTime() {
String input = "id[]";
String input = "id[";
LispParser parser = createLispParser(input);
try {
parser.getSExpr();
parser.eof();
parser.getNextSExpression();
parser.isEof();
} catch (LispException e) {
fail("Exception thrown too early");
}
parser.getSExpr();
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());
}
}