/* Macro tables are organized into a tree. Look up of a macro name starts with a specified macro table, working its way back up the path to the root table. */ MacroTable { (@ // map macro name to its definition private Hashtable def_; private MacroTable parent_; @) init (@ def_ = new Hashtable(); parent_ = null; @) (@ MacroTable(MacroTable parent) { this(); parent_ = parent; } MacroTable parent() { return parent_; } void define(String name, String value){ def_.put(name,value); } String getValue(String name){ String result = (String)def_.get(name); if(result == null && parent_ != null) result = parent_.getValue(name); return result; } Enumeration keys(){ return new MacroTableKeyEnumeration(this); } Enumeration currentKeys(){ return def_.keys(); } void display(){ Enumeration itr = keys(); System.out.println("MacroTable - start"); while(itr.hasMoreElements()){ String name = (String)(itr.nextElement()); String value = getValue(name); System.out.println("name="+name+", value="+value); } System.out.println("MacroTable - end"); } @) } MacroTableKeyEnumeration{ (@ private MacroTable table_ = null; private Enumeration itr_ = null; MacroTableKeyEnumeration(MacroTable table){ itr_ = table.currentKeys(); table_ = table.parent(); } public boolean hasMoreElements(){ if(itr_ == null) return false; boolean result = itr_.hasMoreElements(); while( result == false && itr_ != null){ if(table_ == null){ itr_ = null; result = false; } else{ itr_ = table_.currentKeys(); table_ = table_.parent(); result = itr_.hasMoreElements(); } } return result; } public Object nextElement(){ return itr_.nextElement(); } @) }