/interpreter/tags/at2dist091109/src/edu/vub/at/objects/ATObject.java
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