From 1595ae19219bce66efdf24673862933aa6d9c409 Mon Sep 17 00:00:00 2001 From: Jonathan Bernard Date: Thu, 19 Nov 2009 10:59:14 -0600 Subject: [PATCH] Re-architected SymbolTable using maps rather than sequences. --- .../utexas/cs345/jdblisp/FunctionEntry.java | 16 ++++ src/edu/utexas/cs345/jdblisp/Symbol.java | 14 ++++ src/edu/utexas/cs345/jdblisp/SymbolTable.java | 83 +++++++++++-------- src/edu/utexas/cs345/jdblisp/TableEntry.java | 18 ---- .../utexas/cs345/jdblisp/VariableEntry.java | 14 ++++ 5 files changed, 94 insertions(+), 51 deletions(-) create mode 100644 src/edu/utexas/cs345/jdblisp/FunctionEntry.java delete mode 100644 src/edu/utexas/cs345/jdblisp/TableEntry.java create mode 100644 src/edu/utexas/cs345/jdblisp/VariableEntry.java diff --git a/src/edu/utexas/cs345/jdblisp/FunctionEntry.java b/src/edu/utexas/cs345/jdblisp/FunctionEntry.java new file mode 100644 index 0000000..e1ccbbf --- /dev/null +++ b/src/edu/utexas/cs345/jdblisp/FunctionEntry.java @@ -0,0 +1,16 @@ +package edu.utexas.cs345.jdblisp; + +/** + * FunctionEntry + * @author Jonathan Bernard (jdbernard@gmail.com) + */ +public class FunctionEntry { + + protected final Symbol[] parameters; + protected final SExp body; + + public SExp call(SymbolTable symbolTable, Seq seq) { + // TODO + return null; + } +} diff --git a/src/edu/utexas/cs345/jdblisp/Symbol.java b/src/edu/utexas/cs345/jdblisp/Symbol.java index cfcef75..45f0e2a 100644 --- a/src/edu/utexas/cs345/jdblisp/Symbol.java +++ b/src/edu/utexas/cs345/jdblisp/Symbol.java @@ -19,4 +19,18 @@ public class Symbol implements SExp { public String display(String offset) { return offset + "Symbol: " + name + "\n"; } + + @Override + public String toString() { return name; } + + @Override + public boolean equals(Object that) { + if (this == that) return true; + if (that == null) return false; + if (!(that instanceof Symbol)) return false; + return this.name.equals(((Symbol) that).name); + } + + @Override + public int hashCode() { return name.hashCode(); } } diff --git a/src/edu/utexas/cs345/jdblisp/SymbolTable.java b/src/edu/utexas/cs345/jdblisp/SymbolTable.java index f6ba111..66c4da1 100644 --- a/src/edu/utexas/cs345/jdblisp/SymbolTable.java +++ b/src/edu/utexas/cs345/jdblisp/SymbolTable.java @@ -5,48 +5,65 @@ package edu.utexas.cs345.jdblisp; * @author Jonathan Bernard (jdbernard@gmail.com) */ public class SymbolTable { - public final TableEntry top; - public final SymbolTable rest; - public SymbolTable(TableEntry te, SymbolTable st) { - this.top = te; - this.rest = st; + private Map functions = new HashMap(); + private Map variables = new HashMap(); + private SymbolTable enclosingTable; + private boolean locked = false; + + public SymbolTable() { this(null, false); } + + public SymbolTable(SymbolTable table) { this(table, false); } + + public SymbolTable(SymbolTable table, boolean locked) { + this.enclosingTable = table; + this.locked = locked; } - public SymbolTable(TableEntry... te) { - int idx = te.length; - SymbolTable last = null; - while (idx > 1) last = new SymbolTable(te[--idx], last); - - assert (--idx == 0) : "Error in SymbolTable construction. " - + "Invalid ending index"; - - this.top = te[0]; - this.rest = last; + public Symbol defineFunction(Symbol s, FunctionEntry f) { + if (functions.get(s) != null) { + // TODO: warning: function redefinition + // Also, check access permissions + } + functions.put(s, f); + return s; } - public TableEntry findFunction(Symbol symbol) throws LispException { - if (top.name.equals(symbol) && top.parameters != null) - return top; + public Symbol defineVariable(Symbol s, VariableEntry v) { + if (variables.get(s) != null) { + // TODO: warning: variable redefinition + // Also, check access permissions + } - if (rest == null) - throw new LispException("Undefined function: " - + symbol.name); - - return rest.findFunction(symbol); + variables.put(s, v); + return s; } - public TableEntry findVariable(Symbol symbol) throws LispException { - // if this entry is the one we're looking for, return it - if (top.name.equals(symbol) && top.parameters == null) - return top; + public FunctionEntry lookupFunction(Symbol s) throws LispException { + FunctionEntry fe = functions.get(s); - // if not, and there are no more entries - if (rest == null) - throw new LispException("Undefined variable: " - + symbol.name); + // found function definition + if (fe != null) return fe; - // otherwise, search the remainder of the table - return rest.findVariable(symbol); + // did not find function, and there is no outer scope + if (enclosingTable == null) + throw new LispException("Undefined function " + s.toString()); + + // search outer scope + return enclosingTable.lookupFunction(s); + } + + public VariableEntry lookupVariable(Symbol s) throws LispException { + VariableEntry ve = variables.get(s); + + // found variable entry + if (ve != null) return ve; + + // did not find variable entry and there is no outer scope + if (enclosingTable == null) + throw new LispException("Undefined variable " + s.toString()); + + // search outer scope + return enclosingTable.lookupVariable(s); } } diff --git a/src/edu/utexas/cs345/jdblisp/TableEntry.java b/src/edu/utexas/cs345/jdblisp/TableEntry.java deleted file mode 100644 index 348a792..0000000 --- a/src/edu/utexas/cs345/jdblisp/TableEntry.java +++ /dev/null @@ -1,18 +0,0 @@ -package edu.utexas.cs345.jdblisp; - -/** - * @author Jonathan Bernard (jdbernard@gmail.com) - */ -public class TableEntry { - - public final Symbol name; - public final Symbol[] parameters; - public final SExp body; - - public TableEntry(Symbol name, Symbol[] parameters, SExp body) { - this.name = name; - this.parameters = parameters; - this.body = body; - } - -} diff --git a/src/edu/utexas/cs345/jdblisp/VariableEntry.java b/src/edu/utexas/cs345/jdblisp/VariableEntry.java new file mode 100644 index 0000000..6f6d9d7 --- /dev/null +++ b/src/edu/utexas/cs345/jdblisp/VariableEntry.java @@ -0,0 +1,14 @@ +package edu.utexas.cs345.jdblisp; + +/** + * VariableEntry + * @author Jonathan Bernard (jdbernard@gmail.com) + */ +public class VariableEntry { + + protected final SExp expression; + + public SExp eval(SymbolTable symbolTable) { + return expression.eval(symbolTable); + } +}