Mike Cifelli CIS 443 - Programming Languages Lisp Interpreter Design Document My implementation of LispScanner takes in an InputStream in its constructor that it will use to retrieve the Lisp tokens. It then creates a BufferedInputStream around this input stream so I can be sure that it will support the 'mark' and 'reset' methods (which the LispScanner requires to operate). A LispFilterStream is then created with this BufferedInputStream so I can retrieve all of the bytes from the original input stream without having to worry about dealing with Lisp comments. When the LispScanner looks for the next Lisp token to return it uses a switch statement to determine the type of the next token (or to skip over whitespace). In the case of an identifier or number the scanner has to keep accumulating characters until it sees one that can not be a part of the number or identifier. Once one is found it has obviously been read from the input stream and this is not desirable as it is not part of the current token. This is where I made use of the 'mark' and 'reset' methods in the scanner. I mark the position before I read each character and when one is found that is not part of the current token I reset the input stream to its last position before the token is returned. This effectively unreads the last character so the input stream is in the proper position for the scanner's next read. In the design of the LispParser I had some difficulty in implementing the 'eof' method. This was due to the fact that in order to determine if a LispScanner was at the end of the input stream you have to read in a token. However, I did not want this method to read in a token since this would normally be part of an S-expression. Unfortunately, this meant that I would not be able to detect the end-of-file token until the 'getSExpr' method read it in. This is too late since the 'eof' method is used to determine when to stop calling the 'getSExpr' method. My solution involved reading a token in the 'eof' method and then storing it in a variable. This would only be done once, until the token was used in the 'getSExpr' method. I also stored any exceptions that were thrown during the read so that the 'eof' method would not give the impression of having read in any tokens. Any exception thrown in the 'eof' method during the retrieval of a token is stored and thrown the next time the 'getSExpr' method is called. During the evaluation phase of the Lisp interpreter, I made use of the command pattern during function calls. By creating a LispFunction interface, I was able to place all of the built-in functions into a hash table mapping function names to the appropriate LispFunction. By looking up functions in this hash table, the proper function could be easily called during the evaluation of a list. FINAL NOTE: The function table is located in the EVAL class and the symbol table is located in the SETF class.