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