PageRenderTime 79ms CodeModel.GetById 66ms app.highlight 9ms RepoModel.GetById 2ms app.codeStats 0ms

/interpreter/tags/at2-build190607/src/edu/vub/at/objects/mirrors/OBJMirrorRoot.java

http://ambienttalk.googlecode.com/
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}