Re-architected SymbolTable using maps rather than sequences.

This commit is contained in:
Jonathan Bernard 2009-11-19 10:59:14 -06:00
parent ebbcb87745
commit 1595ae1921
5 changed files with 94 additions and 51 deletions

View File

@ -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;
}
}

View File

@ -19,4 +19,18 @@ public class Symbol implements SExp {
public String display(String offset) { public String display(String offset) {
return offset + "Symbol: " + name + "\n"; 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(); }
} }

View File

@ -5,48 +5,65 @@ package edu.utexas.cs345.jdblisp;
* @author Jonathan Bernard (jdbernard@gmail.com) * @author Jonathan Bernard (jdbernard@gmail.com)
*/ */
public class SymbolTable { public class SymbolTable {
public final TableEntry top;
public final SymbolTable rest;
public SymbolTable(TableEntry te, SymbolTable st) { private Map<Symbol, FunctionEntry> functions = new HashMap<Symbol, FunctionEntry>();
this.top = te; private Map<Symbol, VariableEntry> variables = new HashMap<Symbol, VariableEntry>();
this.rest = st; 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) { public Symbol defineFunction(Symbol s, FunctionEntry f) {
int idx = te.length; if (functions.get(s) != null) {
SymbolTable last = null; // TODO: warning: function redefinition
while (idx > 1) last = new SymbolTable(te[--idx], last); // Also, check access permissions
}
assert (--idx == 0) : "Error in SymbolTable construction. " functions.put(s, f);
+ "Invalid ending index"; return s;
this.top = te[0];
this.rest = last;
} }
public TableEntry findFunction(Symbol symbol) throws LispException { public Symbol defineVariable(Symbol s, VariableEntry v) {
if (top.name.equals(symbol) && top.parameters != null) if (variables.get(s) != null) {
return top; // TODO: warning: variable redefinition
// Also, check access permissions
if (rest == null)
throw new LispException("Undefined function: "
+ symbol.name);
return rest.findFunction(symbol);
} }
public TableEntry findVariable(Symbol symbol) throws LispException { variables.put(s, v);
// if this entry is the one we're looking for, return it return s;
if (top.name.equals(symbol) && top.parameters == null) }
return top;
// if not, and there are no more entries public FunctionEntry lookupFunction(Symbol s) throws LispException {
if (rest == null) FunctionEntry fe = functions.get(s);
throw new LispException("Undefined variable: "
+ symbol.name);
// otherwise, search the remainder of the table // found function definition
return rest.findVariable(symbol); if (fe != null) return fe;
// 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);
} }
} }

View File

@ -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;
}
}

View File

@ -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);
}
}