1 4 package gnu.mapping; 5 import java.util.Hashtable ; 6 7 11 12 public abstract class Environment 13 extends PropertySet 14 { 16 static Environment global; 17 18 public static void setGlobal (Environment env) 19 { 20 global = env; 21 } 22 23 public static Environment getGlobal () 24 { 25 return global; 26 } 27 28 static final int CAN_DEFINE = 1; 29 static final int CAN_REDEFINE = 2; 30 31 32 static final int CAN_IMPLICITLY_DEFINE = 4; 33 34 35 static final int THREAD_SAFE = 8; 36 37 38 static final int DIRECT_INHERITED_ON_SET = 16; 39 40 41 public static final int INDIRECT_DEFINES = 32; 42 43 int flags = (CAN_DEFINE|CAN_REDEFINE|CAN_IMPLICITLY_DEFINE 44 |DIRECT_INHERITED_ON_SET); 45 46 public int getFlags () { return flags; } 47 48 public void setFlag (boolean setting, int flag) 49 { 50 if (setting) flags |= flag; 51 else flags &= ~flag; 52 } 53 54 55 public boolean getCanDefine() { return ( flags & CAN_DEFINE) != 0; } 56 public void setCanDefine(boolean canDefine) 57 { if (canDefine) flags |= CAN_DEFINE; else flags &= ~CAN_DEFINE; } 58 59 60 public boolean getCanRedefine() { return ( flags & CAN_REDEFINE) != 0; } 61 public void setCanRedefine(boolean canRedefine) 62 { if (canRedefine) flags |= CAN_REDEFINE; else flags &= ~CAN_REDEFINE; } 63 64 65 public final boolean isLocked() 66 { 67 return (flags & (CAN_DEFINE|CAN_REDEFINE)) == 0; 68 } 69 70 public void setLocked () 71 { 72 flags &= ~(CAN_DEFINE|CAN_REDEFINE|CAN_IMPLICITLY_DEFINE); 73 } 74 75 public final void setIndirectDefines () 76 { 77 flags |= Environment.INDIRECT_DEFINES; 78 ((InheritingEnvironment) this).baseTimestamp = 0x7fffffff; 79 } 80 81 83 public final Location getLocation (Symbol key, Object property) 84 { 85 return getLocation(key, property, true); 86 } 87 88 90 public final Location getLocation (Symbol key) 91 { 92 return getLocation(key, null, true); 93 } 94 95 97 public final Location lookup (Symbol key, Object property) 98 { 99 return getLocation(key, property, false); 100 } 101 102 public abstract NamedLocation 103 lookup (Symbol name, Object property, int hash); 104 105 public final Location lookup (Symbol key) 106 { 107 return getLocation(key, null, false); 108 } 109 110 public abstract NamedLocation getLocation (Symbol key, Object property, 111 int hash, boolean create); 112 113 public final NamedLocation 114 getLocation (Symbol name, Object property, boolean create) 115 { 116 int hash = name.hashCode() ^ System.identityHashCode(property); 117 return getLocation(name, property, hash, create); 118 } 119 120 public final Location getLocation (Object key, boolean create) 121 { 122 Object property = null; 123 if (key instanceof EnvironmentKey) 124 { 125 EnvironmentKey k = (EnvironmentKey) key; 126 key = k.getKeySymbol(); 127 property = k.getKeyProperty(); 128 } 129 Symbol sym = key instanceof Symbol ? (Symbol) key 130 : getSymbol((String ) key); 131 return getLocation(sym, property, create); 132 } 133 134 public boolean isBound(Symbol key, Object property) 135 { 136 Location loc = lookup(key, property); 137 if (loc == null) 138 return false; 139 return loc.isBound(); 140 } 141 142 public final boolean isBound(Symbol key) 143 { 144 return isBound(key, null); 145 } 146 147 public final boolean containsKey (Object key) 148 { 149 Object property = null; 150 if (key instanceof EnvironmentKey) 151 { 152 EnvironmentKey k = (EnvironmentKey) key; 153 key = k.getKeySymbol(); 154 property = k.getKeyProperty(); 155 } 156 Symbol sym = key instanceof Symbol ? (Symbol) key 157 : getSymbol((String ) key); 158 return isBound(sym, property); 159 } 160 161 165 public final Object getChecked(String name) 166 { 167 Object value = get(name, Location.UNBOUND); 168 if (value == Location.UNBOUND) 169 throw new UnboundLocationException(name+" in "+this); 170 return value; 171 } 172 173 public Object get (Symbol key, Object property, Object defaultValue) 174 { 175 Location loc = lookup(key, property); 176 if (loc == null) 177 return defaultValue; 178 return loc.get(defaultValue); 179 } 180 181 public final Object get (EnvironmentKey key, Object defaultValue) 182 { 183 Symbol symbol = key.getKeySymbol(); 184 Object property = key.getKeyProperty(); 185 return get(symbol, property, defaultValue); 186 } 187 188 public final Object get(String key, Object defaultValue) 189 { 190 return get(getSymbol(key), null, defaultValue); 191 } 192 193 public Object get (Symbol sym) 194 { 195 Object unb = Location.UNBOUND; 196 Object val = get(sym, null, unb); 197 if (val == unb) 198 throw new UnboundLocationException(sym); 199 return val; 200 } 201 202 public final Object getFunction (Symbol key, Object defaultValue) 203 { 204 return get(key, EnvironmentKey.FUNCTION, defaultValue); 205 } 206 207 public final Object getFunction (Symbol sym) 208 { 209 Object unb = Location.UNBOUND; 210 Object val = get(sym, EnvironmentKey.FUNCTION, unb); 211 if (val == unb) 212 throw new UnboundLocationException(sym); 213 return val; 214 } 215 216 221 public final Object get (Object key) 222 { 223 Object property = null; 224 if (key instanceof EnvironmentKey) 225 { 226 EnvironmentKey k = (EnvironmentKey) key; 227 key = k.getKeySymbol(); 228 property = k.getKeyProperty(); 229 } 230 Symbol sym = key instanceof Symbol ? (Symbol) key 231 : getSymbol((String ) key); 232 return get(sym, property, null); 233 } 234 235 public void put(Symbol key, Object property, Object newValue) 236 { 237 Location loc = getLocation(key, property); 238 if (loc.isConstant()) define(key, property, newValue); 240 else 241 loc.set(newValue); 242 } 243 244 public abstract void define (Symbol key, Object property, Object newValue); 245 246 public final void put (Symbol key, Object newValue) 247 { 248 put(key, null, newValue); 249 } 250 251 public final Object put(Object key, Object newValue) 252 { 253 Location loc = getLocation(key, true); 254 Object oldValue = loc.get(null); 255 loc.set(newValue); 256 return oldValue; 257 } 258 259 public final void putFunction(Symbol key, Object newValue) 260 { 261 put(key, EnvironmentKey.FUNCTION, newValue); 262 } 263 264 public final Object put (String key, Object value) 265 { 266 return put((Object ) key, value); 267 } 268 269 272 public Location unlink (Symbol key, Object property, int hash) 273 { 274 throw new RuntimeException ("unsupported operation: unlink (aka undefine)"); 275 } 276 277 278 public Object remove (Symbol key, Object property, int hash) 279 { 280 Location loc = unlink(key, property, hash); 281 if (loc == null) 282 return null; 283 Object value = loc.get(null); 284 loc.undefine(); 285 return value; 286 } 287 288 291 public final Object remove (EnvironmentKey key) 292 { 293 Symbol symbol = key.getKeySymbol(); 294 Object property = key.getKeyProperty(); 295 int hash = symbol.hashCode() ^ System.identityHashCode(property); 296 return remove(symbol, property, hash); 297 } 298 299 public final Object remove (Symbol symbol, Object property) 300 { 301 int hash = symbol.hashCode() ^ System.identityHashCode(property); 302 return remove(symbol, property, hash); 303 } 304 305 public final void remove (Symbol sym) 306 { 307 remove(sym, null, sym.hashCode()); 308 } 309 310 public final void removeFunction (Symbol sym) 311 { 312 remove(sym, EnvironmentKey.FUNCTION); 313 } 314 315 public final Object remove (Object key) 316 { 317 Object property = null; 318 if (key instanceof EnvironmentKey) 319 { 320 EnvironmentKey k = (EnvironmentKey) key; 321 return remove(k.getKeySymbol(), k.getKeyProperty()); 322 } 323 Symbol symbol = key instanceof Symbol ? (Symbol) key 324 : getSymbol((String ) key); 325 int hash = symbol.hashCode() ^ System.identityHashCode(property); 326 return remove(symbol, property, hash); 327 } 328 329 public Namespace defaultNamespace() 330 { 331 return Namespace.getDefault(); 333 } 334 335 public Symbol getSymbol (String name) 336 { 337 return defaultNamespace().getSymbol(name); 338 } 339 340 static final Hashtable envTable = new Hashtable (50); 341 342 public static Environment getInstance(String name) 343 { 344 if (name == null) 345 name = ""; 346 synchronized (envTable) 347 { 348 Environment env = (Environment) envTable.get(name); 349 if (env != null) 350 return env; 351 env = new SimpleEnvironment (); 352 env.setName(name); 353 envTable.put(name, env); 354 return env; 355 } 356 } 357 358 359 public abstract LocationEnumeration enumerateLocations(); 360 361 362 public abstract LocationEnumeration enumerateAllLocations(); 363 364 protected abstract boolean hasMoreElements (LocationEnumeration it); 365 366 369 public static Environment current () { return getCurrent(); } 370 public static Environment getCurrent () 371 { 372 return CallContext.getInstance().getEnvironment(); 373 } 374 375 public static void setCurrent (Environment env) 376 { 377 CallContext.getInstance().curEnvironment = env; 378 } 379 380 public static Environment user () { return getCurrent(); } 381 382 public final void addLocation (NamedLocation loc) 383 { 384 addLocation(loc.getKeySymbol(), loc.getKeyProperty(), loc); 385 } 386 387 public abstract NamedLocation addLocation (Symbol name, Object prop, Location loc); 388 389 public final void addLocation (EnvironmentKey key, Location loc) 390 { 391 addLocation(key.getKeySymbol(), key.getKeyProperty(), loc); 392 } 393 394 public static SimpleEnvironment make () 395 { 396 return new SimpleEnvironment(); 397 } 398 399 public static SimpleEnvironment make (String name) 400 { 401 return new SimpleEnvironment(name); 402 } 403 404 public static InheritingEnvironment make (String name, Environment parent) 405 { 406 return new InheritingEnvironment(name, parent); 407 } 408 409 public String toString () 410 { 411 return "#<environment "+getName()+'>'; 412 } 413 414 415 public String toStringVerbose () 416 { 417 return toString(); 418 } 419 } 420 | Popular Tags |