PageRenderTime 36ms CodeModel.GetById 14ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 0ms

/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 */
 28package edu.vub.at.objects.mirrors;
 29
 30import edu.vub.at.actors.ATAsyncMessage;
 31import edu.vub.at.eval.Evaluator;
 32import edu.vub.at.exceptions.InterpreterException;
 33import edu.vub.at.exceptions.XArityMismatch;
 34import edu.vub.at.exceptions.XIllegalArgument;
 35import edu.vub.at.objects.ATBoolean;
 36import edu.vub.at.objects.ATContext;
 37import edu.vub.at.objects.ATField;
 38import edu.vub.at.objects.ATMethod;
 39import edu.vub.at.objects.ATMethodInvocation;
 40import edu.vub.at.objects.ATNil;
 41import edu.vub.at.objects.ATObject;
 42import edu.vub.at.objects.ATTable;
 43import edu.vub.at.objects.ATTypeTag;
 44import edu.vub.at.objects.coercion.NativeTypeTags;
 45import edu.vub.at.objects.grammar.ATSymbol;
 46import edu.vub.at.objects.natives.NATByCopy;
 47import edu.vub.at.objects.natives.NATTable;
 48import edu.vub.at.objects.natives.NATText;
 49import edu.vub.at.objects.natives.grammar.AGSymbol;
 50import edu.vub.at.util.logging.Logging;
 51
 52import java.io.IOException;
 53
 54/**
 55 * This class denotes the root node of the intercessive mirrors delegation hierarchy.
 56 * 
 57 * Intercessive mirrors are always tied to a particular 'base' object.
 58 * The default intercessive mirror is named 'mirrorroot' and is an object
 59 * that understands all meta_* operations, implementing them using default semantics.
 60 * It can be thought of as being defined as follows:
 61 * 
 62 * def mirrorroot := object: {
 63 *   def base := object: { nil } mirroredBy: self // base of the mirror root is an empty mirage
 64 *   def init(b) {
 65 *     base := b
 66 *   }
 67 *   def invoke(@args) { <default native invocation behaviour on base> }
 68 *   def select(@args) { <default native selection behaviour on base> }
 69 *   ...
 70 * } taggedAs: [ Mirror ]
 71 * 
 72 * This object can then simply be extended / composed by other objects to deviate from the default semantics.
 73 * Note that the default semantics is applied to 'base' and *not* 'self.base', in other words:
 74 * although child mirrors can define their own 'base' field, it is not taken into consideration
 75 * by the mirror root. This also ensures that the mirror root is not abused to enact upon a mirage
 76 * for which it was not assigned to be the mirror.
 77 * 
 78 * Hence, 'mirrors' are simply objects with the same interface as this mirrorroot object: they should be
 79 * able to respond to all meta_* messages and have a 'base' field.
 80 * 
 81 * @author tvcutsem, smostinc
 82 */
 83public final class NATMirrorRoot extends NATByCopy implements ATObject {
 84	
 85	// The name of the field that points to the base_level representation of a custom mirror
 86	public static final AGSymbol _BASE_NAME_ = AGSymbol.jAlloc("base");
 87	
 88	// the native read-only 'base' field of the mirror root
 89	private NATMirage base_;
 90	
 91	private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
 92		try {
 93			in.defaultReadObject();
 94		} catch(IOException e) {
 95			Logging.Actor_LOG.fatal("Failed to reconstruct an OBJMirrorRoot", e);
 96			throw e;
 97		}
 98	}
 99	
