PageRenderTime 38ms CodeModel.GetById 15ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/interpreter/tags/at2dist091109/src/edu/vub/at/objects/ATObject.java

http://ambienttalk.googlecode.com/
Java | 1057 lines | 69 code | 62 blank | 926 comment | 0 complexity | 97e3d39e2b8690822df7304796093f38 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1/**
  2 * AmbientTalk/2 Project
  3 * ATObject.java created on 13-jul-2006 at 15:33:42
  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;
 29
 30import edu.vub.at.actors.ATAsyncMessage;
 31import edu.vub.at.exceptions.InterpreterException;
 32import edu.vub.at.exceptions.XArityMismatch;
 33import edu.vub.at.exceptions.XDuplicateSlot;
 34import edu.vub.at.exceptions.XIllegalQuote;
 35import edu.vub.at.exceptions.XIllegalUnquote;
 36import edu.vub.at.exceptions.XObjectOffline;
 37import edu.vub.at.exceptions.XSelectorNotFound;
 38import edu.vub.at.exceptions.XUnassignableField;
 39import edu.vub.at.exceptions.XUndefinedSlot;
 40import edu.vub.at.objects.coercion.ATConversions;
 41import edu.vub.at.objects.grammar.ATAssignmentSymbol;
 42import edu.vub.at.objects.grammar.ATSymbol;
 43import edu.vub.at.objects.mirrors.NATMirage;
 44import edu.vub.at.objects.mirrors.NATMirrorRoot;
 45import edu.vub.at.objects.natives.NATCallframe;
 46import edu.vub.at.objects.natives.NATObject;
 47import edu.vub.at.objects.natives.NATText;
 48import edu.vub.at.objects.natives.NativeATObject;
 49import edu.vub.at.objects.symbiosis.JavaClass;
 50import edu.vub.at.objects.symbiosis.JavaObject;
 51
 52/**
 53 * ATObject represents the public interface common to any AmbientTalk/2 object.
 54 * Any value representing an ambienttalk object should implement this interface.
 55 * 
 56 * More specifically, this interface actually defines two interfaces all at once:
 57 * <ul>
 58 *  <li>A <b>base-level</b> interface to AmbientTalk objects, describing all
 59 *      methods and fields that a regular AmbientTalk object understands.
 60 *  <li>A <b>meta-level</b> interface to AmbientTalk objects, describing all
 61 *      methods and fields that the <b>mirror</b> on any AmbientTalk object
 62 *      understands.
 63 * </ul>
 64 * 
 65 * In the AmbientTalk/2 Interpreter implementation, there are only a few classes
 66 * that (almost) fully implement this interface. The principal implementors are:
 67 * 
 68 * <ul>
 69 *   <li>{@link NativeATObject}: provides a default implementation for all <i>native</i> data types.
 70 *   For example, native methods, closures, abstract grammar nodes, booleans, numbers, etc.
 71 *   are all represented as AmbientTalk objects with 'native' behaviour.
 72 *   <li>{@link NATCallframe}: overrides most of the default behaviour of {@link NativeATObject} to
 73 *   implement the behaviour of call frames, also known as <i>activation records</i>. In
 74 *   AmbientTalk, call frames are the objects that together define the runtime stack.
 75 *   They are objects with support for fields but without support for actual methods.
 76 *   <li>{@link NATObject}: extends the behaviour of call frames to include support for
 77 *   full-fledged, programmer-defined objects with support for methods and delegation.
 78 *   <li>{@link JavaClass} and {@link JavaObject}: adapt the behaviour of native AmbientTalk
 79 *   objects to engage in symbiosis with either a Java class or a Java object.
 80 *   This implementation makes use of the Java Reflection API to regard Java objects
 81 *   as though it were AmbientTalk objects.
 82 *   <li>{@link NATMirage} and {@link NATMirrorRoot}: these two classes work in tandem to
 83 *   enable reflection on AmbientTalk objects. That is, because of these two classes, an
 84 *   AmbientTalk programmer can himself invoke the methods provided in this interface.
 85 *   {@link NATMirage} implements each operation in this interface by forwarding a
 86 *   downed invocation to a custom so-called <i>mirror</i> object. This mirror object
 87 *   can delegate to {@link NATMirrorRoot}, which is a special object that implements
 88 *   each meta-level operation of this interface as a base-level operation. Hence, in
 89 *   a sense, {@link NATMirrorRoot} also 'implements' this interface, but at the
 90 *   AmbientTalk level, rather than at the Java level.
 91 * </ul>
 92 * 
 93 * @author tvcutsem
 94 */
 95public interface ATObject extends ATConversions {
 96
 97    /* ------------------------------
 98      * -- Message Sending Protocol --
 99      * ------------------------------ */
100
101    /**
102     * This behavioural meta-level operation reifies the act of sending
103     * an asynchronous message.
104     * 
105     * When the base-level AmbientTalk code <code>rcv<-m()</code> is
106     * evaluated in the context of an object <tt>o</tt>, an asynchronous message
107     * <code><-m()</code> is first created by the current actor mirror.
108     * Subsequently, this message needs to be sent to the receiver. This
109     * meta-level operation is reified by this method, as if by invoking:
110     * <pre>(reflect: o).send(message)</pre>
111     * The default behaviour is to access the current actor's mirror and to
112     * ask the actor to send the message in this object's stead by invoking
113     * <pre>actor.send(message)</pre>
114     * @param receiver the object designated to receive the asynchronous message
115     * @param message the asynchronous message to be sent by this object
116     * 
117     * @return the result of message sending, which will be the value of an
118     * asynchronous message send expression.
119     */
120    public ATObject meta_send(ATObject receiver, ATAsyncMessage message) throws InterpreterException;
121    
122    /**
123     * This behavioural meta-level operation reifies the act of receiving
124     * an asynchronous message.
125     * 
126     * When an asynchronous message is sent to an AmbientTalk object, its mirror
127     * is notified of this event by the invocation of this method. The method
128     * is invoked in the same execution turn as the turn in which the message
129     * is sent. This allows the receiver (e.g. a custom eventual reference proxy)
130     * to intervene in the message sending process and return a value different
131     * than the default <tt>nil</tt> value.
132     * <p>
133     * The default behaviour of a mirror on a local reference in response to
134     * the reception of an async
135     * message is to schedule this message for execution in a later turn
136     * in its owner's message queue. The actor will then later process
137     * the message by invoking
138     * <pre>msg.process(self)</pre>
139     * In turn, the default message processing behaviour is to invoke
140     * the method corresponding to the message's selector on this object.
141     * Hence, usually a <tt>receive</tt> operation is translated into
142     * a <tt>invoke</tt> operation in a later turn. The reason for having a
143     * separate <tt>receive</tt>
144     * operation is that this enables the AmbientTalk meta-level programmer to
145     * distinguish between synchronously and asynchronously received messages.
146     * 
147     * Far references react to <tt>receive</tt> by transmitting their message
148     * to their remote target.
149     * 
150     * @param message the message that was asynchronously sent to this object
151     * @return <tt>nil</tt>, by default
152     */
153    public ATObject meta_receive(ATAsyncMessage message) throws InterpreterException;
154   
155    /**
156     * This meta-level operation reifies synchronous message sending ("method invocation").
157     * Hence, the meta-level equivalent
158     * of the base-level code <code>o.m()</code> is:
159     * <pre>(reflect: o).invoke(o,`m,[])</pre>.
160     * 
161     * Method invocation comprises selector lookup and the application of the value
162     * bound to the selector. Selector lookup first queries an object's local
163     * fields, then the method dictionary:
164     * <ul>
165     *  <li>If the selector ends with <tt>:=</tt> and matches a field, the field
166     *  is assigned if a unary argument list is specified (i.e. the field is treated
167     *  as a mutator method).
168     *  <li>Otherwise, if the selector is bound to a field containing
169     * a closure, that closure is applied to the given arguments.
170     *  <li>If the field is not bound to a closure, the field value is returned provided no arguments were
171     * specified (i.e. the field is treated like an accessor method).
172     *  <li>If the selector is bound to a method, the method is applied.
173     *  <li>If the selector is not found, the search continues in the objects <i>dynamic parent</i>.
174     * </ul>
175     * <p>
176     * Note also that the first argument to <tt>invoke</tt> denotes the
177     * so-called "receiver" of the invocation. It is this object to which
178     * the <tt>self</tt> pseudo-variable should be bound during method execution.
179     * 
180     * @see #meta_doesNotUnderstand(ATSymbol) for what happens if the selector
181     * is not found.
182     *
183     * @param delegate the object to which <tt>self</tt> is bound during execution
184     * of the method
185     * @param invocation an object encapsulating at least the invocation's
186     *        <tt>selector</tt> (a {@link ATSymbol}) and <tt>arguments</tt> (a {@link ATTable}).
187     * @return by default, the object returned from the invoked method
188     */
189    public ATObject meta_invoke(ATObject delegate, ATMethodInvocation invocation) throws InterpreterException;
190
191    /**
192     * This meta-level operation reifies "field selection".
193     * In other words, the base-level code
194     * <code>o.m</code>
195     * is interpreted at the meta-level as:
196     * <code>(reflect: o).invokeField(o, `m)</code>
197     * 
198     * This meta-level operation is nearly identical to {@link #meta_invoke(ATObject, ATMethodInvocation)} with one
199     * important difference. When the selector is bound to a field storing a closure, this meta-level operation
200     * does <b>not</b> auto-apply the closure, but returns the closure instead.
201     * 
202     * For all other cases, the following equality holds:
203     * <code>o.m == o.m()</code>
204     * or, at the meta-level:
205     * <code>(reflect: o).invokeField(o, `m) == (reflect: o).invoke(o, MethodInvocation.new(`m, []))</code>
206     * 
207     * This effectively means that for client objects, it should not matter whether
208     * a property is implemented as a field or as a pair of accessor/mutator methods.
209     * 
210     * @param receiver the base-level object from which the 'field' should be selected.
211     * @param selector a symbol denoting the name of the method, accessor or mutator to be invoked
212     * @return the value of a field, or the return value of a nullary method.
213     */
214    public ATObject meta_invokeField(ATObject receiver, ATSymbol selector) throws InterpreterException;
215    
216    /**
217     * This meta-level method is used to determine whether an object has a
218     * field or method corresponding to the given selector, without actually invoking
219     * or selecting any value associated with that selector.
220     * <p>
221     * The lookup process is the same as that for the <tt>invoke</tt> operation (i.e.
222     * not only the object's own fields and methods are searched, but also those of
223     * its dynamic parents).
224     * 
225     * @param selector a symbol denoting the name of a field (accessor or mutator) or method
226     * @return a boolean denoting whether the object responds to <tt>o.selector</tt>
227     */
228    public ATBoolean meta_respondsTo(ATSymbol selector) throws InterpreterException;
229
230    /**
231     * This behavioural meta-level operation reifies a failed dynamic method or field lookup.
232     * 
233     * When method invocation or field selection fails to find the selector in
234     * the dynamic parent chain of an object, rather than immediately raising an
235     * {@link XSelectorNotFound} exception, the mirror of the original receiver
236     * of the method invocation or field selection is asked to handle failed lookup.
237     * <p>
238     * The default behaviour of <tt>doesNotUnderstand</tt> is to raise an
239     * {@link XSelectorNotFound} exception.
240     * <p>
241     * This method is very reminiscent of Smalltalk's well-known
242     * <tt>doesNotUnderstand:</tt> and of Ruby's <tt>method_missing</tt> methods.
243     * There are, however, two important differences:
244     * <ul>
245     *  <li> <tt>doesNotUnderstand</tt> is a <b>meta</b>-level operation in AmbientTalk.
246     *  It is an operation defined on mirrors, not on regular objects.
247     *  <li> <tt>doesNotUnderstand</tt> in AmbientTalk relates to <i>attribute
248     *  selection</i>, not to <i>method invocation</i>. Hence, this operation is
249     *  more general in AmbientTalk than in Smalltalk: it intercepts both failed
250     *  method invocations as well as failed field selections. Hence, it can be used
251     *  to model "virtual" fields. This shows in the interface: this operation
252     *  does not consume the actual arguments of a failed method invocation. Moreover,
253     *  a closure should be returned which can subsequently be applied for failed invocations.
254     *  Failed selections can simply return this closure without application. Hence, arguments
255     *  should be consumed by means of currying, e.g. by making <tt>doesNotUnderstand</tt>
256     *  return a block which can then take the arguments table as its sole parameter.
257     * </ul>
258     *
259     * @param selector a symbol denoting the name of a method or field that could not be found
260     * @return by default, this operation does not return a value, but raises an exception instead.
261     * @throws edu.vub.at.exceptions.XSelectorNotFound the default reaction to a failed selection
262     */
263    public ATClosure meta_doesNotUnderstand(ATSymbol selector) throws InterpreterException;
264
265    /* -----------------------------
266     * -- Object Passing protocol --
267     * ----------------------------- */
268
269    /**
270     * This behavioural meta-level operation reifies object serialization.
271     * 
272     * When an AmbientTalk object crosses actor boundaries, e.g. by means of
273     * parameter passing, as a return value or because it was explicitly
274     * exported, this meta-level operation is invoked on the object's mirror.
275     * <p>
276     * This operation allows objects to specify themselves how they should
277     * be parameter-passed during inter-actor communication. The interpreter
278     * will never pass an object to another actor directly, but instead always
279     * parameter-passes the <i>return value</i> of invoing <tt>pass()</tt> on
280     * the object's mirror.
281     * <p>
282     * Mirrors on by-copy objects implement <tt>pass</tt> as follows:
283     * <pre>def pass() { base }</pre>
284     * Mirrors on by-reference objects implement <tt>pass</tt> by returning
285     * a far reference to their base-level object.
286     * 
287     * @return the object to be parameter-passed instead of this object. For objects,
288     * the default is a far reference to themselves. For isolates, the default is
289     * to return themselves.
290     */
291    public ATObject meta_pass() throws InterpreterException;
292
293    /**
294     * This behavioural meta-level operation reifies object deserialization.
295     * 
296     * When an AmbientTalk object has just crossed an actor boundary (e.g.
297     * because of inter-actor message sending) this meta-level operation
298     * is invoked on the object's mirror.
299     * <p>
300     * This meta-level operation gives objects a chance to tell the interpreter
301     * which object they actually represent, because the object retained
302     * after parameter passing is the return value of the <tt>resolve</tt>
303     * operation.
304     * <p>
305     * Mirrors on by-copy objects, like isolates, implement <tt>resolve</tt> as follows:
306     * <pre>def resolve() { base }</pre>
307     * In other words, by-copy objects represent themselves. By-reference objects
308     * are paremeter passed as far references. Mirrors on far references implement
309     * <tt>resolve</tt> by trying to resolve the far reference into a local, regular
310     * object reference (which is possible if the object they point to is located
311     * in the actor in which they just arrived). If it is not possible to resolve
312     * a far reference into a local object, the far reference remains a far reference.
313     * <p>
314     * Note that for isolates, this operation also ensures that the isolate's
315     * lexical scope is rebound to the lexical root of the recipient actor.
316     *  
317     * @return the object represented by this object
318     * @throws XObjectOffline if a far reference to a local object can no longer be resolved
319     * because the object has been taken offline 
320     */
321    public ATObject meta_resolve() throws InterpreterException;
322    
323    /* ------------------------------------------
324     * -- Slot accessing and mutating protocol --
325     * ------------------------------------------ */
326    
327    /**
328     * This meta-level operation reifies first-class field or method selection. Hence, the
329     * base-level evaluation of <code>o.&x</code> is interpreted at the meta-level as:
330     * <pre>(reflect: o).select(o, `x)</pre>
331     * 
332     * The selector lookup follows the same search rules as those for <tt>invoke</tt>.
333     * That is: first an object's local fields and method dictionary are searched,
334     * and only then the object's <i>dynamic parent</i>.
335     * <p>
336     * The <tt>select</tt> operation can be used to both select fields or methods from
337     * an object. When the selector is bound to a method, the return value of
338     * <tt>select</tt> is a closure that wraps the found method in the object in which
339     * the method was found. This ensures that the method retains its context information,
340     * such as the lexical scope in which it was defined and the value of <tt>self</tt>, which
341     * will be bound to the original receiver, i.e. the first argument of <tt>select</tt>.
342     * <p>
343     * If the selector matches a field, an accessor is returned. If the selector ends with
344     * <tt>:=</tt>, a mutator is returned instead. An accessor is a nullary closure which upon
345     * application yields the field's value. A mutator is a unary closure which upon
346     * application assigns the field to the specified value.
347	 * Even for fields already bound to a closure, selecting the field returns an accessor
348	 * closure, not the bound closure itself.
349     *
350     * @see #meta_doesNotUnderstand(ATSymbol) for what happens if the selector is not found.
351     *
352     * @param receiver the dynamic receiver of the selection. If the result of the selection is
353     * a method, the closure wrapping the method will bind <tt>self</tt> to this object.
354     * @param selector a symbol denoting the name of the field or method to select.
355     * @return if selector is bound to a field, an accessor or mutator for the field; otherwise if
356     * the selector is bound to a method, a closure wrapping the method.
357     */
358    public ATClosure meta_select(ATObject receiver, ATSymbol selector) throws InterpreterException;
359
360    /**
361     * This meta-level operation reifies field definition. Hence, the base-level
362     * code <code>def x := v</code> evaluated in a lexical scope <tt>lex</tt>
363     * is interpreted at the meta-level as:
364     * <pre>(reflect: lex).defineField(`x, v)</pre>
365     * 
366     * Invoking this meta-level operation on an object's mirror adds a new field
367     * to that object. An object cannot contain two or more fields with the
368     * same name.
369     *
370     * @param name a symbol denoting the name of the new field
371     * @param value the value of the new field
372     * @return nil
373     * @throws edu.vub.at.exceptions.XDuplicateSlot if the object already has a
374     * local field with the given name
375     */
376    public ATNil meta_defineField(ATSymbol name, ATObject value) throws InterpreterException;
377
378    /* -----------------------------------------
379      * -- Cloning and instantiation protocol --
380      * ---------------------------------------- */
381
382    /**
383     * This meta-level operation reifies the act of cloning the base-level object.
384     * Hence, the code <code>clone: o</code> is interpreted at the meta-level as
385     * <pre>(reflect: o).clone()</pre>
386     * 
387     * AmbientTalk's default cloning semantics are based on shallow copying.
388     * A cloned object has copies of the original object's fields, but the values
389     * of the fields are shared between the clones. A clone has the same methods
390     * as the original object. Methods added at a later stage to the original
391     * will not affect the clone's methods and vice versa. This means that each
392     * objects has its own independent fields and methods.
393     * <p>
394     * If the cloned AmbientTalk object contains programmer-defined field objects,
395     * each of these fields is re-instantiated with the clone as a parameter. The
396     * clone is intialized with the re-instantiated fields rather than with the
397     * fields of the original object. This property helps to ensure that each
398     * object has its own independent fields.
399     * <p>
400     * If the object has a <i>shares-a</i> relationship with its parent, the object
401     * and its clone will <b>share</b> the same parent object. Shares-a relationships
402     * are the default in AmbientTalk, and they match with the semantics of
403     * shallow copying: the dynamic parent of an object is a regular field, hence
404     * its contents is shallow-copied.
405     * <p>
406     * If the object has an <i>is-a</i> relationship with its parent object, a
407     * clone of the object will receive a clone of the parent object as its parent.
408     * Hence, is-a relationships "override" the default shallow copying semantics
409     * and recursively clone the parent of an object up to a shares-a relationship.
410     * <p>
411     * If a mirage is cloned, its mirror is automatically re-instantiated with
412     * the new mirage, to ensure that each mirage has its independent mirror.
413     * @return a clone of the mirror's <tt>base</tt> object
414     */
415    public ATObject meta_clone() throws InterpreterException;
416
417    /**
418     * This meta-level operation reifies instance creation. The default
419     * implementation of an AmbientTalk object's <tt>new</tt> method is:
420     * <pre>def new(@initargs) { (reflect: self).newInstance(initargs) }</pre>
421     * 
422     * Creating a new instance of an object is a combination of:
423     * <ul>
424     *  <li>creating a clone of the object
425     *  <li>initializing the clone by invoking its <tt>init</tt> method
426     * </ul>
427     * 
428     * The default implementation is:
429     * <pre>def newInstance(initargs) {
430     *  def instance := self.clone();
431     *  instance.init(@initargs);
432     *  instance;
433     *}
434     * </pre>
435     * 
436     * Instance creation in AmbientTalk is designed to mimick class instantiation
437     * in a class-based language. Instantiating a class <tt>c</tt> requires <i>allocating</i>
438     * a new instance <tt>i</tt> and then invoking the <i>constructor</i> on that
439     * new instance. In AmbientTalk, class allocation is replaced by object
440     * <i>cloning</i>. The benefit is that an instantiated object its variables are
441     * already initialized to useful values, being those of the object from which
442     * it is instantiated. The <tt>init</tt> method plays the role of "constructor"
443     * in AmbientTalk.
444     *
445     * @param initargs a table denoting the actual arguments to be passed to
446     * the <tt>init</tt> method
447     * @return the new instance
448     */
449    public ATObject meta_newInstance(ATTable initargs) throws InterpreterException;
450
451    /* ---------------------------------
452      * -- Structural Access Protocol  --
453      * --------------------------------- */
454
455    /**
456     * This structural meta-level operation adds a field object to the receiver mirror's
457     * base object. An object cannot contain two or more fields with the same name.
458     * 
459     * Note that the field object passed as an argument serves as a <i>prototype</i>
460     * object: the actual field object added is an <i>instance</i> of the passed field object.
461     * A field object should always have an <tt>init</tt> method that takes as an argument
462     * the new host object to which it is added. This is often useful, as the behaviour
463     * of a field may depend on the object in which it resides. Because <tt>addField</tt>
464     * creates a new instance of the field, this gives the field object a chance to
465     * properly refer to its new host. 
466     * <p>
467     * As an example, here is how to add a read-only field <tt>foo</tt> initialized
468     * to <tt>5</tt> to an object <tt>obj</tt>:
469     * <pre>def makeConstantField(nam, val) {
470     *   object: {
471     *     def new(newHost) { self }; // singleton pattern
472     *     def name := nam;
473     *     def readField() { val };
474     *     def writeField(newVal) { nil };
475     *     def accessor() { (&readField).method };
476     *     def mutator() { (&writeField).method };
477     *   } taggedAs: [/.at.types.Field]
478     * };
479     * (reflect: obj).addField(makeConstantField(`foo, 5));
480     * </pre>
481     * 
482     * @param field the prototype field object whose instance should be added
483     * to the receiver's base object
484     * @return nil
485     * @throws XDuplicateSlot if the base object already has a field with the
486     * same name as the new field
487     */
488    public ATNil meta_addField(ATField field) throws InterpreterException;
489
490    /**
491     * This structural meta-level operation adds a method to the receiver
492     * mirror's base object. An object cannot contain two or more methods
493     * with the same name.
494     * 
495     * @param method a method object to add to the receiver's base object's
496     * method dictionary.
497     * @return nil
498     * @throws XDuplicateSlot if a method with the new method's selector already
499     * exists in the base object.
500     */
501    public ATNil meta_addMethod(ATMethod method) throws InterpreterException;
502
503    /**
504     * This structural meta-level operation allows the metaprogrammer to reify a
505     * field of the receiver mirror's base object. Hence, unlike <tt>select</tt>
506     * and <tt>lookup</tt>, <tt>grabField</tt> returns a <i>field object</i> rather
507     * than the <i>value</i> bound to the field. For example: one could express
508     * <code>obj.super := val</code> at the meta-level as:
509     * 
510     * <pre>
511     * def superField := (reflect: obj).grabField(`super);
512     * superField.writeField(val);
513     * </pre>
514     *
515     * Another important difference between <tt>select</tt>, <tt>lookup</tt> and
516     * <tt>grabField</tt> is that <tt>grabField</tt> only considers the fields
517     * <i>local</i> to the receiver's base object. Fields of lexical or dynamic
518     * parent objects are <i>not</i> considered.
519     *
520     * @param selector a symbol representing the name of the field to select.
521     * @return a mirror on this object's field slot.
522     * @throws XUndefinedSlot if the field cannot be found within the receiver's
523     * base object.
524     */
525    public ATField meta_grabField(ATSymbol selector) throws InterpreterException;
526
527    /**
528     * This structural meta-level operation allows the metaprogrammer to
529     * reify a method defined on the receiver mirror's base object. Note that,
530     * unlike the <tt>select</tt> or <tt>lookup</tt> operations, <tt>grabMethod</tt>
531     * returns the bare method object, i.e. <i>not</i> a closure wrapping the method.
532     * <p>
533     * Also, unlike <tt>select</tt> and <tt>lookup</tt>, <tt>grabField</tt> only
534     * considers the locally defined methods of an object, methods of lexical or
535     * dynamic parent objects are <i>not</i> considered.
536     *
537     * @param selector a symbol representing the name of the method to grab from
538     * the receiver's base object.
539     * @return the bare method object bound to the given selector.
540     * @throws XSelectorNotFound if the method object cannot be found within the
541     * receiver's base object.
542     */
543    public ATMethod meta_grabMethod(ATSymbol selector) throws InterpreterException;
544
545    /**
546     * This structural meta-level operation allows access to all of the
547     * fields defined on the receiver mirror's base object. Note that
548     * this method only returns the base object's <i>locally</i> defined
549     * fields. Fields from parent objects are not returned.
550     * 
551     * @see ATObject#meta_grabField(ATSymbol) for details about the returned
552     * field objects. 
553     * @return a table of field objects (of type {@link ATField}).
554     */
555    public ATTable meta_listFields() throws InterpreterException;
556
557    /**
558     * This structural meta-level operation allows access to all of the
559     * methods defined on the receiver mirror's base object. Note that
560     * this method only returns the base object's <i>locally</i> defined
561     * methods. Methods from parent objects are not returned.
562     * 
563     * @see ATObject#meta_grabMethod(ATSymbol) for details about the returned
564     * method objects.
565     * @return a table of method objects (of type {@link ATMethod}).
566     */
567    public ATTable meta_listMethods() throws InterpreterException;
568
569    /**
570     * This structural meta-level operation adds a slot object to the receiver mirror's
571     * base object. An object cannot contain two or more slots with the same name.
572     * 
573     * A slot is either a method or a closure. A closure serves to encapsulate access to
574     * or mutation of a field.
575     * 
576     * Care must be taken with closures when the object to which they are added is
577     * cloned or instantiated: the closure will be shared between clones!
578     * <p>
579     * As an example, here is how to add a read-only field <tt>foo</tt> initialized
580     * to <tt>5</tt> to an object <tt>obj</tt>:
581     * <pre>
582     * def [accessor,mutator] := /.at.lang.values.createFieldSlot(`foo, 5);
583     * (reflect: obj).addSlot(accessor);
584     * </pre>
585     * 
586     * @param slot the method representing the slot to be added
587     * to the receiver's base object
588     * @return nil
589     * @throws XDuplicateSlot if the base object already has a slot with the
590     * same name as the new slot
591     */
592    public ATNil meta_addSlot(ATMethod slot) throws InterpreterException;
593
594    /**
595     * This structural meta-level operation allows the metaprogrammer to reify a
596     * slot of the receiver mirror's base object. Hence, unlike <tt>select</tt>
597     * and <tt>lookup</tt>, <tt>grabSlot</tt> returns a <i>slot object</i> rather
598     * than the <i>value</i> bound to the slot. For example: one could express
599     * <code>obj.super := val</code> at the meta-level as:
600     * 
601     * <pre>
602     * def superMutator := (reflect: obj).grabSlot(`super:=);
603     * superMutator(val);
604     * </pre>
605     *
606     * Another important difference between <tt>select</tt>, <tt>lookup</tt> and
607     * <tt>grabSlot</tt> is that <tt>grabSlot</tt> only considers the slots
608     * <i>local</i> to the receiver's base object. Slots of lexical or dynamic
609     * parent objects are <i>not</i> considered.
610     *
611     * @param selector a symbol representing the name of the slot to select.
612     * @return a method representing the selected slot.
613     * @throws XUndefinedSlot if the field cannot be found within the receiver's
614     * base object.
615     */
616    public ATMethod meta_grabSlot(ATSymbol selector) throws InterpreterException;
617
618    /**
619     * This structural meta-level operation allows access to all of the
620     * slots defined on the receiver mirror's base object. Note that
621     * this method only returns the base object's <i>locally</i> defined
622     * slots. Slots from parent objects are not returned.
623     * 
624     * @see ATObject#meta_grabSlot(ATSymbol) for details about the returned
625     * slot objects. 
626     * @return a table of slot objects (of type {@link ATMethod}).
627     */
628    public ATTable meta_listSlots() throws InterpreterException;
629    
630    /**
631     * This structural meta-level operation removes a slot from the
632     * object. Note that this method only removes slots that are
633     * <i>locally</i> defined in the object.
634     * 
635     * @param selector the name of the slot to remove
636     * @return the value to which the slot was previously bound
637     * (e.g. a value or a method object)
638     * @throws XSelectorNotFound if no slot with the given name is found in the object
639     */
640    public ATObject meta_removeSlot(ATSymbol selector) throws InterpreterException;
641    
642    /**
643     * This structural meta-level operation returns whether or not
644     * the receiver mirror's base object is an <i>extension</i> of its
645     * parent object.
646     * <p>
647     * In AmbientTalk, all objects are part of a dynamic parent delegation chain:
648     * each object has a <tt>super</tt> field that denotes the object to which to
649     * delegate messages the object cannot understand itself. There are, however,
650     * two kinds of delegation links:
651     * <ul>
652     *  <li><b>IS-A</b> links: this kind of link denotes that the child object is
653     *  a true extension of its parent, and cannot meaningfully exist without the
654     *  parent's state. When the child is cloned, its parent will be cloned as well.
655     *  <li><b>SHARES-A</b> links: this kind of link denotes that the child object
656     *  simply delegates to its parent for purposes of sharing or code reuse. The
657     *  child can meaningfully exist without the parent's state. When the child is
658     *  cloned, the clone will delegate to the same parent.
659     * </ul>
660     *
661     * Examples:
662     * <pre>(reflect: (extend: parent with: code)).isExtensionOfParent() => true
663     *(reflect: (share: parent with: code)).isExtensionOfParent() => false
664     * </pre>
665     * 
666     * Note that accessing the dynamic parent itself is not a meta-level operation,
667     * the dynamic parent can simply be accessed from the base level by performing
668     * <code>obj.super</code>.
669     * 
670     * @return whether the base object extends its parent object via an
671     * <b>IS-A</b> link or not.
672     */
673    public ATBoolean meta_isExtensionOfParent() throws InterpreterException;
674    
675    /* ------------------------------------------
676      * -- Abstract Grammar evaluation protocol --
677      * ------------------------------------------ */
678
679    /**
680     * This behavioural meta-level operation reifies the evaluation of
681     * abstract grammar objects into values. For objects, this operation
682     * returns the base object itself, signifying that the evaluation
683     * function defined on objects is the identity function. In other words,
684     * objects are <i>self-evaluating</i>. Parse tree objects (first-class
685     * abstract grammar elements), however, have dedicated evaluation
686     * functions. For example, evaluating <code>x</code> is equivalent to
687     * evaluating <code>(reflect: `x).eval(ctx)</code> where <tt>ctx</tt>
688     * is a reification of the current evaluation context.
689     * 
690     * @param ctx a context object that stores the current lexical scope and
691     * the current value of <tt>self</tt>
692     * @return the value of the abstract grammar element denoted by this mirror's
693     * base object.
694     * @throws XIllegalUnquote if an unquote abstract grammar element is evaluated. Such
695     * abstract grammar elements should only be encountered in a quoted parse tree.
696     */
697    public ATObject meta_eval(ATContext ctx) throws InterpreterException;
698
699    /**
700     * This behavioural meta-level operation reifies the quotation of
701     * abstract grammar elements. Regular objects simply return themselves
702     * upon quotation. When an abstract grammar element is quoted, rather
703     * than tree-recursively invoking <tt>eval</tt> on the parse trees,
704     * <tt>quote</tt> is tree-recursively invoked. When encountering
705     * an unquote, <tt>eval</tt> is again invoked on the unquoted subtree,
706     * with the context passed as an argument to <tt>quote</tt>.
707     * 
708     * @param ctx a context object passed on to be used in subsequent evaluations.
709     * @throws XIllegalQuote exception whenever an unquote-splice unquotation is discovered
710     * in an Abstract Grammar node where the resulting table cannot be spliced.
711     */
712    public ATObject meta_quote(ATContext ctx) throws InterpreterException;
713
714    /**
715     * This behavioural meta-level operation reifies the act of printing
716     * the base object in the read-eval-print loop. This operation may be
717     * overridden by mirrors to customise the printed representation of
718     * their base object.
719     * 
720     * @return a text value denoting a human-readable representation of the object.
721     */
722    public NATText meta_print() throws InterpreterException;
723
724    /* ----------------------------------
725     * -- Object Relational Comparison --
726     * ---------------------------------- */
727    
728    /**
729     * This meta-level operation determines whether this mirror's base object
730     * is related to the parameter object by a combination of cloning and
731     * extension operators. The default implementation is:
732     * 
733     * <pre>def isRelatedTo(object) {
734     *  self.isCloneOf(object).or: { (reflect: base.super).isRelatedTo(object) }
735     *}</pre>
736     * 
737     * @param object the object to compare this mirror's base object to
738     * @return true if the given object is a clone of the base object or a clone
739     * of the base object's parents.
740     */
741    public ATBoolean meta_isRelatedTo(ATObject object) throws InterpreterException;
742    
743    /**
744     * This meta-level operation determines whether this mirror's base object
745     * is a clone of the parameter object. The <i>is-clone-of</i> relation is transitive,
746     * so if <tt>martin</tt> is a clone of <tt>sally</tt> and <tt>sally</tt> is a clone of
747     * <tt>dolly</tt>, then <tt>martin</tt> is a clone of <tt>dolly</tt> as well.
748     * The relation is reflexive: <tt>dolly</tt> is a clone of itself.
749     * The relation is symmetric: <tt>dolly</tt> is also a clone of <tt>sally</tt>.
750     * 
751     * @param other the object to check the is-clone-of relationship with.
752     * @return true if the base object and the parameter object are clones (i.e. one
753     * was created by cloning the other), false otherwise.
754     */
755    public ATBoolean meta_isCloneOf(ATObject other) throws InterpreterException;
756
757    /* ---------------------------------
758     * -- Type Testing and Querying --
759     * --------------------------------- */
760    
761    /**
762     * Tests whether the receiver mirror's base object is tagged as a particular type.
763     * 
764     * The default implementation first compares the object's local type tags to the given type
765     * by means of the {@link ATTypeTag#base_isSubtypeOf(ATTypeTag)} method. If no local type
766     * is found, the test is applied recursively on this object's dynamic parent. In code:
767     * <pre>def isTaggedAs(type) {
768     *  (nil != (self.tagsOf: object).find: { |localType|
769	 *    localType.isSubtypeOf(type)
770	 *  }).or: { (reflect: base.super).isTaggedAs(type) }
771	 * };
772     * </pre>
773     * 
774     * The primitive method <tt>is: obj taggedAs: type</tt> is defined in terms of this
775     * method:
776     * <pre>
777     * def is: obj taggedAs: type {
778     *  (reflect: obj).isTaggedAs(type)
779     *};
780     * </pre>
781     * 
782     * @param type the type tag object to check for
783     * @return true if this mirror's base object or one of its parent objects is tagged
784     * with a subtype of the given type, false otherwise.
785     */
786    public ATBoolean meta_isTaggedAs(ATTypeTag type) throws InterpreterException;
787    
788    /**
789     * Returns all of the local type tags of this object. The primitive method
790     * <tt>tagsOf: obj</tt> is defined in terms of this method:
791     * 
792     * <pre>
793     * def tagsOf: obj {
794     *  (reflect: obj).typeTags
795     *};
796     * </pre>
797     * 
798     * @return a table of the type tags that were attached directly to this mirror's base
799     * object. The type tags of its parent objects are not returned.
800     */
801    public ATTable meta_typeTags() throws InterpreterException;
802    
803     /* -------------------------------
804      * - Base Level Object interface -
805      * ------------------------------- */
806
807    /**
808     * Bound to the dynamic parent of this object.
809     * 
810     * The dynamic parent of an object is the object to which failed
811     * selection or invocation requests or type tests are delegated to.
812     * 
813     * @return the current dynamic parent of this object.
814     */
815    public ATObject base_super() throws InterpreterException;
816    
817    /**
818     * The identity operator. In AmbientTalk, equality of objects
819     * is by default pointer-equality (i.e. objects are equal only
820     * if they are identical).
821     * 
822     * @return by default, true if the parameter object and this object are identical,
823     * false otherwise.
824     */
825    // public ATBoolean base__opeql__opeql_(ATObject other) throws InterpreterException;
826    
827    /**
828     * The object instantiation method. Note that in class-based OO languages,
829     * this method is usually at the level of the <i>class</i>. In AmbientTalk,
830     * this method is situated at the object-level directly. It can be overridden
831     * to e.g. enforce the singleton pattern or to return instances of other
832     * objects.
833     * 
834     * The default implementation of this method is:
835     * <pre>def new(@args) {
836     *  (reflect: self).newInstance(@args)
837     *};
838     * </pre>
839     * 
840     * This is a primitive method, present by default in every AmbientTalk
841     * object but redefinable by the programmer.
842     * 
843     * @see ATObject#meta_newInstance(ATTable) for a description of object instantiation.
844     * @param initargs the variable argument list to pass to the <tt>init</tt> method.
845     * @return by default, the new instance of this mirror's base object.
846     */
847    // public ATObject base_new(ATObject[] initargs) throws InterpreterException;
848
849    /**
850     * The object initialisation method. In class-based languages, this method
851     * is often called the constructor. AmbientTalk only supports one constructor
852     * per object, but thanks to variable argument lists and optional parameters,
853     * the same flexibility as defining multiple constructors can often be achieved.
854     * Also, by overriding <tt>new</tt>, the developer may invoke additional methods
855     * on newly created objects if this is desirable.
856     * 
857     * The default implementation of this method is:
858     * <pre>def init(@args) {
859     *  super^init(@args)
860     *};
861     * </pre>
862     * 
863     * This is a primitive method, present by default in every AmbientTalk
864     * object but redefinable by the programmer.
865     * 
866     * @see ATObject#meta_newInstance(ATTable) for a description of object initialisation.
867     * @param initargs the arguments to the <tt>init</tt> constructor method.
868     * @return the return value of invoking the <tt>init</tt> method. Note that
869     * this value is <i>discarded</i> when <tt>init</tt> is invoked from the
870     * <tt>newInstance</tt> meta-level operation.
871     */
872    // public ATObject base_init(ATObject[] initargs) throws InterpreterException;
873    
874    /* -----------------------------------------
875     * - Implementation-Level Object interface -
876     * ----------------------------------------- */
877    
878    /**
879     * Implementation-level shortcut for method invocation that foregoes the creation of
880     * a 'method invocation' object, but rather passes the selector and arguments directly
881     * to the implementation.
882     */
883    public ATObject impl_invoke(ATObject delegate, ATSymbol selector, ATTable arguments) throws InterpreterException;
884    
885    /**
886     * The <tt>lexicalParent</tt> field of a mirror denotes the lexical parent
887     * pointer of the mirror's base object. The lexical parent is the enclosing
888     * <i>lexical scope</i> in which the object was defined.
889     * 
890     * @return the object denoting this mirror's base object's lexically
891     * enclosing scope.
892     */
893    public ATObject impl_lexicalParent() throws InterpreterException;
894    
895	/**
896	 * Interprets <code>o.x()</code> or <code>o.m(arg)</code>.
897	 * Implements slot access. This method is an implementation-level method (not part of the MOP).
898	 * @param receiver the dynamic receiver of the slot invocation.
899	 * @param selector a regular symbol denoting the slot accessor.
900	 * @param arguments the actual arguments to the slot invocation.
901	 * @return the result of applying the accessor.
902	 * @throws XArityMismatch if a field accessor is not invoked with exactly zero arguments.
903	 */
904	public ATObject impl_invokeAccessor(ATObject receiver, ATSymbol selector, ATTable arguments) throws InterpreterException;
905	
906    /**
907     * Interprets <code>o.x := v</code>.
908     * Implements slot mutation. This method is an implementation-level method (not part of the MOP).
909     * @param receiver the dynamic receiver of the slot invocation.
910	 * @param selector an assignment symbol denoting which slot to invoke.
911	 * @param arguments the actual arguments to the slot invocation.
912	 * @return the result of applying the mutator.
913	 * @throws XArityMismatch if a field mutator is not invoked with exactly one argument.
914     */
915	public ATObject impl_invokeMutator(ATObject receiver, ATAssignmentSymbol selector, ATTable arguments) throws InterpreterException;
916	
917	/**
918	 * Interprets <code>o.&m</code>.
919	 * Implements slot accessor selection. This method is an implementation-level method (not part of the MOP).
920	 * @param receiver the dynamic receiver of the slot selection.
921	 * @param selector a regular symbol denoting the accessor to select.
922	 * @return a closure wrapping the selected method or an accessor for a field.
923	 */
924	public ATClosure impl_selectAccessor(ATObject receiver, ATSymbol selector) throws InterpreterException;
925	
926	/**
927	 * Interprets <code>o.&m:=</code>.
928	 * Implements slot mutator selection. This method is an implementation-level method (not part of the MOP).
929	 * @param receiver the dynamic receiver of the slot selection.
930	 * @param selector an assignment symbol denoting the mutator to select.
931	 * @return a closure representing the mutator of a given slot.
932	 */
933	public ATClosure impl_selectMutator(ATObject receiver, ATAssignmentSymbol selector) throws InterpreterException;
934	
935	
936    /**
937     * Interprets <code>x := v</code> (equivalent to <code>x:=(v)</code>) or <code>f(v)</code>.
938     * Implements functions calls and lexical access to variables.
939     * This method is an implementation-level method (not part of the MOP).
940
941     * Variable lookup first queries the local fields of this object, then the local
942     * method dictionary. If the selector is not found, the search continues in
943     * this object's <i>lexical parent</i>. Hence, variable lookup follows
944     * <b>lexical scoping rules</b>.
945     * <p>
946     * Similar to the behaviour of <tt>invoke</tt>, if the selector is bound to a
947     * field rather than a method, <tt>call</tt> treats the field as an accessor
948     * or mutator method (depending on the selector).
949     * <p>
950     * Note that, unlike <tt>invoke</tt> and <tt>select</tt>, <tt>call</tt> does
951     * not give rise to the invocation of <tt>doesNotUnderstand</tt> if the selector
952     * was not found. The reason for this is that lexical lookup is a static process
953     * for which it makes less sense to provide dynamic interception facilities.
954     *
955     * @param selector a symbol denoting the name of the field or method to look up lexically.
956     * @param arguments the arguments to the lexically scoped function call.
957     * @return if selector is bound to a field, the value of the field; otherwise if selector
958     * is bound to a method, the return value of the method.
959     * @throws XUndefinedSlot if the selector could not be found in the lexical scope of this object.
960     */
961    public ATObject impl_call(ATSymbol selector, ATTable arguments) throws InterpreterException;
962    
963    /**
964     * Interprets <code>f(v)</code>.
965     * Implements the protocol to access lexical variables and methods. This operation (which is not exposed
966     * as part of the MOP) locates the lexically visible binding with the given selector and will return 
967     * the value of the slot.
968     * <p>
969     * When this object has a local slot corresponding to the selector:
970     * <ul>
971     * <li> and the slot contains a method or closure, it will be applied with the given arguments (within a context
972     *   where self is bound to this object)
973     * <li> and the slot contains a value and the argumentlist is empty, the value is returned
974     * <li> and the slot contains a value and the argumentlist is not empty, an arity mismatch exception is raised
975     * </ul>
976     * <p>
977     * When no local slot is found, lookup continues along the lexical parent chain. When the lexical chain is 
978     * completely traversed, an undefined slot exception is raised.
979     */
980    public ATObject impl_callAccessor(ATSymbol selector, ATTable arguments) throws InterpreterException;
981    
982    /**
983     * Interprets <code>x := v</code> (which is equivalent to <code>x:=(v)</code>.
984     * Implements the protocol to assign lexical variables. This operation (which is not exposed as part of the MOP) 
985     * locates slots to assign corresponding to a specific assignment symbol (selector + ":=") and looks for:
986     * <ol>
987     * <li> a mutator method with the specified assignment symbol (i.e. including the ":=") which can then be 
988     * invoked with the provided arguments.
989     * <li> a field with a corresponding selector (i.e. without the ":=") which is then treated as if it were
990     * a unary mutator method.
991     * </ol>
992     * 
993     * If the slot is a method slot, an {@link XUnassignableField} exception is raised, otherwise t

Large files files are truncated, but you can click here to view the full file