diff --git a/.hgignore b/.hgignore old mode 100644 new mode 100755 diff --git a/build-common-versioning.xml b/build-common-versioning.xml old mode 100644 new mode 100755 diff --git a/build.xml b/build.xml old mode 100644 new mode 100755 diff --git a/project.properties b/project.properties old mode 100644 new mode 100755 diff --git a/src/edu/utexas/cs345/jdblisp/FunctionEntry.java b/src/edu/utexas/cs345/jdblisp/FunctionEntry.java old mode 100644 new mode 100755 index 65b4d40..60af07c --- a/src/edu/utexas/cs345/jdblisp/FunctionEntry.java +++ b/src/edu/utexas/cs345/jdblisp/FunctionEntry.java @@ -18,7 +18,7 @@ public class FunctionEntry { // bind arguments to parameters SymbolTable localScope = new SymbolTable(symbolTable); - int i = 0 + int i = 0; while (i < parameters.length) { // too few arguments diff --git a/src/edu/utexas/cs345/jdblisp/InvalidArgumentQuantityException.java b/src/edu/utexas/cs345/jdblisp/InvalidArgumentQuantityException.java old mode 100644 new mode 100755 index 9bc903e..e823c58 --- a/src/edu/utexas/cs345/jdblisp/InvalidArgumentQuantityException.java +++ b/src/edu/utexas/cs345/jdblisp/InvalidArgumentQuantityException.java @@ -1,7 +1,8 @@ -package edu.utexas.cs345.jdb-lisp; +package edu.utexas.cs345.jdblisp; /** * InvalidArgumentQuantityException + * @author Jonathan Bernard (jdbernard@gmail.com) * Indicates a call to a form with an incorrect number of arguments. */ public class InvalidArgumentQuantityException extends LispException { diff --git a/src/edu/utexas/cs345/jdblisp/Lisp.java b/src/edu/utexas/cs345/jdblisp/Lisp.java old mode 100644 new mode 100755 index bc1ab13..1b9a042 --- a/src/edu/utexas/cs345/jdblisp/Lisp.java +++ b/src/edu/utexas/cs345/jdblisp/Lisp.java @@ -26,12 +26,13 @@ public class Lisp { public Lisp(boolean interactive) { this.interactive = interactive; Parser parser = new Parser(new ByteArrayInputStream(new byte[]{})); + globalSymbolTable = new SymbolTable(); + SpecialFormEntry.defineSpecialForms(this); } public static void main(String[] args) { Lisp lisp = new Lisp(); lisp.repl(System.in, System.out); - globalSymbolTable = SpecialForms.createSymbolTable(); } public void repl(InputStream is, OutputStream os) { @@ -68,7 +69,6 @@ public class Lisp { } out.println(sexp.display(" ")); - out.println(sexp.eval(globalSymbolTable).car.body); // print prompt if applicable if (interactive) { diff --git a/src/edu/utexas/cs345/jdblisp/LispException.java b/src/edu/utexas/cs345/jdblisp/LispException.java old mode 100644 new mode 100755 diff --git a/src/edu/utexas/cs345/jdblisp/List.java b/src/edu/utexas/cs345/jdblisp/List.java old mode 100644 new mode 100755 index 2edac91..840316c --- a/src/edu/utexas/cs345/jdblisp/List.java +++ b/src/edu/utexas/cs345/jdblisp/List.java @@ -1,6 +1,7 @@ package edu.utexas.cs345.jdblisp; /** + * List * @author Jonathan Bernard (jdbernard@gmail.com) */ public class List implements SExp { @@ -42,4 +43,9 @@ public class List implements SExp { return sb.toString(); } + @Override + public String toString() { + return "(" + (seq == null ? "" : seq.toString()) + ")"; + } + } diff --git a/src/edu/utexas/cs345/jdblisp/Num.java b/src/edu/utexas/cs345/jdblisp/Num.java old mode 100644 new mode 100755 index b8251a8..d32f00d --- a/src/edu/utexas/cs345/jdblisp/Num.java +++ b/src/edu/utexas/cs345/jdblisp/Num.java @@ -36,7 +36,7 @@ public class Num implements SExp { } /** {@inheritdoc} */ - public SymbolTable eval(SymbolTable table) { + public SExp eval(SymbolTable table) { return new SymbolTable( new TableEntry( new Symbol("RETURN-VAL"), @@ -48,6 +48,7 @@ public class Num implements SExp { return offset + "Num: " + n.toString() + "\n"; } + @Override public String toString() { return n.toString(); } diff --git a/src/edu/utexas/cs345/jdblisp/Parser.jj b/src/edu/utexas/cs345/jdblisp/Parser.jj old mode 100644 new mode 100755 diff --git a/src/edu/utexas/cs345/jdblisp/SExp.java b/src/edu/utexas/cs345/jdblisp/SExp.java old mode 100644 new mode 100755 diff --git a/src/edu/utexas/cs345/jdblisp/Seq.java b/src/edu/utexas/cs345/jdblisp/Seq.java old mode 100644 new mode 100755 index 0014170..51372b6 --- a/src/edu/utexas/cs345/jdblisp/Seq.java +++ b/src/edu/utexas/cs345/jdblisp/Seq.java @@ -46,4 +46,9 @@ public class Seq implements SExp { return sb.toString(); } + + @Override + public String toString() { + return car.toString() + (cdr == null ? "" : cdr.toString()); + } } diff --git a/src/edu/utexas/cs345/jdblisp/SpecialFormEntry.java b/src/edu/utexas/cs345/jdblisp/SpecialFormEntry.java new file mode 100755 index 0000000..759cd94 --- /dev/null +++ b/src/edu/utexas/cs345/jdblisp/SpecialFormEntry.java @@ -0,0 +1,101 @@ +package edu.utexas.cs345.jdblisp; + +import java.util.ArrayList; + +/** + * SpecialFormEntry + * @author Jonathan Bernard (jdbernard@gmail.com) + */ +public abstract class SpecialFormEntry extends FunctionEntry { + + protected Lisp environment; + + public SpecialFormEntry(Lisp environment) { this.environment = environment; } + + public abstract SExp call(SymbolTable symbolTable, Seq arguments) throws LispException; + + + public static void defineSpecialForms(Lisp environment) { + + SpecialFormEntry DEFUN = new SpecialFormEntry(environment) { + public SExp call(SymbolTable symbolTable, Seq arguments) throws LispException { + + Symbol functionName; + ArrayList parameters; + SExp body; + + // TODO: check to see if a function for this symbol exists + // and warn if so + + if (arguments.length() != 3) + new InvalidArgumentQuantityException(3, arguments.length()); + + // first argument: Symbol for function name + if (!(arguments.car instanceof Symbol)) + throw new TypeException(arguments.car, Symbol.class); + + functionName = (Symbol) arguments.car; + + // second argument, parameter list + arguments = arguments.cdr; + assert (arguments != null); + + if (!(arguments.car instanceof List)) + // TODO: error, need parameter list + + // read parameters + parameters = new ArrayList(); + Seq paramSeq = ((List) arguments.car).seq; + while (seq != null) { + if (!(seq.car instanceof Symbol)) + throw new TypeException(seq.car, Symbol.class); + + parameters.add((Symbol) seq.car); + seq = seq.cdr; + } + + // third argument: function body + arguments = arguments.cdr; + assert (arguments != null); + + // TODO: necessary? if (!(arguments.car instanceof List)) + + body = arguments.car; + + environment.globalSymbolTable.define(functionName, + new FunctionEntry(parameters.toArray(new Symbol[]{}), body)); + + return functionName; + } + }; + + SpecialFormEntry SETQ = new SpecialFormEntry(environment) { + public SExp call(SymbolTable symbolTable, Seq arguments) throws LispException { + + Symbol variableName; + SExp variableValue; + + // TODO: check for redifinition of variable (and warn) + + if (arguments.length() != 2) + throw new InvalidArgumentQuantityException(2, + arguments.length()); + + // first argument: Symbol for variable name + if (!(arguments.car instanceof Symbol)) + // TODO: error: expected symbol + + variableName = (Symbol) arguments.car; + + // second argument: variable value + arguments = arguments.cdr; + assert (arguments != null); + + variableValue = arguments.car; + } + }; + + environment.globalSymbolTable.defin(new Symbol("DEFUN"), DEFUN); + environment.globalSymbolTable.defin(new Symbol("SETQ"), SETQ); + } +} diff --git a/src/edu/utexas/cs345/jdblisp/Str.java b/src/edu/utexas/cs345/jdblisp/Str.java old mode 100644 new mode 100755 index 3fd9841..59c8234 --- a/src/edu/utexas/cs345/jdblisp/Str.java +++ b/src/edu/utexas/cs345/jdblisp/Str.java @@ -24,6 +24,7 @@ public class Str implements SExp { return offset + "Str: " + value + "\n"; } + @Override public String toString() { return value; } diff --git a/src/edu/utexas/cs345/jdblisp/Symbol.java b/src/edu/utexas/cs345/jdblisp/Symbol.java old mode 100644 new mode 100755 diff --git a/src/edu/utexas/cs345/jdblisp/SymbolTable.java b/src/edu/utexas/cs345/jdblisp/SymbolTable.java old mode 100644 new mode 100755 index 627ef83..2645a53 --- a/src/edu/utexas/cs345/jdblisp/SymbolTable.java +++ b/src/edu/utexas/cs345/jdblisp/SymbolTable.java @@ -1,5 +1,8 @@ package edu.utexas.cs345.jdblisp; +import java.util.HashMap; +import java.util.Map; + /** * SymbolTable * @author Jonathan Bernard (jdbernard@gmail.com) diff --git a/src/edu/utexas/cs345/jdblisp/TypeException.java b/src/edu/utexas/cs345/jdblisp/TypeException.java new file mode 100644 index 0000000..fd57846 --- /dev/null +++ b/src/edu/utexas/cs345/jdblisp/TypeException.java @@ -0,0 +1,14 @@ +package edu.utexas.cs345.jdblisp; + +/** + * TypeException + * @author Jonathan Bernard (jdbernard@gmail.com) + * Represents type errors. + */ +public class TypeException extends LispException { + + public TypeException(SExp sexp, Class expectedType) { + super("TYPE-ERROR: The value " + sexp.toString() + " is not of type " + + expectedType.getSimpleName()); + } +} diff --git a/src/edu/utexas/cs345/jdblisp/VariableEntry.java b/src/edu/utexas/cs345/jdblisp/VariableEntry.java old mode 100644 new mode 100755 index 053f311..19366ae --- a/src/edu/utexas/cs345/jdblisp/VariableEntry.java +++ b/src/edu/utexas/cs345/jdblisp/VariableEntry.java @@ -10,7 +10,7 @@ public class VariableEntry { public VariableEntry(SExp expression) { this.expression = expression; } - public SExp eval(SymbolTable symbolTable) { + public SExp eval(SymbolTable symbolTable) throws LispException { return expression.eval(symbolTable); } }