100	/**
101	 * Constructor used to initialize the initial mirror root prototype.
102	 */
103	public NATMirrorRoot() {
104		base_ = new NATMirage(this);
105	};
106
107	/**
108	 * Constructor used for cloning: creates a shallow copy of the mirror root.
109	 * @param base the base field value of the original mirror root from which
110	 * this new one will be cloned.
111	 */
112	private NATMirrorRoot(NATMirage base) {
113		base_ = base;
114	};
115
116	/**
117	 * OBJMirrorRoot's primitive 'init method, in pseudo-code:
118	 * 
119	 * def init(newBase) {
120	 *   base := newBase
121	 * }
122	 */
123	public ATObject base_init(ATObject[] initargs) throws InterpreterException {
124		if (initargs.length != 1) {
125			throw new XArityMismatch("init", 1, initargs.length);
126		}
127		
128		NATMirage newBase = initargs[0].asMirage();
129		// check whether the passed base field does not have a mirror assigned to it yet
130		if (newBase.getMirror() == Evaluator.getNil()) {
131			base_ = newBase;
132			return newBase;
133		} else {
134			throw new XIllegalArgument("mirror root's init method requires an uninitialized mirage, found: " + newBase);
135		}
136	}
137
138	/**
139	 * This implementation is actually an ad hoc modification of the NATObject implementation
140	 * of instance creation, dedicated for the mirror root. Using the NATObject implementation
141	 * would work perfectly, but this one is more efficient.
142	 */
143	public ATObject meta_newInstance(ATTable initargs) throws InterpreterException {
144		ATObject[] initargz = initargs.asNativeTable().elements_;
145		if (initargz.length != 1) {
146			throw new XArityMismatch("newInstance", 1, initargz.length);
147		}
148		NATMirage newBase = initargz[0].asMirage();
149		// check whether the passed base field does not have a mirror assigned to it yet
150		if (newBase.getMirror() == Evaluator.getNil()) {
151			return new NATMirrorRoot(newBase);
152		} else {
153			throw new XIllegalArgument("mirror root's init method requires an uninitialized mirage, found: " + newBase);
154		}
155	}
156	
157	/* ------------------------------------
158	 * -- Extension and cloning protocol --
159	 * ------------------------------------ */
160	
161	/**
162	 * The mirror root is cloned but the base field is only shallow-copied, i.e. it is shared
163	 * between the clones! Normally, mirrors are instantiated rather than cloned when assigned
164	 * to a new object, such that this new base field will be re-assigned to another mirage
165	 * (in {@link NATMirrorRoot#base_init(ATObject[])}).
166	 */
167	public ATObject meta_clone() throws InterpreterException {
168		return new NATMirrorRoot(base_);
169	}
170	
171    public ATTable meta_typeTags() throws InterpreterException {
172    	return NATTable.of(NativeTypeTags._MIRROR_);
173    }
174    
175    public NATText meta_print() throws InterpreterException {
176    	return NATText.atValue("<mirror on: "+base_+">");
177    }
178    
179	
180	/**
181	 * The read-only field containing the mirror's base-level mirage.
182	 */
183	public NATMirage base_base() throws InterpreterException {
184		return base_;
185	}
186	
187    
188	/* ------------------------------------------
189	 * -- Slot accessing and mutating protocol --
190	 * ------------------------------------------ */
191
192	/*
193	 * <p>The effect of selecting fields or methods on a mirror (through meta_select) 
194	 * consists of checking whether the requested selector matches a field of the 
195	 * principal wrapped by this mirror. If this is the case, the principal's 
196	 * ('meta_get' + selector) method will be invoked. Else the selector might 
197	 * identify one of the principal's meta-operations. If this is the case, then
198	 * an AmbientTalk representation of the Java method ('meta_' + selector) will 
199	 * be returned. </p>
200	 *  
201	 * <p>Because an explicit AmbientTalk method invocation must be converted into 
202	 * an implicit Java method invocation, the invocation must be deified ('upped').
203	 * To uphold stratification of the mirror architecture, the result of this 
204	 * operation should be a mirror on the result of the Java method invocation.</p>
205	 * 
206	 * <p>Note that only when the principal does not have a matching meta_level field 
207	 * or method the mirror itself will be tested for a corresponding base_level 
208	 * behaviour (e.g. for its base field or for operators such as ==). In the 
209	 * latter case, stratification is not enforced. This is due to the fact that 
210	 * the said fields and methods are not meta-level behaviour, rather they are 
211	 * base-level operations which happen to be applicable on a mirror. An added 
212	 * advantage of this technique is that it permits a mirror to have a field 
213	 * referring to its principal.</p>
214	 */
215	
216	/* ========================================================================
217	 * OBJMirrorRoot has a base_x method for each meta_x method defined in ATObject.
218	 * Each base_x method invokes NATObject's default behaviour on the base_ NATMirage
219	 * via that mirage's magic_x methods.
220	 * ======================================================================== */
221
222	public ATObject base_clone() throws InterpreterException {
223		return base_base().magic_clone();
224	}
225	
226    public ATTable base_typeTags() throws InterpreterException {
227		return base_base().magic_typeTags();
228    }
229    
230    public NATText base_print() throws InterpreterException {
231		return base_base().magic_print();
232    }
233	
234	public ATObject base_pass() throws InterpreterException {
235		return base_base().magic_pass();
236	}
237
238	public ATObject base_resolve() throws InterpreterException {
239		return base_base().magic_resolve();
240	}
241
242	public ATNil base_addField(ATField field) throws InterpreterException {
243		return base_base().magic_addField(field);
244	}
245
246	public ATNil base_addMethod(ATMethod method) throws InterpreterException {
247		return base_base().magic_addMethod(method);
248	}
249
250	public ATNil base_defineField(ATSymbol name, ATObject value) throws InterpreterException {
251		return base_base().magic_defineField(name, value);
252	}
253
254	public ATObject base_doesNotUnderstand(ATSymbol selector) throws InterpreterException {
255		return base_base().magic_doesNotUnderstand(selector);
256	}
257
258	public ATObject base_eval(ATContext ctx) throws InterpreterException {
259		return base_base().magic_eval(ctx);
260	}
261
262	public ATBoolean base_isExtensionOfParent() throws InterpreterException {
263		return base_base().magic_isExtensionOfParent();
264	}
265
266	public ATObject base_invokeField(ATObject rcv, ATSymbol sym) throws InterpreterException {
267		return base_base().magic_invokeField(rcv, sym);
268	}
269
270	public ATField base_grabField(ATSymbol fieldName) throws InterpreterException {
271		return base_base().magic_grabField(fieldName);
272	}
273
274	public ATMethod base_grabMethod(ATSymbol methodName) throws InterpreterException {
275		return base_base().magic_grabMethod(methodName);
276	}
277
278	public ATObject base_invoke(ATObject receiver, ATMethodInvocation inv) throws InterpreterException {
279		return base_base().magic_invoke(receiver, inv);
280	}
281
282	public ATBoolean base_isCloneOf(ATObject original) throws InterpreterException {
283		return base_base().magic_isCloneOf(original);
284	}
285
286	public ATBoolean base_isRelatedTo(ATObject object) throws InterpreterException {
287		return base_base().magic_isRelatedTo(object);
288	}
289
290	public ATBoolean base_isTaggedAs(ATTypeTag type) throws InterpreterException {
291		return base_base().magic_isTaggedAs(type);
292	}
293
294	public ATTable base_listFields() throws InterpreterException {
295		return base_base().magic_listFields();
296	}
297
298	public ATTable base_listMethods() throws InterpreterException {
299		return base_base().magic_listMethods();
300	}
301
302	public ATObject base_newInstance(ATTable initargs) throws InterpreterException {
303		return base_base().magic_newInstance(initargs);
304	}
305
306	public ATObject base_quote(ATContext ctx) throws InterpreterException {
307		return base_base().magic_quote(ctx);
308	}
309
310	public ATObject base_receive(ATAsyncMessage message) throws InterpreterException {
311		return base_base().magic_receive(message);
312	}
313
314	public ATBoolean base_respondsTo(ATSymbol atSelector) throws InterpreterException {
315		return base_base().magic_respondsTo(atSelector);
316	}
317
318	public ATObject base_select(ATObject receiver, ATSymbol selector) throws InterpreterException {
319		return base_base().magic_select(receiver, selector);
320	}
321
322	public ATObject base_send(ATObject receiver, ATAsyncMessage message) throws InterpreterException {
323		return base_base().magic_send(receiver, message);
324	}
325	
326}