/interpreter/tags/at2-build190607/src/edu/vub/at/objects/mirrors/OBJMirrorRoot.java
Java | 318 lines | 146 code | 49 blank | 123 comment | 5 complexity | cdcfe0872307744d68381cfbaf2d97de 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 */ 28package edu.vub.at.objects.mirrors; 29 30import edu.vub.at.actors.ATAsyncMessage; 31import edu.vub.at.exceptions.InterpreterException; 32import edu.vub.at.exceptions.XArityMismatch; 33import edu.vub.at.exceptions.XIllegalArgument; 34import edu.vub.at.objects.ATBoolean; 35import edu.vub.at.objects.ATContext; 36import edu.vub.at.objects.ATField; 37import edu.vub.at.objects.ATMethod; 38import edu.vub.at.objects.ATNil; 39import edu.vub.at.objects.ATObject; 40import edu.vub.at.objects.ATTypeTag; 41import edu.vub.at.objects.ATTable; 42import edu.vub.at.objects.coercion.NativeTypeTags; 43import edu.vub.at.objects.grammar.ATSymbol; 44import edu.vub.at.objects.natives.NATByCopy; 45import edu.vub.at.objects.natives.NATNil; 46import edu.vub.at.objects.natives.NATTable; 47import edu.vub.at.objects.natives.NATText; 48import edu.vub.at.objects.natives.grammar.AGSymbol; 49 50/** 51 * OBJMirrorRoot denotes the root node of the intercessive mirrors delegation hierarchy. 52 * 53 * Intercessive mirrors are always tied to a particular 'base' object. 54 * The default intercessive mirror is named 'mirrorroot' and is an object 55 * that understands all meta_* operations, implementing them using default semantics. 56 * It can be thought of as being defined as follows: 57 * 58 * def mirrorroot := object: { 59 * def base := object: { nil } mirroredBy: self // base of the mirror root is an empty mirage 60 * def init(b) { 61 * base := b 62 * } 63 * def invoke(@args) { <default native invocation behaviour on base> } 64 * def select(@args) { <default native selection behaviour on base> } 65 * ... 66 * } taggedAs: [ Mirror ] 67 * 68 * This object can then simply be extended / composed by other objects to deviate from the default semantics. 69 * Note that the default semantics is applied to 'base' and *not* 'self.base', in other words: 70 * although child mirrors can define their own 'base' field, it is not taken into consideration 71 * by the mirror root. This also ensures that the mirror root is not abused to enact upon a mirage 72 * for which it was not assigned to be the mirror. 73 * 74 * Hence, 'mirrors' are simply objects with the same interface as this mirrorroot object: they should be 75 * able to respond to all meta_* messages and have a 'base' field. 76 * 77 * @author smostinc 78 * @author tvcutsem 79 */ 80public final class OBJMirrorRoot extends NATByCopy implements ATObject { 81 82 // The name of the field that points to the base_level representation of a custom mirror 83 public static final AGSymbol _BASE_NAME_ = AGSymbol.jAlloc("base"); 84 85 // the native read-only 'base' field of the mirror root 86 private NATMirage base_; 87 88 /** 89 * Constructor used to initialize the initial mirror root prototype. 90 */ 91 public OBJMirrorRoot() { 92 base_ = new NATMirage(this); 93 }; 94 95 /** 96 * Constructor used for cloning: creates a shallow copy of the mirror root. 97 * @param base the base field value of the original mirror root from which 98 * this new one will be cloned. 99 */ 100 private OBJMirrorRoot(NATMirage base) { 101 base_ = base; 102 }; 103 104 /** 105 * OBJMirrorRoot's primitive 'init method, in pseudo-code: 106 * 107 * def init(newBase) { 108 * base := newBase 109 * } 110 */ 111 public ATObject base_init(ATObject[] initargs) throws InterpreterException { 112 if (initargs.length != 1) { 113 throw new XArityMismatch("init", 1, initargs.length); 114 } 115 116 NATMirage newBase = initargs[0].asMirage(); 117 // check whether the passed base field does not have a mirror assigned to it yet 118 if (newBase.getMirror() == NATNil._INSTANCE_) { 119 base_ = newBase; 120 return newBase; 121 } else { 122 throw new XIllegalArgument("mirror root's init method requires an uninitialized mirage, found: " + newBase); 123 } 124 } 125 126 /** 127 * This implementation is actually an ad hoc modification of the NATObject implementation 128 * of instance creation, dedicated for OBJMirrorRoot. Using the NATObject implementation 129 * would work perfectly, but this one is more efficient. 130 */ 131 public ATObject meta_newInstance(ATTable initargs) throws InterpreterException { 132 OBJMirrorRoot clone = new OBJMirrorRoot(base_); // same as this.meta_clone() 133 clone.base_init(initargs.asNativeTable().elements_); 134 return clone; 135 } 136 137 /* ------------------------------------ 138 * -- Extension and cloning protocol -- 139 * ------------------------------------ */ 140 141 /** 142 * The mirror root is cloned but the base field is only shallow-copied, i.e. it is shared 143 * between the clones! Normally, mirrors are instantiated rather than cloned when assigned 144 * to a new object, such that this new base field will be re-assigned to another mirage 145 * (in OBJMirrorRoot's primitive 'init' method. 146 */ 147 public ATObject meta_clone() throws InterpreterException { 148 return new OBJMirrorRoot(base_); 149 } 150 151 public ATTable meta_getTypeTags() throws InterpreterException { 152 return NATTable.of(NativeTypeTags._MIRROR_); 153 } 154 155 public NATText meta_print() throws InterpreterException { 156 return NATText.atValue("<mirror on: "+base_+">"); 157 } 158 159 160 /** 161 * The read-only field containing the mirror's base-level mirage. 162 */ 163 public NATMirage base_getBase() throws InterpreterException { 164 return base_; 165 } 166 167 168 /* ------------------------------------------ 169 * -- Slot accessing and mutating protocol -- 170 * ------------------------------------------ */ 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 /* ======================================================================== 197 * OBJMirrorRoot has a base_x method for each meta_x method defined in ATObject. 198 * Each base_x method invokes NATObject's default behaviour on the base_ NATMirage 199 * via that mirage's magic_x methods. 200 * ======================================================================== */ 201 202 public ATObject base_clone() throws InterpreterException { 203 return base_getBase().magic_clone(); 204 } 205 206 public ATTable base_getTypeTags() throws InterpreterException { 207 return base_getBase().magic_getTypeTags(); 208 } 209 210 public NATText base_print() throws InterpreterException { 211 return base_getBase().magic_print(); 212 } 213 214 public ATObject base_pass() throws InterpreterException { 215 return base_getBase().magic_pass(); 216 } 217 218 public ATObject base_resolve() throws InterpreterException { 219 return base_getBase().magic_resolve(); 220 } 221 222 public ATNil base_addField(ATField field) throws InterpreterException { 223 return base_getBase().magic_addField(field); 224 } 225 226 public ATNil base_addMethod(ATMethod method) throws InterpreterException { 227 return base_getBase().magic_addMethod(method); 228 } 229 230 public ATNil base_assignField(ATObject receiver, ATSymbol name, ATObject value) throws InterpreterException { 231 return base_getBase().magic_assignField(receiver, name, value); 232 } 233 234 public ATNil base_assignVariable(ATSymbol name, ATObject value) throws InterpreterException { 235 return base_getBase().magic_assignVariable(name, value); 236 } 237 238 public ATNil base_defineField(ATSymbol name, ATObject value) throws InterpreterException { 239 return base_getBase().magic_defineField(name, value); 240 } 241 242 public ATObject base_doesNotUnderstand(ATSymbol selector) throws InterpreterException { 243 return base_getBase().magic_doesNotUnderstand(selector); 244 } 245 246 public ATObject base_eval(ATContext ctx) throws InterpreterException { 247 return base_getBase().magic_eval(ctx); 248 } 249 250 public ATBoolean base_isExtensionOfParent() throws InterpreterException { 251 return base_getBase().magic_isExtensionOfParent(); 252 } 253 254 public ATObject base_getLexicalParent() throws InterpreterException { 255 return base_getBase().magic_getLexicalParent(); 256 } 257 258 public ATField base_grabField(ATSymbol fieldName) throws InterpreterException { 259 return base_getBase().magic_grabField(fieldName); 260 } 261 262 public ATMethod base_grabMethod(ATSymbol methodName) throws InterpreterException { 263 return base_getBase().magic_grabMethod(methodName); 264 } 265 266 public ATObject base_invoke(ATObject receiver, ATSymbol atSelector, ATTable arguments) throws InterpreterException { 267 return base_getBase().magic_invoke(receiver, atSelector, arguments); 268 } 269 270 public ATBoolean base_isCloneOf(ATObject original) throws InterpreterException { 271 return base_getBase().magic_isCloneOf(original); 272 } 273 274 public ATBoolean base_isRelatedTo(ATObject object) throws InterpreterException { 275 return base_getBase().magic_isRelatedTo(object); 276 } 277 278 public ATBoolean base_isTaggedAs(ATTypeTag type) throws InterpreterException { 279 return base_getBase().magic_isTaggedAs(type); 280 } 281 282 public ATTable base_listFields() throws InterpreterException { 283 return base_getBase().magic_listFields(); 284 } 285 286 public ATTable base_listMethods() throws InterpreterException { 287 return base_getBase().magic_listMethods(); 288 } 289 290 public ATObject base_lookup(ATSymbol selector) throws InterpreterException { 291 return base_getBase().magic_lookup(selector); 292 } 293 294 public ATObject base_newInstance(ATTable initargs) throws InterpreterException { 295 return base_getBase().magic_newInstance(initargs); 296 } 297 298 public ATObject base_quote(ATContext ctx) throws InterpreterException { 299 return base_getBase().magic_quote(ctx); 300 } 301 302 public ATObject base_receive(ATAsyncMessage message) throws InterpreterException { 303 return base_getBase().magic_receive(message); 304 } 305 306 public ATBoolean base_respondsTo(ATSymbol atSelector) throws InterpreterException { 307 return base_getBase().magic_respondsTo(atSelector); 308 } 309 310 public ATObject base_select(ATObject receiver, ATSymbol selector) throws InterpreterException { 311 return base_getBase().magic_select(receiver, selector); 312 } 313 314 public ATObject base_send(ATAsyncMessage message) throws InterpreterException { 315 return base_getBase().magic_send(message); 316 } 317 318}