InheritingEnvironment.java 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // Copyright (c) 2004 Per M.A. Bothner.
  2. // This is free software; for terms and warranty disclaimer see ./COPYING.
  3. package gnu.mapping;
  4. public class InheritingEnvironment extends SimpleEnvironment
  5. {
  6. int numInherited;
  7. Environment[] inherited;
  8. int baseTimestamp;
  9. public InheritingEnvironment (String name, Environment parent)
  10. {
  11. super(name);
  12. addParent(parent);
  13. if (parent instanceof SimpleEnvironment)
  14. {
  15. int timestamp = ++((SimpleEnvironment) parent).currentTimestamp;
  16. baseTimestamp = timestamp;
  17. currentTimestamp = timestamp;
  18. }
  19. }
  20. public final int getNumParents () { return numInherited; }
  21. public final Environment getParent (int index) { return inherited[index]; }
  22. public void addParent (Environment env)
  23. {
  24. if (numInherited == 0)
  25. inherited = new Environment[4];
  26. else if (numInherited <= inherited.length)
  27. {
  28. Environment[] newInherited
  29. = new Environment[2 * numInherited];
  30. System.arraycopy(inherited, 0, newInherited, 0, numInherited);
  31. inherited = newInherited;
  32. }
  33. inherited[numInherited] = env;
  34. numInherited++;
  35. }
  36. public NamedLocation lookupInherited (Symbol name, Object property, int hash)
  37. {
  38. for (int i = 0; i < numInherited; i++)
  39. {
  40. Symbol sym = name;
  41. Object prop = property;
  42. NamedLocation loc = inherited[i].lookup(sym, prop, hash);
  43. if (loc != null && loc.isBound())
  44. {
  45. if (! (loc instanceof SharedLocation)
  46. || ((SharedLocation) loc).timestamp < baseTimestamp)
  47. return loc;
  48. }
  49. }
  50. return null;
  51. }
  52. public NamedLocation lookup (Symbol name, Object property, int hash)
  53. {
  54. NamedLocation loc = super.lookup(name, property, hash);
  55. if (loc != null && loc.isBound())
  56. return loc;
  57. return lookupInherited(name, property, hash);
  58. }
  59. public synchronized NamedLocation
  60. getLocation (Symbol name, Object property, int hash, boolean create)
  61. {
  62. NamedLocation loc = lookupDirect(name, property, hash);
  63. if (loc != null && (create || loc.isBound()))
  64. return loc;
  65. if ((flags & INDIRECT_DEFINES) != 0 && create)
  66. loc = inherited[0].getLocation(name, property, hash, true);
  67. else
  68. loc = lookupInherited(name, property, hash);
  69. if (loc != null)
  70. {
  71. if (create /* && loc.getEnvironment() != this*/)
  72. {
  73. NamedLocation xloc = addUnboundLocation(name, property, hash);
  74. if ((flags & CAN_DEFINE) == 0 && loc.isBound())
  75. redefineError(name, property, xloc);
  76. xloc.base = loc;
  77. if (loc.value == IndirectableLocation.INDIRECT_FLUIDS)
  78. xloc.value = loc.value;
  79. else if ((flags & DIRECT_INHERITED_ON_SET) != 0)
  80. xloc.value = IndirectableLocation.DIRECT_ON_SET;
  81. else
  82. xloc.value = null;
  83. if (xloc instanceof SharedLocation)
  84. ((SharedLocation) xloc).timestamp = baseTimestamp;
  85. return xloc;
  86. }
  87. else
  88. return loc;
  89. }
  90. return create ? addUnboundLocation(name, property, hash) : null;
  91. }
  92. public LocationEnumeration enumerateAllLocations()
  93. {
  94. LocationEnumeration it = new LocationEnumeration(table, 1 << log2Size);
  95. it.env = this;
  96. if (inherited != null && inherited.length > 0)
  97. {
  98. it.inherited = inherited[0].enumerateAllLocations();
  99. it.index = 0;
  100. }
  101. return it;
  102. }
  103. protected boolean hasMoreElements (LocationEnumeration it)
  104. {
  105. if (it.inherited != null)
  106. {
  107. for (;;)
  108. {
  109. NamedLocation loc = it.nextLoc;
  110. for (;;)
  111. {
  112. it.inherited.nextLoc = loc;
  113. if (! it.inherited.hasMoreElements())
  114. {
  115. it.prevLoc = null;
  116. it.nextLoc = it.inherited.nextLoc;
  117. break;
  118. }
  119. loc = it.inherited.nextLoc;
  120. if (lookup(loc.name, loc.property) == loc)
  121. {
  122. it.nextLoc = loc;
  123. return true;
  124. }
  125. loc = loc.next;
  126. }
  127. if (++it.index == numInherited)
  128. break;
  129. it.inherited = inherited[it.index].enumerateAllLocations();
  130. }
  131. it.inherited = null;
  132. it.bindings = table;
  133. it.index = 1 << log2Size;
  134. }
  135. return super.hasMoreElements(it);
  136. }
  137. protected void toStringBase (StringBuffer sbuf)
  138. {
  139. sbuf.append(" baseTs:");
  140. sbuf.append(baseTimestamp);
  141. for (int i = 0; i < numInherited; i++)
  142. {
  143. sbuf.append(" base:");
  144. sbuf.append(inherited[i].toStringVerbose());
  145. }
  146. }
  147. }