Implemented on-line help system, initial trace system, debug functions.
Rewrote REPL Added NIL and comments to parser. Added T as a predefined constant. Added HELP, TRACE, ENABLE-DEBUG-AST special form. Fixed variable evaluation (shouldn't automatically eval it's value)
This commit is contained in:
parent
943c91dedc
commit
dfc1234817
@ -6,4 +6,5 @@ package edu.utexas.cs345.jdblisp;
|
||||
*/
|
||||
public interface FormEntry {
|
||||
SExp call(SymbolTable table, Seq arguments) throws LispException;
|
||||
HelpTopic helpinfo();
|
||||
}
|
||||
|
56
src/edu/utexas/cs345/jdblisp/FormHelpTopic.java
Normal file
56
src/edu/utexas/cs345/jdblisp/FormHelpTopic.java
Normal file
@ -0,0 +1,56 @@
|
||||
package edu.utexas.cs345.jdblisp;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* FormHelpTopic
|
||||
* @author Jonathan Bernard (jdbernard@gmail.com)
|
||||
*/
|
||||
public class FormHelpTopic extends HelpTopic {
|
||||
|
||||
protected final String invokation;
|
||||
protected final String[][] parameters;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
public FormHelpTopic(String operatorName, String shortDescription,
|
||||
String invokation, String longDescription, String... parameterDefinitions) {
|
||||
super(operatorName, shortDescription, longDescription);
|
||||
this.invokation = invokation;
|
||||
|
||||
assert (parameterDefinitions.length % 2 == 0);
|
||||
|
||||
ArrayList<String[]> paramDefs = new ArrayList<String[]>();
|
||||
for (int i = 0; i < parameterDefinitions.length; i+=2) {
|
||||
paramDefs.add(new String[] {
|
||||
parameterDefinitions[i],
|
||||
parameterDefinitions[i+1] });
|
||||
}
|
||||
|
||||
parameters = paramDefs.toArray(new String[][] {});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(OutputStream os, int wrapWidth) {
|
||||
WrappedPrinter out = new WrappedPrinter(os, wrapWidth, true);
|
||||
|
||||
out.print(name + ": ");
|
||||
if (shortDescription != null)
|
||||
out.println(shortDescription, " ");
|
||||
out.println();
|
||||
out.println(invokation, " ");
|
||||
out.println();
|
||||
if (body != null) {
|
||||
out.println(body, " ");
|
||||
out.println();
|
||||
}
|
||||
|
||||
for (String[] param : parameters) {
|
||||
out.print(param[0] + "\t", " ");
|
||||
out.println(param[1], " ");
|
||||
}
|
||||
}
|
||||
}
|
@ -6,16 +6,52 @@ package edu.utexas.cs345.jdblisp;
|
||||
*/
|
||||
public class FunctionEntry implements FormEntry {
|
||||
|
||||
public final HelpTopic helpinfo;
|
||||
public final Symbol name;
|
||||
protected final Symbol[] parameters;
|
||||
protected final SExp body;
|
||||
|
||||
public FunctionEntry(Symbol[] parameters, SExp body) {
|
||||
protected boolean traceEnabled;
|
||||
|
||||
//private Logger traceLog = Logger.getLogger(getClass());
|
||||
|
||||
public FunctionEntry(Symbol name, Symbol[] parameters, SExp body) {
|
||||
|
||||
// build invocation help string
|
||||
String invokation = "(" + name.name;
|
||||
for (Symbol param : parameters) invokation += " <" + param.name + ">";
|
||||
invokation += ")";
|
||||
String bodyInfo = "Function body: " + body.toString();
|
||||
|
||||
// build help topic
|
||||
FormHelpTopic helpinfo = new FormHelpTopic(name.name, null, invokation, bodyInfo);
|
||||
|
||||
this.name = name;
|
||||
this.parameters = parameters;
|
||||
this.body = body;
|
||||
this.helpinfo = helpinfo;
|
||||
}
|
||||
|
||||
public FunctionEntry(Symbol name, Symbol[] parameters, SExp body,
|
||||
HelpTopic helpinfo) {
|
||||
this.name = name;
|
||||
this.parameters = parameters;
|
||||
this.body = body;
|
||||
this.helpinfo = helpinfo;
|
||||
}
|
||||
|
||||
public boolean isTraceEnabled() { return traceEnabled ;}
|
||||
|
||||
public void enableTrace(boolean enable) { this.traceEnabled = enable; }
|
||||
|
||||
public SExp call(SymbolTable symbolTable, Seq arguments) throws LispException {
|
||||
|
||||
String traceString = null;
|
||||
SExp evaluatedArg, retVal;
|
||||
|
||||
if (traceEnabled)
|
||||
traceString = "(" + name.name;
|
||||
|
||||
// bind arguments to parameters
|
||||
SymbolTable localScope = new SymbolTable(symbolTable);
|
||||
int i = 0;
|
||||
@ -27,7 +63,10 @@ public class FunctionEntry implements FormEntry {
|
||||
parameters.length, i);
|
||||
|
||||
// bind one arg to param
|
||||
localScope.bind(parameters[i], new VariableEntry(arguments.car.eval(symbolTable)));
|
||||
evaluatedArg = arguments.car.eval(symbolTable);
|
||||
localScope.bind(parameters[i], new VariableEntry(evaluatedArg));
|
||||
|
||||
if (traceEnabled) traceString += " " + evaluatedArg.toString();
|
||||
|
||||
arguments = arguments.cdr;
|
||||
++i;
|
||||
@ -38,6 +77,18 @@ public class FunctionEntry implements FormEntry {
|
||||
throw new InvalidArgumentQuantityException(parameters.length,
|
||||
(i + arguments.length()));
|
||||
|
||||
return body.eval(localScope);
|
||||
if (traceEnabled) traceString += ")";
|
||||
if (traceEnabled) System.out.println(traceString);
|
||||
|
||||
|
||||
retVal = body.eval(localScope);
|
||||
|
||||
if (traceEnabled)
|
||||
traceString = name.name + " returned " + retVal.toString();
|
||||
if (traceEnabled) System.out.println(traceString);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public HelpTopic helpinfo() { return helpinfo; }
|
||||
}
|
||||
|
120
src/edu/utexas/cs345/jdblisp/HelpTopic.java
Normal file
120
src/edu/utexas/cs345/jdblisp/HelpTopic.java
Normal file
@ -0,0 +1,120 @@
|
||||
package edu.utexas.cs345.jdblisp;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* HelpTopic
|
||||
* @author Jonathan Bernard (jdbernard@gmail.com)
|
||||
*/
|
||||
public class HelpTopic {
|
||||
|
||||
public static Map<String, HelpTopic> helpTopics;
|
||||
|
||||
protected final String name;
|
||||
protected final String shortDescription;
|
||||
protected final String body;
|
||||
|
||||
public HelpTopic(String name, String shortDescription, String body) {
|
||||
this.name = name;
|
||||
this.shortDescription = shortDescription;
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public void print(OutputStream os) { print(os, 79); }
|
||||
|
||||
public void print(OutputStream os, int wrapWidth) {
|
||||
WrappedPrinter out = new WrappedPrinter(os, wrapWidth, true);
|
||||
out.println(name);
|
||||
out.println(shortDescription, " ");
|
||||
out.println();
|
||||
out.println(body, " ");
|
||||
}
|
||||
|
||||
class WrappedPrinter {
|
||||
|
||||
private PrintWriter printer;
|
||||
private int wrapWidth;
|
||||
private int lastPrintedLineLength = 0;
|
||||
|
||||
public WrappedPrinter(OutputStream os, int wrapWidth,
|
||||
boolean autoflush) {
|
||||
this(new PrintWriter(os, autoflush), wrapWidth);
|
||||
}
|
||||
|
||||
public WrappedPrinter(PrintWriter pw, int wrapWidth) {
|
||||
this.printer = pw;
|
||||
this.wrapWidth = wrapWidth;
|
||||
}
|
||||
|
||||
public void print(String message) { print(message, ""); }
|
||||
|
||||
public void print(String message, String offset) {
|
||||
int lastSpaceIdx = 0;
|
||||
int curLineLength = 0;
|
||||
int lineStartIdx = 0;
|
||||
int i = 0;
|
||||
int actualWidth = wrapWidth - offset.length();
|
||||
|
||||
//message = message.replaceAll("[\n\r]", " ");
|
||||
|
||||
// print initial offset if this is the beginning of the line
|
||||
if (lastPrintedLineLength == 0) {
|
||||
printer.print(offset);
|
||||
curLineLength = offset.length();
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < message.length(); ++i) {
|
||||
|
||||
curLineLength++;
|
||||
if (message.charAt(i) == '\t') curLineLength += 7;
|
||||
|
||||
// line has overflowed the prescribed width
|
||||
if (curLineLength > actualWidth) {
|
||||
// print up to the last space before the overflow
|
||||
printer.println(message.substring(lineStartIdx, lastSpaceIdx));
|
||||
|
||||
// pick up the next line after said space
|
||||
lineStartIdx = lastSpaceIdx + 1;
|
||||
i = lastSpaceIdx;
|
||||
curLineLength = 0;
|
||||
|
||||
// print initial offset if there is still more to print
|
||||
if (lineStartIdx < message.length()) {
|
||||
printer.print(offset);
|
||||
curLineLength = offset.length();
|
||||
}
|
||||
}
|
||||
|
||||
// see whitespace, update last space index
|
||||
if (Character.isWhitespace(message.charAt(i))) lastSpaceIdx = i;
|
||||
}
|
||||
|
||||
// any left over, it will fit on one line
|
||||
if (i - lineStartIdx > 1) {
|
||||
String lastLine = message.substring(lineStartIdx);
|
||||
printer.print(lastLine);
|
||||
curLineLength += lastLine.length();
|
||||
}
|
||||
|
||||
// save back the new position
|
||||
lastPrintedLineLength = curLineLength;
|
||||
|
||||
}
|
||||
|
||||
public void println() { println("", ""); }
|
||||
|
||||
public void println(String message) { println(message, ""); }
|
||||
|
||||
public void println(String message, String offset) {
|
||||
|
||||
print(message, offset);
|
||||
printer.println();
|
||||
lastPrintedLineLength = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
117
src/edu/utexas/cs345/jdblisp/LISPRuntime.java
Executable file
117
src/edu/utexas/cs345/jdblisp/LISPRuntime.java
Executable file
@ -0,0 +1,117 @@
|
||||
package edu.utexas.cs345.jdblisp;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Scanner;
|
||||
|
||||
import edu.utexas.cs345.jdblisp.parser.Parser;
|
||||
import edu.utexas.cs345.jdblisp.parser.ParseException;
|
||||
|
||||
/**
|
||||
* @author Jonathan Bernard (jdbernard@gmail.com)
|
||||
*/
|
||||
public class LISPRuntime {
|
||||
|
||||
public static final String VERSION = "0.1.0";
|
||||
|
||||
public SymbolTable globalSymbolTable;
|
||||
|
||||
private Parser parser;
|
||||
|
||||
private boolean interactive = true;
|
||||
|
||||
boolean dumpAST = false;
|
||||
|
||||
private OutputStream os;
|
||||
|
||||
public LISPRuntime() {
|
||||
this(true);
|
||||
}
|
||||
|
||||
public LISPRuntime(boolean interactive) {
|
||||
this.interactive = interactive;
|
||||
Parser parser = new Parser(new ByteArrayInputStream(new byte[]{}));
|
||||
globalSymbolTable = new SymbolTable();
|
||||
SpecialFormEntry.defineSpecialForms(this);
|
||||
globalSymbolTable.bind(new Symbol("T"), new VariableEntry(SExp.T));
|
||||
}
|
||||
|
||||
// TODO: is this needed?
|
||||
// public void setInteractive(boolean interactive) { this.interactive = interactive; }
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
// create the LISP environment
|
||||
LISPRuntime lisp = new LISPRuntime();
|
||||
|
||||
// print welcome message
|
||||
System.out.println("Welcome to JDB-Lisp v" + VERSION + ", a subset of Common Lisp.");;
|
||||
System.out.println("On-line help is available via the (help funcname) command.");
|
||||
// parse command-line arguments (treat non-options as input files)
|
||||
// TODO: replace with Apache Commons CLI
|
||||
for (String arg : args) {
|
||||
System.out.println("Loading file '" + arg + "...");
|
||||
lisp.interactive = false;
|
||||
lisp.repl(new FileInputStream(arg), System.out);
|
||||
}
|
||||
|
||||
// drop into interactive mode
|
||||
lisp.interactive = true;
|
||||
lisp.repl(System.in, System.out);
|
||||
}
|
||||
|
||||
public void repl(InputStream is, OutputStream os) throws IOException {
|
||||
|
||||
// wrap output in a more friendly object
|
||||
this.os = os;
|
||||
PrintWriter out = new PrintWriter(os,true);
|
||||
|
||||
parser.ReInit(is);
|
||||
SExp sexp;
|
||||
while (true) {
|
||||
|
||||
// print prompt if applicable
|
||||
if (interactive) {
|
||||
out.print("> ");
|
||||
out.flush();
|
||||
}
|
||||
|
||||
try { sexp = parser.sexp(); }
|
||||
catch (ParseException pe) {
|
||||
|
||||
// using the available call to check if the stream is open.
|
||||
try { is.available(); } // if an exception is
|
||||
catch (IOException ioe) { break; } // then it is closed
|
||||
|
||||
out.println(pe.getLocalizedMessage());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dumpAST) {
|
||||
out.println("ABSTRACT SYNTAX:");
|
||||
out.println(sexp.display(" "));
|
||||
out.println("----------------");
|
||||
}
|
||||
|
||||
if (interactive) {
|
||||
try {
|
||||
SExp result = sexp.eval(globalSymbolTable);
|
||||
out.println(result == null ? "NIL" : result.toString());
|
||||
} catch (LispException le) {
|
||||
out.println(le.getLocalizedMessage());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
out.println("\nLeaving JDB-LISP");
|
||||
}
|
||||
|
||||
OutputStream getOutputStream() { return os; }
|
||||
|
||||
}
|
@ -13,6 +13,10 @@ public class List implements SExp {
|
||||
|
||||
/** {@inheritdoc}*/
|
||||
public SExp eval(SymbolTable table) throws LispException {
|
||||
|
||||
// null is NIL
|
||||
if (seq == null) return null;
|
||||
|
||||
// if the car of the sequence is a symbol,
|
||||
if (seq.car instanceof Symbol) {
|
||||
// then that symbol is the name of an operator
|
||||
|
@ -21,11 +21,13 @@ SKIP : /* WHITE SPACE */
|
||||
| "\t"
|
||||
| "\n"
|
||||
| "\n\r"
|
||||
| ";.*$"
|
||||
}
|
||||
|
||||
TOKEN : /* PUNCTUATION */
|
||||
{ < LPAREN: "(" >
|
||||
| < RPAREN: ")" >
|
||||
| < NIL: (["N","n"]["I","i"]["L","l"])>
|
||||
|
||||
}
|
||||
|
||||
@ -56,6 +58,7 @@ List list():
|
||||
{ Seq s;
|
||||
}
|
||||
{ <LPAREN> s = seq() <RPAREN> { return new List(s); }
|
||||
| <NIL> { return new List(null); } // allow NIL to be shorthand for ()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,4 +15,15 @@ public interface SExp {
|
||||
|
||||
String display(String offset);
|
||||
|
||||
public static final SExp T = new SExp() {
|
||||
public SExp eval(SymbolTable table) { return this; }
|
||||
public String display(String offset) { return offset + "T\n"; }
|
||||
public String toString() { return "T"; }
|
||||
};
|
||||
|
||||
/*public static final SExp NIL = new SExp() {
|
||||
SExp eval(SymbolTable table) { return this; }
|
||||
String display(String offset) { return offset + "NIL\n"; }
|
||||
String toString() { return "NIL"; }
|
||||
};*/
|
||||
}
|
||||
|
@ -49,6 +49,6 @@ public class Seq implements SExp {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return car.toString() + (cdr == null ? "" : cdr.toString());
|
||||
return car.toString() + (cdr == null ? "" : " " + cdr.toString());
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package edu.utexas.cs345.jdblisp;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
@ -8,17 +9,103 @@ import java.util.ArrayList;
|
||||
*/
|
||||
public abstract class SpecialFormEntry implements FormEntry {
|
||||
|
||||
protected Lisp environment;
|
||||
public final HelpTopic helpinfo;
|
||||
|
||||
public SpecialFormEntry(Lisp environment) { this.environment = environment; }
|
||||
protected LISPRuntime environment;
|
||||
|
||||
public abstract SExp call(SymbolTable symbolTable, Seq arguments) throws LispException;
|
||||
public SpecialFormEntry(LISPRuntime environment, HelpTopic helpinfo) {
|
||||
this.environment = environment;
|
||||
this.helpinfo = helpinfo;
|
||||
}
|
||||
|
||||
public HelpTopic helpinfo() { return helpinfo; }
|
||||
|
||||
public static void defineSpecialForms(Lisp environment) {
|
||||
public abstract SExp call(SymbolTable symbolTable, Seq arguments)
|
||||
throws LispException;
|
||||
|
||||
SpecialFormEntry DEFUN = new SpecialFormEntry(environment) {
|
||||
public SExp call(SymbolTable symbolTable, Seq arguments) throws LispException {
|
||||
// ------------------------
|
||||
// SPECIAL FORMS DEFINITION
|
||||
// ------------------------
|
||||
|
||||
// JDB-Lisp includes on-line help for all of its special forms. See the
|
||||
// help strings for documentation of the individual special forms.
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
public static void defineSpecialForms(LISPRuntime environment) {
|
||||
|
||||
// ----
|
||||
// HELP
|
||||
// ----
|
||||
|
||||
SpecialFormEntry HELP = new SpecialFormEntry(
|
||||
environment,
|
||||
new FormHelpTopic("HELP",
|
||||
"Display online help information for a topic.",
|
||||
"(help <topic>)",
|
||||
null,
|
||||
"topic",
|
||||
"either a string representing the topic to lookup or a symbol"))
|
||||
{
|
||||
public SExp call(SymbolTable symbolTable, Seq arguments)
|
||||
throws LispException {
|
||||
|
||||
HelpTopic topic = null;
|
||||
|
||||
// no arguments: print help for HELP
|
||||
if (arguments == null)
|
||||
return this.call(symbolTable,
|
||||
new Seq(new Symbol("HELP"), null));
|
||||
|
||||
// too many arguments
|
||||
if (arguments.length() > 1)
|
||||
throw new InvalidArgumentQuantityException(1,
|
||||
arguments.length());
|
||||
|
||||
// try to find the topic or function help
|
||||
if (arguments.car instanceof Str) {
|
||||
topic = HelpTopic.helpTopics.get(
|
||||
((Str) arguments.car).value);
|
||||
} else if (arguments.car instanceof Symbol) {
|
||||
try {
|
||||
FormEntry fe = symbolTable.lookupFunction(
|
||||
(Symbol) arguments.car);
|
||||
topic = fe.helpinfo();
|
||||
} catch (LispException le) { topic = null; }
|
||||
}
|
||||
|
||||
// no topic found
|
||||
if (topic == null) {
|
||||
new PrintWriter(environment.getOutputStream(), true)
|
||||
.println(
|
||||
"No help information found for topic '"
|
||||
+ arguments.car.toString() + "'.");
|
||||
return null;
|
||||
}
|
||||
|
||||
topic.print(environment.getOutputStream());
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// -----
|
||||
// DEFUN
|
||||
// -----
|
||||
|
||||
SpecialFormEntry DEFUN = new SpecialFormEntry(
|
||||
environment,
|
||||
new FormHelpTopic("DEFUN", "Define a (global) function.",
|
||||
"(defun <name> (<param-list>) <func-body>)",
|
||||
"Create a function binding. This will replace any existing binding.",
|
||||
"name", "the symbol to bind to the function definition.",
|
||||
"param-list", "a list of symbols that will be bound in the "
|
||||
+ "function scope to the arguments passed to the function.",
|
||||
"func-body", "an sexpression evaluated when the function is "
|
||||
+ "called."))
|
||||
{
|
||||
public SExp call(SymbolTable symbolTable, Seq arguments)
|
||||
throws LispException {
|
||||
|
||||
Symbol functionName;
|
||||
ArrayList<Symbol> parameters = new ArrayList<Symbol>();
|
||||
@ -27,7 +114,7 @@ public abstract class SpecialFormEntry implements FormEntry {
|
||||
// TODO: check to see if a function for this symbol exists
|
||||
// and warn if so
|
||||
|
||||
if (arguments.length() != 3)
|
||||
if (arguments == null || arguments.length() != 3)
|
||||
new InvalidArgumentQuantityException(3, arguments.length());
|
||||
|
||||
// first argument: Symbol for function name
|
||||
@ -62,14 +149,31 @@ public abstract class SpecialFormEntry implements FormEntry {
|
||||
body = arguments.car;
|
||||
|
||||
environment.globalSymbolTable.bind(functionName,
|
||||
new FunctionEntry(parameters.toArray(new Symbol[]{}), body));
|
||||
new FunctionEntry(functionName,
|
||||
parameters.toArray(new Symbol[]{}),
|
||||
body));
|
||||
|
||||
return functionName;
|
||||
}
|
||||
};
|
||||
|
||||
SpecialFormEntry SETQ = new SpecialFormEntry(environment) {
|
||||
public SExp call(SymbolTable symbolTable, Seq arguments) throws LispException {
|
||||
// ----
|
||||
// SETQ
|
||||
// ----
|
||||
|
||||
|
||||
SpecialFormEntry SETQ = new SpecialFormEntry(
|
||||
environment,
|
||||
new FormHelpTopic("SETQ", "Define a global variable.",
|
||||
"(setq <name> <value>)",
|
||||
"Bind a value to a symbol in the global symbol table.",
|
||||
"name", "the symbol to bind to the given value.",
|
||||
"value", "an sexpression representing the value of the "
|
||||
+ "variable. The value of the variable when it is "
|
||||
+ "evaluated is the evaluated value of this sexpression."))
|
||||
{
|
||||
public SExp call(SymbolTable symbolTable, Seq arguments)
|
||||
throws LispException {
|
||||
|
||||
Symbol variableName;
|
||||
SExp variableValue;
|
||||
@ -90,7 +194,7 @@ public abstract class SpecialFormEntry implements FormEntry {
|
||||
arguments = arguments.cdr;
|
||||
assert (arguments != null);
|
||||
|
||||
variableValue = arguments.car;
|
||||
variableValue = arguments.car.eval(symbolTable);
|
||||
|
||||
environment.globalSymbolTable.bind(variableName,
|
||||
new VariableEntry(variableValue));
|
||||
@ -99,7 +203,51 @@ public abstract class SpecialFormEntry implements FormEntry {
|
||||
}
|
||||
};
|
||||
|
||||
SpecialFormEntry SUM = new SpecialFormEntry(environment) {
|
||||
// -----
|
||||
// TRACE
|
||||
// -----
|
||||
|
||||
SpecialFormEntry TRACE = new SpecialFormEntry(
|
||||
environment,
|
||||
new FormHelpTopic("TRACE",
|
||||
"enable trace information for a function",
|
||||
"(trace <funcname>)",
|
||||
"Turn on trace information for a function.",
|
||||
"funcname", "the name of the function to trace"))
|
||||
{
|
||||
public SExp call(SymbolTable symbolTable, Seq arguments)
|
||||
throws LispException {
|
||||
|
||||
if (arguments == null || arguments.car == null)
|
||||
return null;
|
||||
|
||||
if (!(arguments.car instanceof Symbol))
|
||||
throw new LispException(arguments.car.toString()
|
||||
+ " is not a valid function name.");
|
||||
|
||||
FormEntry fe = symbolTable.lookupFunction((Symbol) arguments.car);
|
||||
|
||||
if (fe instanceof FunctionEntry) ((FunctionEntry) fe).enableTrace(true);
|
||||
// TODO: else throw error
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
// ---
|
||||
// SUM
|
||||
// ---
|
||||
|
||||
SpecialFormEntry SUM = new SpecialFormEntry(
|
||||
environment,
|
||||
new FormHelpTopic("+", "Sum several expressions.",
|
||||
"(+ [<addend_1> ... <addend_n>])",
|
||||
"Compute the summation of the zero or more expressions passed"
|
||||
+ "as arguments. In general, expressions are evaluated "
|
||||
+ "before being bound to function parameters. The"
|
||||
+ " expressions passed to sum must evaluate to numbers.",
|
||||
"addend_1 ... addend_n", "Addends may be any expression that "
|
||||
+ "evaluates to a number."))
|
||||
{
|
||||
public SExp call(SymbolTable symbolTable, Seq arguments)
|
||||
throws LispException {
|
||||
|
||||
@ -119,7 +267,22 @@ public abstract class SpecialFormEntry implements FormEntry {
|
||||
}
|
||||
};
|
||||
|
||||
SpecialFormEntry DIF = new SpecialFormEntry(environment) {
|
||||
SpecialFormEntry DIF = new SpecialFormEntry(
|
||||
environment,
|
||||
new FormHelpTopic("-", "Subtract several expressions.",
|
||||
"(- subtrahend) | (- ??? <subtrahend_1> [... <subtrahend_n>])",
|
||||
"Perform a subtraction. If there is only one argument passed "
|
||||
+ "then result = 0 - arg. If multiple arguments are passed"
|
||||
+ " then result = arg_1 - arg_2 - ... - args_n. In "
|
||||
+ "general, expressions are evaluated before being bound "
|
||||
+ " to function parameters. The expressions passed to - "
|
||||
+ "must evaluate to numbers.",
|
||||
"???", "In the case of multiple arguments to -, this is the "
|
||||
+ "number from which the others are subtracted.",
|
||||
"subtrahend_1 ... subtrahend_n", "Subtrahends are numbers "
|
||||
+ "subtracted from the ??? and may be any expression that "
|
||||
+ "evaluates to a number."))
|
||||
{
|
||||
public SExp call(SymbolTable symbolTable, Seq arguments)
|
||||
throws LispException {
|
||||
|
||||
@ -158,7 +321,17 @@ public abstract class SpecialFormEntry implements FormEntry {
|
||||
}
|
||||
};
|
||||
|
||||
SpecialFormEntry MUL = new SpecialFormEntry(environment) {
|
||||
SpecialFormEntry MUL = new SpecialFormEntry(
|
||||
environment,
|
||||
new FormHelpTopic("*", "Multiply several expressions.",
|
||||
"(+ [<multiplicand_1> ... <multiplicand_n>])",
|
||||
"Compute the product of the zero or more expressions passed"
|
||||
+ "as arguments. In general, expressions are evaluated "
|
||||
+ "before being bound to function parameters. The"
|
||||
+ " expressions passed to multiply must evaluate to numbers.",
|
||||
"multiplicand_1 ... multiplicand_n", "Multiplicands may be "
|
||||
+ "any expression that evaluates to a number."))
|
||||
{
|
||||
public SExp call(SymbolTable symbolTable, Seq arguments)
|
||||
throws LispException {
|
||||
|
||||
@ -179,7 +352,22 @@ public abstract class SpecialFormEntry implements FormEntry {
|
||||
}
|
||||
};
|
||||
|
||||
SpecialFormEntry DIV = new SpecialFormEntry(environment) {
|
||||
SpecialFormEntry DIV = new SpecialFormEntry(
|
||||
environment,
|
||||
new FormHelpTopic("/", "Divide several expressions.",
|
||||
"(- divisor) | (- quotient <divisor_1> [... <divisor_n>])",
|
||||
"Perform division. If there is only one argument passed "
|
||||
+ "then result = 1/ arg. If multiple arguments are passed"
|
||||
+ " then result = arg_1 / arg_2 / ... / args_n, computed "
|
||||
+ "from left to right. In general, expressions are "
|
||||
+ "evaluated before being bound to function parameters. "
|
||||
+ "The expressions passed to / must evaluate to numbers.",
|
||||
"quotient", "In the case of multiple arguments to /, this is "
|
||||
+ "the number which is diveded.",
|
||||
"divisor_1 ... divisor_n", "Divisors are the numbers dividing "
|
||||
+ "the quotient and may be any expression that evaluates "
|
||||
+ "to a number."))
|
||||
{
|
||||
public SExp call(SymbolTable symbolTable, Seq arguments)
|
||||
throws LispException {
|
||||
|
||||
@ -218,11 +406,47 @@ public abstract class SpecialFormEntry implements FormEntry {
|
||||
}
|
||||
};
|
||||
|
||||
SpecialFormEntry ENABLEDEBUGAST = new SpecialFormEntry(
|
||||
environment,
|
||||
new FormHelpTopic("ENABLE-DEBUG-AST",
|
||||
"Enable debug information: abstract syntax tree.",
|
||||
"(enable-debug-ast [<enable>])",
|
||||
"When DEBUG-AST is enabled, the runtime environment prints a "
|
||||
+ "representation of the abstract syntax tree generated "
|
||||
+ "by the parser for each sexpression it parses.",
|
||||
"enable", "NIL = disabled, anything else = enabled. No "
|
||||
+ "argument = enabled."))
|
||||
{
|
||||
public SExp call(SymbolTable symbolTable, Seq arguments)
|
||||
throws LispException {
|
||||
if (arguments == null) {
|
||||
environment.dumpAST = true;
|
||||
return null;
|
||||
}
|
||||
|
||||
SExp retVal = arguments.car.eval(symbolTable);
|
||||
|
||||
if (retVal != null) environment.dumpAST = true;
|
||||
else environment.dumpAST = false;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
};
|
||||
|
||||
/*SpecialFormEntry LET = new SpecialFormEntry(environment) {
|
||||
public SExp call(SymbolTable table, Seq arguments) {
|
||||
// TODO
|
||||
}
|
||||
}*/
|
||||
|
||||
environment.globalSymbolTable.bind(new Symbol("HELP"), HELP);
|
||||
environment.globalSymbolTable.bind(new Symbol("DEFUN"), DEFUN);
|
||||
environment.globalSymbolTable.bind(new Symbol("SETQ"), SETQ);
|
||||
environment.globalSymbolTable.bind(new Symbol("TRACE"), TRACE);
|
||||
environment.globalSymbolTable.bind(new Symbol("+"), SUM);
|
||||
environment.globalSymbolTable.bind(new Symbol("-"), DIF);
|
||||
environment.globalSymbolTable.bind(new Symbol("*"), MUL);
|
||||
environment.globalSymbolTable.bind(new Symbol("/"), DIV);
|
||||
environment.globalSymbolTable.bind(new Symbol("ENABLE-DEBUG-AST"), ENABLEDEBUGAST);
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ public class Symbol implements SExp {
|
||||
/** {@inheritdoc}*/
|
||||
public SExp eval(SymbolTable table) throws LispException {
|
||||
VariableEntry ve = table.lookupVariable(this);
|
||||
return ve.eval(table);
|
||||
return ve.value;
|
||||
}
|
||||
|
||||
public String display(String offset) {
|
||||
|
@ -6,11 +6,7 @@ package edu.utexas.cs345.jdblisp;
|
||||
*/
|
||||
public class VariableEntry {
|
||||
|
||||
protected final SExp expression;
|
||||
public final SExp value;
|
||||
|
||||
public VariableEntry(SExp expression) { this.expression = expression; }
|
||||
|
||||
public SExp eval(SymbolTable symbolTable) throws LispException {
|
||||
return expression.eval(symbolTable);
|
||||
}
|
||||
public VariableEntry(SExp value) { this.value = value; }
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ public class Parser implements ParserConstants {
|
||||
{if (true) return new Num(t.image);}
|
||||
break;
|
||||
case LPAREN:
|
||||
case NIL:
|
||||
s = list();
|
||||
{if (true) return s;}
|
||||
break;
|
||||
@ -39,10 +40,22 @@ public class Parser implements ParserConstants {
|
||||
*/
|
||||
static final public List list() throws ParseException {
|
||||
Seq s;
|
||||
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
|
||||
case LPAREN:
|
||||
jj_consume_token(LPAREN);
|
||||
s = seq();
|
||||
jj_consume_token(RPAREN);
|
||||
{if (true) return new List(s);}
|
||||
break;
|
||||
case NIL:
|
||||
jj_consume_token(NIL);
|
||||
{if (true) return new List(null);}
|
||||
break;
|
||||
default:
|
||||
jj_la1[1] = jj_gen;
|
||||
jj_consume_token(-1);
|
||||
throw new ParseException();
|
||||
}
|
||||
throw new Error("Missing return statement in function");
|
||||
}
|
||||
|
||||
@ -53,6 +66,7 @@ public class Parser implements ParserConstants {
|
||||
Seq sq; SExp se;
|
||||
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
|
||||
case LPAREN:
|
||||
case NIL:
|
||||
case NUMB:
|
||||
case STRG:
|
||||
case SYMB:
|
||||
@ -61,7 +75,7 @@ public class Parser implements ParserConstants {
|
||||
{if (true) return new Seq(se, sq);}
|
||||
break;
|
||||
default:
|
||||
jj_la1[1] = jj_gen;
|
||||
jj_la1[2] = jj_gen;
|
||||
;
|
||||
}
|
||||
{if (true) return null;}
|
||||
@ -78,13 +92,13 @@ public class Parser implements ParserConstants {
|
||||
static public Token jj_nt;
|
||||
static private int jj_ntk;
|
||||
static private int jj_gen;
|
||||
static final private int[] jj_la1 = new int[2];
|
||||
static final private int[] jj_la1 = new int[3];
|
||||
static private int[] jj_la1_0;
|
||||
static {
|
||||
jj_la1_init_0();
|
||||
}
|
||||
private static void jj_la1_init_0() {
|
||||
jj_la1_0 = new int[] {0x740,0x740,};
|
||||
jj_la1_0 = new int[] {0x1e80,0x280,0x1e80,};
|
||||
}
|
||||
|
||||
/** Constructor with InputStream. */
|
||||
@ -105,7 +119,7 @@ public class Parser implements ParserConstants {
|
||||
token = new Token();
|
||||
jj_ntk = -1;
|
||||
jj_gen = 0;
|
||||
for (int i = 0; i < 2; i++) jj_la1[i] = -1;
|
||||
for (int i = 0; i < 3; i++) jj_la1[i] = -1;
|
||||
}
|
||||
|
||||
/** Reinitialise. */
|
||||
@ -119,7 +133,7 @@ public class Parser implements ParserConstants {
|
||||
token = new Token();
|
||||
jj_ntk = -1;
|
||||
jj_gen = 0;
|
||||
for (int i = 0; i < 2; i++) jj_la1[i] = -1;
|
||||
for (int i = 0; i < 3; i++) jj_la1[i] = -1;
|
||||
}
|
||||
|
||||
/** Constructor. */
|
||||
@ -136,7 +150,7 @@ public class Parser implements ParserConstants {
|
||||
token = new Token();
|
||||
jj_ntk = -1;
|
||||
jj_gen = 0;
|
||||
for (int i = 0; i < 2; i++) jj_la1[i] = -1;
|
||||
for (int i = 0; i < 3; i++) jj_la1[i] = -1;
|
||||
}
|
||||
|
||||
/** Reinitialise. */
|
||||
@ -146,7 +160,7 @@ public class Parser implements ParserConstants {
|
||||
token = new Token();
|
||||
jj_ntk = -1;
|
||||
jj_gen = 0;
|
||||
for (int i = 0; i < 2; i++) jj_la1[i] = -1;
|
||||
for (int i = 0; i < 3; i++) jj_la1[i] = -1;
|
||||
}
|
||||
|
||||
/** Constructor with generated Token Manager. */
|
||||
@ -162,7 +176,7 @@ public class Parser implements ParserConstants {
|
||||
token = new Token();
|
||||
jj_ntk = -1;
|
||||
jj_gen = 0;
|
||||
for (int i = 0; i < 2; i++) jj_la1[i] = -1;
|
||||
for (int i = 0; i < 3; i++) jj_la1[i] = -1;
|
||||
}
|
||||
|
||||
/** Reinitialise. */
|
||||
@ -171,7 +185,7 @@ public class Parser implements ParserConstants {
|
||||
token = new Token();
|
||||
jj_ntk = -1;
|
||||
jj_gen = 0;
|
||||
for (int i = 0; i < 2; i++) jj_la1[i] = -1;
|
||||
for (int i = 0; i < 3; i++) jj_la1[i] = -1;
|
||||
}
|
||||
|
||||
static private Token jj_consume_token(int kind) throws ParseException {
|
||||
@ -222,12 +236,12 @@ public class Parser implements ParserConstants {
|
||||
/** Generate ParseException. */
|
||||
static public ParseException generateParseException() {
|
||||
jj_expentries.clear();
|
||||
boolean[] la1tokens = new boolean[11];
|
||||
boolean[] la1tokens = new boolean[13];
|
||||
if (jj_kind >= 0) {
|
||||
la1tokens[jj_kind] = true;
|
||||
jj_kind = -1;
|
||||
}
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (jj_la1[i] == jj_gen) {
|
||||
for (int j = 0; j < 32; j++) {
|
||||
if ((jj_la1_0[i] & (1<<j)) != 0) {
|
||||
@ -236,7 +250,7 @@ public class Parser implements ParserConstants {
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 11; i++) {
|
||||
for (int i = 0; i < 13; i++) {
|
||||
if (la1tokens[i]) {
|
||||
jj_expentry = new int[1];
|
||||
jj_expentry[0] = i;
|
||||
|
@ -11,15 +11,17 @@ public interface ParserConstants {
|
||||
/** End of File. */
|
||||
int EOF = 0;
|
||||
/** RegularExpression Id. */
|
||||
int LPAREN = 6;
|
||||
int LPAREN = 7;
|
||||
/** RegularExpression Id. */
|
||||
int RPAREN = 7;
|
||||
int RPAREN = 8;
|
||||
/** RegularExpression Id. */
|
||||
int NUMB = 8;
|
||||
int NIL = 9;
|
||||
/** RegularExpression Id. */
|
||||
int STRG = 9;
|
||||
int NUMB = 10;
|
||||
/** RegularExpression Id. */
|
||||
int SYMB = 10;
|
||||
int STRG = 11;
|
||||
/** RegularExpression Id. */
|
||||
int SYMB = 12;
|
||||
|
||||
/** Lexical state. */
|
||||
int DEFAULT = 0;
|
||||
@ -32,8 +34,10 @@ public interface ParserConstants {
|
||||
"\"\\t\"",
|
||||
"\"\\n\"",
|
||||
"\"\\n\\r\"",
|
||||
"\";.*$\"",
|
||||
"\"(\"",
|
||||
"\")\"",
|
||||
"<NIL>",
|
||||
"<NUMB>",
|
||||
"<STRG>",
|
||||
"<SYMB>",
|
||||
|
@ -36,9 +36,11 @@ static private int jjMoveStringLiteralDfa0_0()
|
||||
jjmatchedKind = 4;
|
||||
return jjMoveStringLiteralDfa1_0(0x20L);
|
||||
case 40:
|
||||
return jjStopAtPos(0, 6);
|
||||
case 41:
|
||||
return jjStopAtPos(0, 7);
|
||||
case 41:
|
||||
return jjStopAtPos(0, 8);
|
||||
case 59:
|
||||
return jjMoveStringLiteralDfa1_0(0x40L);
|
||||
default :
|
||||
return jjMoveNfa_0(0, 0);
|
||||
}
|
||||
@ -56,15 +58,55 @@ static private int jjMoveStringLiteralDfa1_0(long active0)
|
||||
if ((active0 & 0x20L) != 0L)
|
||||
return jjStopAtPos(1, 5);
|
||||
break;
|
||||
case 46:
|
||||
return jjMoveStringLiteralDfa2_0(active0, 0x40L);
|
||||
default :
|
||||
break;
|
||||
}
|
||||
return jjStartNfa_0(0, active0);
|
||||
}
|
||||
static private int jjMoveStringLiteralDfa2_0(long old0, long active0)
|
||||
{
|
||||
if (((active0 &= old0)) == 0L)
|
||||
return jjStartNfa_0(0, old0);
|
||||
try { curChar = input_stream.readChar(); }
|
||||
catch(java.io.IOException e) {
|
||||
jjStopStringLiteralDfa_0(1, active0);
|
||||
return 2;
|
||||
}
|
||||
switch(curChar)
|
||||
{
|
||||
case 42:
|
||||
return jjMoveStringLiteralDfa3_0(active0, 0x40L);
|
||||
default :
|
||||
break;
|
||||
}
|
||||
return jjStartNfa_0(1, active0);
|
||||
}
|
||||
static private int jjMoveStringLiteralDfa3_0(long old0, long active0)
|
||||
{
|
||||
if (((active0 &= old0)) == 0L)
|
||||
return jjStartNfa_0(1, old0);
|
||||
try { curChar = input_stream.readChar(); }
|
||||
catch(java.io.IOException e) {
|
||||
jjStopStringLiteralDfa_0(2, active0);
|
||||
return 3;
|
||||
}
|
||||
switch(curChar)
|
||||
{
|
||||
case 36:
|
||||
if ((active0 & 0x40L) != 0L)
|
||||
return jjStopAtPos(3, 6);
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
return jjStartNfa_0(2, active0);
|
||||
}
|
||||
static private int jjMoveNfa_0(int startState, int curPos)
|
||||
{
|
||||
int startsAt = 0;
|
||||
jjnewStateCnt = 9;
|
||||
jjnewStateCnt = 12;
|
||||
int i = 1;
|
||||
jjstateSet[0] = startState;
|
||||
int kind = 0x7fffffff;
|
||||
@ -82,57 +124,61 @@ static private int jjMoveNfa_0(int startState, int curPos)
|
||||
case 0:
|
||||
if ((0x3ff000000000000L & l) != 0L)
|
||||
{
|
||||
if (kind > 8)
|
||||
kind = 8;
|
||||
jjCheckNAddTwoStates(1, 2);
|
||||
if (kind > 10)
|
||||
kind = 10;
|
||||
jjCheckNAddTwoStates(4, 5);
|
||||
}
|
||||
else if ((0x2000ac0000000000L & l) != 0L)
|
||||
{
|
||||
if (kind > 10)
|
||||
kind = 10;
|
||||
jjCheckNAddTwoStates(7, 8);
|
||||
if (kind > 12)
|
||||
kind = 12;
|
||||
jjCheckNAddTwoStates(10, 11);
|
||||
}
|
||||
else if (curChar == 34)
|
||||
jjAddStates(0, 1);
|
||||
if ((0x280000000000L & l) != 0L)
|
||||
jjCheckNAdd(1);
|
||||
break;
|
||||
case 1:
|
||||
if ((0x3ff000000000000L & l) == 0L)
|
||||
break;
|
||||
if (kind > 8)
|
||||
kind = 8;
|
||||
jjCheckNAddTwoStates(1, 2);
|
||||
break;
|
||||
case 2:
|
||||
if (curChar == 46)
|
||||
jjCheckNAdd(3);
|
||||
jjCheckNAdd(4);
|
||||
break;
|
||||
case 3:
|
||||
if ((0x3ff000000000000L & l) == 0L)
|
||||
break;
|
||||
if (kind > 8)
|
||||
kind = 8;
|
||||
jjCheckNAdd(3);
|
||||
if ((0x280000000000L & l) != 0L)
|
||||
jjCheckNAdd(4);
|
||||
break;
|
||||
case 4:
|
||||
if (curChar == 34)
|
||||
jjAddStates(0, 1);
|
||||
break;
|
||||
case 6:
|
||||
if (curChar == 34 && kind > 9)
|
||||
kind = 9;
|
||||
break;
|
||||
case 7:
|
||||
if ((0x2000ac0000000000L & l) == 0L)
|
||||
if ((0x3ff000000000000L & l) == 0L)
|
||||
break;
|
||||
if (kind > 10)
|
||||
kind = 10;
|
||||
jjCheckNAddTwoStates(7, 8);
|
||||
jjCheckNAddTwoStates(4, 5);
|
||||
break;
|
||||
case 8:
|
||||
if ((0x23ffac0000000000L & l) != 0L && kind > 10)
|
||||
case 5:
|
||||
if (curChar == 46)
|
||||
jjCheckNAdd(6);
|
||||
break;
|
||||
case 6:
|
||||
if ((0x3ff000000000000L & l) == 0L)
|
||||
break;
|
||||
if (kind > 10)
|
||||
kind = 10;
|
||||
jjCheckNAdd(6);
|
||||
break;
|
||||
case 7:
|
||||
if (curChar == 34)
|
||||
jjAddStates(0, 1);
|
||||
break;
|
||||
case 9:
|
||||
if (curChar == 34 && kind > 11)
|
||||
kind = 11;
|
||||
break;
|
||||
case 10:
|
||||
if ((0x2000ac0000000000L & l) == 0L)
|
||||
break;
|
||||
if (kind > 12)
|
||||
kind = 12;
|
||||
jjCheckNAddTwoStates(10, 11);
|
||||
break;
|
||||
case 11:
|
||||
if ((0x23ffac0000000000L & l) != 0L && kind > 12)
|
||||
kind = 12;
|
||||
break;
|
||||
default : break;
|
||||
}
|
||||
@ -146,20 +192,37 @@ static private int jjMoveNfa_0(int startState, int curPos)
|
||||
switch(jjstateSet[--i])
|
||||
{
|
||||
case 0:
|
||||
case 7:
|
||||
if ((0x7fffffe87fffffeL & l) == 0L)
|
||||
if ((0x7fffffe87fffffeL & l) != 0L)
|
||||
{
|
||||
if (kind > 12)
|
||||
kind = 12;
|
||||
jjCheckNAddTwoStates(10, 11);
|
||||
}
|
||||
if ((0x400000004000L & l) != 0L)
|
||||
jjstateSet[jjnewStateCnt++] = 1;
|
||||
break;
|
||||
if (kind > 10)
|
||||
kind = 10;
|
||||
jjCheckNAddTwoStates(7, 8);
|
||||
case 1:
|
||||
if ((0x20000000200L & l) != 0L)
|
||||
jjstateSet[jjnewStateCnt++] = 2;
|
||||
break;
|
||||
case 5:
|
||||
case 2:
|
||||
if ((0x100000001000L & l) != 0L && kind > 9)
|
||||
kind = 9;
|
||||
break;
|
||||
case 8:
|
||||
if ((0x7fffffe87fffffeL & l) != 0L)
|
||||
jjAddStates(0, 1);
|
||||
break;
|
||||
case 8:
|
||||
if ((0x7fffffe87fffffeL & l) != 0L && kind > 10)
|
||||
kind = 10;
|
||||
case 10:
|
||||
if ((0x7fffffe87fffffeL & l) == 0L)
|
||||
break;
|
||||
if (kind > 12)
|
||||
kind = 12;
|
||||
jjCheckNAddTwoStates(10, 11);
|
||||
break;
|
||||
case 11:
|
||||
if ((0x7fffffe87fffffeL & l) != 0L && kind > 12)
|
||||
kind = 12;
|
||||
break;
|
||||
default : break;
|
||||
}
|
||||
@ -184,33 +247,33 @@ static private int jjMoveNfa_0(int startState, int curPos)
|
||||
kind = 0x7fffffff;
|
||||
}
|
||||
++curPos;
|
||||
if ((i = jjnewStateCnt) == (startsAt = 9 - (jjnewStateCnt = startsAt)))
|
||||
if ((i = jjnewStateCnt) == (startsAt = 12 - (jjnewStateCnt = startsAt)))
|
||||
return curPos;
|
||||
try { curChar = input_stream.readChar(); }
|
||||
catch(java.io.IOException e) { return curPos; }
|
||||
}
|
||||
}
|
||||
static final int[] jjnextStates = {
|
||||
5, 6,
|
||||
8, 9,
|
||||
};
|
||||
|
||||
/** Token literal values. */
|
||||
public static final String[] jjstrLiteralImages = {
|
||||
"", null, null, null, null, null, "\50", "\51", null, null, null, };
|
||||
"", null, null, null, null, null, null, "\50", "\51", null, null, null, null, };
|
||||
|
||||
/** Lexer state names. */
|
||||
public static final String[] lexStateNames = {
|
||||
"DEFAULT",
|
||||
};
|
||||
static final long[] jjtoToken = {
|
||||
0x7c1L,
|
||||
0x1f81L,
|
||||
};
|
||||
static final long[] jjtoSkip = {
|
||||
0x3eL,
|
||||
0x7eL,
|
||||
};
|
||||
static protected SimpleCharStream input_stream;
|
||||
static private final int[] jjrounds = new int[9];
|
||||
static private final int[] jjstateSet = new int[18];
|
||||
static private final int[] jjrounds = new int[12];
|
||||
static private final int[] jjstateSet = new int[24];
|
||||
static protected char curChar;
|
||||
/** Constructor. */
|
||||
public ParserTokenManager(SimpleCharStream stream){
|
||||
@ -237,7 +300,7 @@ static private void ReInitRounds()
|
||||
{
|
||||
int i;
|
||||
jjround = 0x80000001;
|
||||
for (i = 9; i-- > 0;)
|
||||
for (i = 12; i-- > 0;)
|
||||
jjrounds[i] = 0x80000000;
|
||||
}
|
||||
|
||||
|
14
src/org/jdbernard/util/NullOutputStream.java
Normal file
14
src/org/jdbernard/util/NullOutputStream.java
Normal file
@ -0,0 +1,14 @@
|
||||
package org.jdbernard.util;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* NullOutputStream
|
||||
* @author Jonathan Bernard (jdbernard@gmail.com)
|
||||
* All output directed to this OutputStream is ignored and lost. Writing to
|
||||
* stream is like writing to /dev/null.
|
||||
*/
|
||||
public class NullOutputStream extends OutputStream {
|
||||
|
||||
public void write(int b) {};
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user