/interpreter/tags/reactive-pattern-matching/src/edu/vub/at/objects/mirrors/NATMirrorRoot.java

http://ambienttalk.googlecode.com/ · Java · 326 lines · 155 code · 48 blank · 123 comment · 10 complexity · 148ee90e1e85ee1fe21e2ec04f6432a0 MD5 · raw file

  1. /**
  2. * AmbientTalk/2 Project
  3. * OBJMirrorRoot.java created on Oct 3, 2006 at 3:26:08 PM
  4. * (c) Programming Technology Lab, 2006 - 2007
  5. * Authors: Tom Van Cutsem & Stijn Mostinckx
  6. *
  7. * Permission is hereby granted, free of charge, to any person
  8. * obtaining a copy of this software and associated documentation
  9. * files (the "Software"), to deal in the Software without
  10. * restriction, including without limitation the rights to use,
  11. * copy, modify, merge, publish, distribute, sublicense, and/or
  12. * sell copies of the Software, and to permit persons to whom the
  13. * Software is furnished to do so, subject to the following
  14. * conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be
  17. * included in all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  20. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  21. * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  22. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  23. * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  24. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  25. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  26. * OTHER DEALINGS IN THE SOFTWARE.
  27. */
  28. package edu.vub.at.objects.mirrors;
  29. import edu.vub.at.actors.ATAsyncMessage;
  30. import edu.vub.at.eval.Evaluator;
  31. import edu.vub.at.exceptions.InterpreterException;
  32. import edu.vub.at.exceptions.XArityMismatch;
  33. import edu.vub.at.exceptions.XIllegalArgument;
  34. import edu.vub.at.objects.ATBoolean;
  35. import edu.vub.at.objects.ATContext;
  36. import edu.vub.at.objects.ATField;
  37. import edu.vub.at.objects.ATMethod;
  38. import edu.vub.at.objects.ATMethodInvocation;
  39. import edu.vub.at.objects.ATNil;
  40. import edu.vub.at.objects.ATObject;
  41. import edu.vub.at.objects.ATTable;
  42. import edu.vub.at.objects.ATTypeTag;
  43. import edu.vub.at.objects.coercion.NativeTypeTags;
  44. import edu.vub.at.objects.grammar.ATSymbol;
  45. import edu.vub.at.objects.natives.NATByCopy;
  46. import edu.vub.at.objects.natives.NATTable;
  47. import edu.vub.at.objects.natives.NATText;
  48. import edu.vub.at.objects.natives.grammar.AGSymbol;
  49. import edu.vub.at.util.logging.Logging;
  50. import java.io.IOException;
  51. /**
  52. * This class denotes the root node of the intercessive mirrors delegation hierarchy.
  53. *
  54. * Intercessive mirrors are always tied to a particular 'base' object.
  55. * The default intercessive mirror is named 'mirrorroot' and is an object
  56. * that understands all meta_* operations, implementing them using default semantics.
  57. * It can be thought of as being defined as follows:
  58. *
  59. * def mirrorroot := object: {
  60. * def base := object: { nil } mirroredBy: self // base of the mirror root is an empty mirage
  61. * def init(b) {
  62. * base := b
  63. * }
  64. * def invoke(@args) { <default native invocation behaviour on base> }
  65. * def select(@args) { <default native selection behaviour on base> }
  66. * ...
  67. * } taggedAs: [ Mirror ]
  68. *
  69. * This object can then simply be extended / composed by other objects to deviate from the default semantics.
  70. * Note that the default semantics is applied to 'base' and *not* 'self.base', in other words:
  71. * although child mirrors can define their own 'base' field, it is not taken into consideration
  72. * by the mirror root. This also ensures that the mirror root is not abused to enact upon a mirage
  73. * for which it was not assigned to be the mirror.
  74. *
  75. * Hence, 'mirrors' are simply objects with the same interface as this mirrorroot object: they should be
  76. * able to respond to all meta_* messages and have a 'base' field.
  77. *
  78. * @author tvcutsem, smostinc
  79. */
  80. public final class NATMirrorRoot extends NATByCopy implements ATObject {
  81. // The name of the field that points to the base_level representation of a custom mirror
  82. public static final AGSymbol _BASE_NAME_ = AGSymbol.jAlloc("base");
  83. // the native read-only 'base' field of the mirror root
  84. private NATMirage base_;
  85. private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
  86. try {
  87. in.defaultReadObject();
  88. } catch(IOException e) {
  89. Logging.Actor_LOG.fatal("Failed to reconstruct an OBJMirrorRoot", e);
  90. throw e;
  91. }
  92. }
  93. /**
  94. * Constructor used to initialize the initial mirror root prototype.
  95. */
  96. public NATMirrorRoot() {
  97. base_ = new NATMirage(this);
  98. };
  99. /**
  100. * Constructor used for cloning: creates a shallow copy of the mirror root.
  101. * @param base the base field value of the original mirror root from which
  102. * this new one will be cloned.
  103. */
  104. private NATMirrorRoot(NATMirage base) {
  105. base_ = base;
  106. };
  107. /**
  108. * OBJMirrorRoot's primitive 'init method, in pseudo-code:
  109. *
  110. * def init(newBase) {
  111. * base := newBase
  112. * }
  113. */
  114. public ATObject base_init(ATObject[] initargs) throws InterpreterException {
  115. if (initargs.length != 1) {
  116. throw new XArityMismatch("init", 1, initargs.length);
  117. }
  118. NATMirage newBase = initargs[0].asMirage();
  119. // check whether the passed base field does not have a mirror assigned to it yet
  120. if (newBase.getMirror() == Evaluator.getNil()) {
  121. base_ = newBase;
  122. return newBase;
  123. } else {
  124. throw new XIllegalArgument("mirror root's init method requires an uninitialized mirage, found: " + newBase);
  125. }
  126. }
  127. /**
  128. * This implementation is actually an ad hoc modification of the NATObject implementation
  129. * of instance creation, dedicated for the mirror root. Using the NATObject implementation
  130. * would work perfectly, but this one is more efficient.
  131. */
  132. public ATObject meta_newInstance(ATTable initargs) throws InterpreterException {
  133. ATObject[] initargz = initargs.asNativeTable().elements_;
  134. if (initargz.length != 1) {
  135. throw new XArityMismatch("newInstance", 1, initargz.length);
  136. }
  137. NATMirage newBase = initargz[0].asMirage();
  138. // check whether the passed base field does not have a mirror assigned to it yet
  139. if (newBase.getMirror() == Evaluator.getNil()) {
  140. return new NATMirrorRoot(newBase);
  141. } else {
  142. throw new XIllegalArgument("mirror root's init method requires an uninitialized mirage, found: " + newBase);
  143. }
  144. }
  145. /* ------------------------------------
  146. * -- Extension and cloning protocol --
  147. * ------------------------------------ */
  148. /**
  149. * The mirror root is cloned but the base field is only shallow-copied, i.e. it is shared
  150. * between the clones! Normally, mirrors are instantiated rather than cloned when assigned
  151. * to a new object, such that this new base field will be re-assigned to another mirage
  152. * (in {@link NATMirrorRoot#base_init(ATObject[])}).
  153. */
  154. public ATObject meta_clone() throws InterpreterException {
  155. return new NATMirrorRoot(base_);
  156. }
  157. public ATTable meta_typeTags() throws InterpreterException {
  158. return NATTable.of(NativeTypeTags._MIRROR_);
  159. }
  160. public NATText meta_print() throws InterpreterException {
  161. return NATText.atValue("<mirror on: "+base_+">");
  162. }
  163. /**
  164. * The read-only field containing the mirror's base-level mirage.
  165. */
  166. public NATMirage base_base() throws InterpreterException {
  167. return base_;
  168. }
  169. /* ------------------------------------------
  170. * -- Slot accessing and mutating protocol --
  171. * ------------------------------------------ */
  172. /*
  173. * <p>The effect of selecting fields or methods on a mirror (through meta_select)
  174. * consists of checking whether the requested selector matches a field of the
  175. * principal wrapped by this mirror. If this is the case, the principal's
  176. * ('meta_get' + selector) method will be invoked. Else the selector might
  177. * identify one of the principal's meta-operations. If this is the case, then
  178. * an AmbientTalk representation of the Java method ('meta_' + selector) will
  179. * be returned. </p>
  180. *
  181. * <p>Because an explicit AmbientTalk method invocation must be converted into
  182. * an implicit Java method invocation, the invocation must be deified ('upped').
  183. * To uphold stratification of the mirror architecture, the result of this
  184. * operation should be a mirror on the result of the Java method invocation.</p>
  185. *
  186. * <p>Note that only when the principal does not have a matching meta_level field
  187. * or method the mirror itself will be tested for a corresponding base_level
  188. * behaviour (e.g. for its base field or for operators such as ==). In the
  189. * latter case, stratification is not enforced. This is due to the fact that
  190. * the said fields and methods are not meta-level behaviour, rather they are
  191. * base-level operations which happen to be applicable on a mirror. An added
  192. * advantage of this technique is that it permits a mirror to have a field
  193. * referring to its principal.</p>
  194. */
  195. /* ========================================================================
  196. * OBJMirrorRoot has a base_x method for each meta_x method defined in ATObject.
  197. * Each base_x method invokes NATObject's default behaviour on the base_ NATMirage
  198. * via that mirage's magic_x methods.
  199. * ======================================================================== */
  200. public ATObject base_clone() throws InterpreterException {
  201. return base_base().magic_clone();
  202. }
  203. public ATTable base_typeTags() throws InterpreterException {
  204. return base_base().magic_typeTags();
  205. }
  206. public NATText base_print() throws InterpreterException {
  207. return base_base().magic_print();
  208. }
  209. public ATObject base_pass() throws InterpreterException {
  210. return base_base().magic_pass();
  211. }
  212. public ATObject base_resolve() throws InterpreterException {
  213. return base_base().magic_resolve();
  214. }
  215. public ATNil base_addField(ATField field) throws InterpreterException {
  216. return base_base().magic_addField(field);
  217. }
  218. public ATNil base_addMethod(ATMethod method) throws InterpreterException {
  219. return base_base().magic_addMethod(method);
  220. }
  221. public ATNil base_defineField(ATSymbol name, ATObject value) throws InterpreterException {
  222. return base_base().magic_defineField(name, value);
  223. }
  224. public ATObject base_doesNotUnderstand(ATSymbol selector) throws InterpreterException {
  225. return base_base().magic_doesNotUnderstand(selector);
  226. }
  227. public ATObject base_eval(ATContext ctx) throws InterpreterException {
  228. return base_base().magic_eval(ctx);
  229. }
  230. public ATBoolean base_isExtensionOfParent() throws InterpreterException {
  231. return base_base().magic_isExtensionOfParent();
  232. }
  233. public ATObject base_invokeField(ATObject rcv, ATSymbol sym) throws InterpreterException {
  234. return base_base().magic_invokeField(rcv, sym);
  235. }
  236. public ATField base_grabField(ATSymbol fieldName) throws InterpreterException {
  237. return base_base().magic_grabField(fieldName);
  238. }
  239. public ATMethod base_grabMethod(ATSymbol methodName) throws InterpreterException {
  240. return base_base().magic_grabMethod(methodName);
  241. }
  242. public ATObject base_invoke(ATObject receiver, ATMethodInvocation inv) throws InterpreterException {
  243. return base_base().magic_invoke(receiver, inv);
  244. }
  245. public ATBoolean base_isCloneOf(ATObject original) throws InterpreterException {
  246. return base_base().magic_isCloneOf(original);
  247. }
  248. public ATBoolean base_isRelatedTo(ATObject object) throws InterpreterException {
  249. return base_base().magic_isRelatedTo(object);
  250. }
  251. public ATBoolean base_isTaggedAs(ATTypeTag type) throws InterpreterException {
  252. return base_base().magic_isTaggedAs(type);
  253. }
  254. public ATTable base_listFields() throws InterpreterException {
  255. return base_base().magic_listFields();
  256. }
  257. public ATTable base_listMethods() throws InterpreterException {
  258. return base_base().magic_listMethods();
  259. }
  260. public ATObject base_newInstance(ATTable initargs) throws InterpreterException {
  261. return base_base().magic_newInstance(initargs);
  262. }
  263. public ATObject base_quote(ATContext ctx) throws InterpreterException {
  264. return base_base().magic_quote(ctx);
  265. }
  266. public ATObject base_receive(ATAsyncMessage message) throws InterpreterException {
  267. return base_base().magic_receive(message);
  268. }
  269. public ATBoolean base_respondsTo(ATSymbol atSelector) throws InterpreterException {
  270. return base_base().magic_respondsTo(atSelector);
  271. }
  272. public ATObject base_select(ATObject receiver, ATSymbol selector) throws InterpreterException {
  273. return base_base().magic_select(receiver, selector);
  274. }
  275. public ATObject base_send(ATObject receiver, ATAsyncMessage message) throws InterpreterException {
  276. return base_base().magic_send(receiver, message);
  277. }
  278. }