Skip to content

Instantly share code, notes, and snippets.

@joseanpg
Created November 18, 2012 08:26
Show Gist options
  • Save joseanpg/4104192 to your computer and use it in GitHub Desktop.
Save joseanpg/4104192 to your computer and use it in GitHub Desktop.
Symbols and Tables :: Cool Support Code
class SymbolTable {
private Stack tbl;
public SymbolTable() { tbl = new Stack();}
public void enterScope() { tbl.push(new Hashtable());}
public void exitScope() {
if (tbl.empty()) { Utilities.fatalError("existScope: can't remove scope from an empty symbol table.");}
tbl.pop();
}
public void addId(AbstractSymbol id, Object info) {
if (tbl.empty()) { Utilities.fatalError("addId: can't add a symbol without a scope."); }
((Hashtable)tbl.peek()).put(id, info);
}
public Object lookup(AbstractSymbol sym) {
if (tbl.empty()) { Utilities.fatalError("lookup: no scope in symbol table.");}
for (int i = tbl.size() - 1; i >= 0; i--) {
Object info = ((Hashtable)tbl.elementAt(i)).get(sym);
if (info != null) return info;
}
return null;
}
public Object probe(AbstractSymbol sym) {
if (tbl.empty()) { Utilities.fatalError("lookup: no scope in symbol table.");}
return ((Hashtable)tbl.peek()).get(sym);
}
public String toString() {
String res = "";
for (int i = tbl.size() - 1, j = 0; i >= 0; i--, j++) {
res += "Scope " + j + ": " + tbl.elementAt(i) + "\n";
}
return res;
}
}
public class SymtabExample {
public static void main(String args[]) {
SymbolTable map = new SymbolTable();
AbstractSymbol fred = AbstractTable.stringtable.addString("Fred");
AbstractSymbol mary = AbstractTable.stringtable.addString("Mary");
AbstractSymbol miguel = AbstractTable.stringtable.addString("Miguel");
map.enterScope();
map.addId(fred, new Integer(22));
map.addId(mary, new Integer(25));
map.enterScope();
map.addId(miguel, new Integer(35));
map.addId(mary, new Integer(23));
// check whether Fred is in the current scope; predicate is false
System.out.println((map.probe(fred) != null) ? "Yes" : "No");
// check whether Mary is in any scope; predicate is true
System.out.println((map.lookup(mary) != null) ? "Yes" : "No");
// print age of most-closely-nested Mary
System.out.println(map.lookup(mary));
// check whether Miguel is in the current scope; predicate is true
System.out.println((map.probe(miguel) != null) ? "Yes" : "No");
// leave a scope
map.exitScope();
// print age of most-closely-nested Mary
System.out.println(map.lookup(mary));
// check whether Fred is in the current scope; predicate is now true
System.out.println((map.probe(fred) != null) ? "Yes" : "No");
// check whether Miguel is in any scope; predicate is now false
System.out.println((map.lookup(miguel) != null) ? "Yes" : "No");
}
}
import java.io.PrintStream;
public abstract class AbstractSymbol {
protected String str;
protected int index;
public AbstractSymbol(String str, int len, int index) {
this.str = str.length() == len ? str : str.substring(0, len);
this.index = index;
}
public boolean equalString(String str, int len) {
String other = str.length() == len ? str : str.substring(0, len);
return this.str.equals(other);
}
public boolean equalsIndex(int index) {
return this.index == index;
}
public boolean equals(Object another) {
return (another instanceof AbstractSymbol) &&
((AbstractSymbol)another).index == this.index;
}
public String getString() { return str; }
public String toString() { return str;}
public abstract Object clone();
}
public class IdSymbol extends AbstractSymbol {
public IdSymbol(String str, int len, int index) {
super(str, len, index);
}
public Object clone() {
return new IdSymbol(str, str.length(), index);
}
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// These are project skeleton files for PA5, but a regular support code
// for other assignments.
public class IntSymbol extends AbstractSymbol {
public IntSymbol(String str, int len, int index) {
super(str, len, index);
}
/** Generates code for the integer constant definition. This method
* is incomplete; you get to finish it up in programming assignment
* 5.
* @param intclasstag the class tag for string object
* @param s the output stream
*
* */
public void codeDef(int intclasstag, PrintStream s) {
// Add -1 eye catcher
s.println(CgenSupport.WORD + "-1");
codeRef(s); s.print(CgenSupport.LABEL); // label
s.println(CgenSupport.WORD + intclasstag); // tag
s.println(CgenSupport.WORD + (CgenSupport.DEFAULT_OBJFIELDS +
CgenSupport.INT_SLOTS)); // size
s.print(CgenSupport.WORD);
/* Add code to reference the dispatch table for class Int here */
s.println(""); // dispatch table
s.println(CgenSupport.WORD + str); // integer value
}
public void codeRef(PrintStream s) { s.print(CgenSupport.INTCONST_PREFIX + index); }
public Object clone() { return new IntSymbol(str, str.length(), index);}
}
public class StringSymbol extends AbstractSymbol {
public StringSymbol(String str, int len, int index) {
super(str, len, index);
}
/** Generates code for the string constant definition. This method
* is incomplete; you get to finish it up in programming assignment
* 5.
* @param stringclasstag the class tag for string object
* @param s the output stream
*
* */
public void codeDef(int stringclasstag, PrintStream s) {
IntSymbol lensym = (IntSymbol)AbstractTable.inttable.addInt(str.length());
// Add -1 eye catcher
s.println(CgenSupport.WORD + "-1");
codeRef(s); s.print(CgenSupport.LABEL); // label
s.println(CgenSupport.WORD + stringclasstag); // tag
s.println(CgenSupport.WORD + (CgenSupport.DEFAULT_OBJFIELDS +
CgenSupport.STRING_SLOTS +
(str.length() + 4) / 4)); // object size
s.print(CgenSupport.WORD);
/* Add code to reference the dispatch table for class String here */
s.println(""); // dispatch table
s.print(CgenSupport.WORD); lensym.codeRef(s); s.println(""); // length
CgenSupport.emitStringConstant(str, s); // ascii string
s.print(CgenSupport.ALIGN); // align to word
}
public void codeRef(PrintStream s) {
s.print(CgenSupport.STRCONST_PREFIX + index);
}
public Object clone() {
return new StringSymbol(str, str.length(), index);
}
}
public abstract class AbstractTable {
public static StringTable stringtable = new StringTable();
public static IdTable idtable = new IdTable();
public static IntTable inttable = new IntTable();
private static int MAXSIZE = 1000000;
protected Vector tbl = new Vector();
protected abstract AbstractSymbol getNewSymbol(String s, int len, int index);
public AbstractSymbol addString(String s, int maxchars) {
int len = Math.min(s.length(), maxchars);
AbstractSymbol sym = null;
for (int i = 0; i < tbl.size(); i++) {
try {
sym = (AbstractSymbol)tbl.elementAt(i);
} catch (ArrayIndexOutOfBoundsException ex) {
Utilities.fatalError("Unexpected exception: " + ex);
}
if (sym.equalString(s, len)) {
return sym;
}
}
sym = getNewSymbol(s, len, tbl.size());
tbl.addElement(sym);
return sym;
}
public AbstractSymbol addString(String s) {
return addString(s, MAXSIZE);
}
public AbstractSymbol addInt(int i) {
return addString(Integer.toString(i), MAXSIZE);
}
public Enumeration getSymbols() {
return tbl.elements();
}
public AbstractSymbol lookup(int index) {
AbstractSymbol sym = null;
try {
sym = (AbstractSymbol)tbl.elementAt(index);
} catch (ArrayIndexOutOfBoundsException ex) {
Utilities.fatalError("Symbol index out of bounds: " + index);
}
return sym;
}
public AbstractSymbol lookup(String s) {
int len = s.length();
AbstractSymbol sym = null;
for (int i = 0; i < tbl.size(); i++) {
try {
sym = (AbstractSymbol)tbl.elementAt(i);
} catch (ArrayIndexOutOfBoundsException ex) {
Utilities.fatalError("Unexpected exception: " + ex);
}
if (sym.equalString(s, len)) {
return sym;
}
}
Utilities.fatalError("String table lookup failed on string: " + s);
return null;
}
public String toString() {
String res = "[\n";
AbstractSymbol sym = null;
for (int i = 0; i < tbl.size(); i++) {
try {
sym = (AbstractSymbol)tbl.elementAt(i);
} catch (ArrayIndexOutOfBoundsException ex) {
Utilities.fatalError("Unexpected exception: " + ex);
}
res += " " + sym.toString() + "\n";
}
res += "]\n";
return res;
}
}
////////////////////////////////////////////////////////////////////////////
import java.io.PrintStream;
public class IdTable extends AbstractTable {
protected AbstractSymbol getNewSymbol(String s, int len, int index) {
return new IdSymbol(s, len, index);
}
}
public class StringTable extends AbstractTable {
protected AbstractSymbol getNewSymbol(String s, int len, int index) {
return new StringSymbol(s, len, index);
}
public void codeStringTable(int stringclasstag, PrintStream s) {
StringSymbol sym = null;
for (int i = tbl.size() - 1; i >= 0; i--) {
try {
sym = (StringSymbol)tbl.elementAt(i);
} catch (ArrayIndexOutOfBoundsException ex) {
Utilities.fatalError("Unexpected exception: " + ex);
}
sym.codeDef(stringclasstag, s);
}
}
}
public class IntTable extends AbstractTable {
protected AbstractSymbol getNewSymbol(String s, int len, int index) {
return new IntSymbol(s, len, index);
}
public void codeStringTable(int intclasstag, PrintStream s) {
IntSymbol sym = null;
for (int i = tbl.size() - 1; i >= 0; i--) {
try {
sym = (IntSymbol)tbl.elementAt(i);
} catch (ArrayIndexOutOfBoundsException ex) {
Utilities.fatalError("Unexpected exception: " + ex);
}
sym.codeDef(intclasstag, s);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment