PageRenderTime 61ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/interpreter/tags/at2dist110511/src/edu/vub/at/objects/natives/OBJLexicalRoot.java

http://ambienttalk.googlecode.com/
Java | 2542 lines | 1226 code | 123 blank | 1193 comment | 158 complexity | 9bfdd6fde26521118313086642bb7591 MD5 | raw file
Possible License(s): Apache-2.0, LGPL-2.0, LGPL-2.1
  1. /**
  2. * AmbientTalk/2 Project
  3. * OBJLexicalRoot.java created on 8-aug-2006 at 16:51:10
  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. */
  28. package edu.vub.at.objects.natives;
  29. import edu.vub.at.actors.ATActorMirror;
  30. import edu.vub.at.actors.ATFarReference;
  31. import edu.vub.at.actors.natives.ELActor;
  32. import edu.vub.at.actors.natives.ELVirtualMachine;
  33. import edu.vub.at.actors.natives.NATFarReference;
  34. import edu.vub.at.actors.natives.Packet;
  35. import edu.vub.at.actors.net.OBJNetwork;
  36. import edu.vub.at.eval.Evaluator;
  37. import edu.vub.at.exceptions.InterpreterException;
  38. import edu.vub.at.exceptions.XIllegalOperation;
  39. import edu.vub.at.exceptions.XUnassignableField;
  40. import edu.vub.at.exceptions.XUndefinedSlot;
  41. import edu.vub.at.objects.ATAbstractGrammar;
  42. import edu.vub.at.objects.ATBoolean;
  43. import edu.vub.at.objects.ATClosure;
  44. import edu.vub.at.objects.ATContext;
  45. import edu.vub.at.objects.ATHandler;
  46. import edu.vub.at.objects.ATMethod;
  47. import edu.vub.at.objects.ATNil;
  48. import edu.vub.at.objects.ATNumber;
  49. import edu.vub.at.objects.ATNumeric;
  50. import edu.vub.at.objects.ATObject;
  51. import edu.vub.at.objects.ATTable;
  52. import edu.vub.at.objects.ATText;
  53. import edu.vub.at.objects.ATTypeTag;
  54. import edu.vub.at.objects.coercion.NativeTypeTags;
  55. import edu.vub.at.objects.grammar.ATAssignmentSymbol;
  56. import edu.vub.at.objects.grammar.ATSymbol;
  57. import edu.vub.at.objects.mirrors.DirectNativeMethod;
  58. import edu.vub.at.objects.mirrors.JavaInterfaceAdaptor;
  59. import edu.vub.at.objects.mirrors.NATMirage;
  60. import edu.vub.at.objects.mirrors.NATMirrorRoot;
  61. import edu.vub.at.objects.mirrors.NativeClosure;
  62. import edu.vub.at.parser.NATParser;
  63. import edu.vub.at.util.logging.Logging;
  64. import java.lang.reflect.Method;
  65. import java.util.HashMap;
  66. import java.util.Iterator;
  67. import java.util.LinkedList;
  68. import java.util.List;
  69. import java.util.Set;
  70. import java.util.Map.Entry;
  71. import java.util.concurrent.atomic.AtomicInteger;
  72. /**
  73. * The singleton instance of this class represents the lexical root of an actor.
  74. * Since this lexical root is constant (it cannot be modified) and contains no mutable fields,
  75. * it is possible to share a singleton instance of this class among all actors.
  76. * <p>
  77. * The lexical root is an object containing globally visible AmbientTalk native methods.
  78. * Such methods include control structures such as <tt>if:then:else:</tt>
  79. * but also object creation methods like <tt>object:</tt> and reflective constructs
  80. * like <tt>reflect:</tt>.
  81. *
  82. * Furthermore, the lexical root is also the root of the lexical parent hierarchy for objects.
  83. * This means that this object's mirror is responsible for ending recursive meta-level methods
  84. * such as <tt>lookup</tt> and <tt>assignField</tt>.
  85. * <p>
  86. * Like any class whose instances represent native AmbientTalk objects, this class is a subclass
  87. * of {@link NativeATObject}. This means that this class can use the typical protocol of native objects
  88. * to implement base-level AmbientTalk methods as Java methods whose name is prefixed with
  89. * <tt>base_</tt>.
  90. * <p>
  91. * Note that OBJLexicalRoot is a <i>sentinel</i> class. The actual object bound to the
  92. * lexical root of an actor (accessible via the field <tt>root</tt> will be a normal
  93. * AmbientTalk object whose lexical parent is this object.
  94. * The real, empty, root object is local to each actor and is mutable. The definitions
  95. * from the <tt>init.at</tt> file are added to that object.
  96. *
  97. * @author smostinc
  98. * @author tvcutsem
  99. */
  100. public final class OBJLexicalRoot extends NATByCopy {
  101. /**
  102. * The singleton instance of the sentinel lexical root
  103. */
  104. static public final OBJLexicalRoot _INSTANCE_ = new OBJLexicalRoot();
  105. /**
  106. * Constructor made private for singleton design pattern
  107. */
  108. private OBJLexicalRoot() { }
  109. /**
  110. * The lexical root has a special lexical parent object which ends the recursion
  111. * along the lexical lookup chain. These methods cannot be implemented
  112. * directly in this class because this class still implements useful
  113. * <tt>base_</tt> Java methods which have to be invoked by means of the
  114. * implementations defined in {@link NativeATObject}.
  115. */
  116. private final NativeATObject lexicalSentinel_ = new NATByCopy() {
  117. // METHODS THAT END THE LEXICAL LOOKUP CHAIN
  118. public ATObject impl_callAccessor(ATSymbol selector, ATTable arguments) throws InterpreterException {
  119. throw new XUndefinedSlot("variable access", selector.toString());
  120. }
  121. public ATObject impl_callMutator(ATAssignmentSymbol selector, ATTable arguments) throws InterpreterException {
  122. throw new XUnassignableField(selector.toString());
  123. }
  124. public ATObject impl_callField(ATSymbol selector) throws InterpreterException {
  125. throw new XUndefinedSlot("variable access", selector.toString());
  126. }
  127. public ATClosure impl_lookupAccessor(final ATSymbol selector) throws InterpreterException {
  128. throw new XUndefinedSlot("accessor", selector.toString());
  129. }
  130. public ATClosure impl_lookupMutator(ATAssignmentSymbol selector) throws InterpreterException {
  131. throw new XUnassignableField(selector.toString());
  132. }
  133. public NATText meta_print() throws InterpreterException {
  134. return NATText.atValue("lexicalrootsentinel");
  135. }
  136. };
  137. public ATObject impl_lexicalParent() {
  138. return lexicalSentinel_;
  139. }
  140. /* -----------------------
  141. * -- Primitive Methods --
  142. * ----------------------- */
  143. /* ===============================================================================
  144. * NOTE: the code below has been replaced by dedicated syntax and AST elements.
  145. * However, the skeleton of this code may still prove useful in the future, if
  146. * we ever plan to implement all base_ native methods as true AmbientTalk methods
  147. * (i.e. as PrimitiveMethod instances).
  148. * ===============================================================================
  149. */
  150. /*
  151. private static final AGSymbol _IMPORT_NAME_ = AGSymbol.jAlloc("import:");
  152. private static final AGSymbol _IMPORT_ALIAS_NAME_ = AGSymbol.jAlloc("import:alias:");
  153. private static final AGSymbol _IMPORT_EXCLUDE_NAME_ = AGSymbol.jAlloc("import:exclude:");
  154. private static final AGSymbol _IMPORT_ALIAS_EXCLUDE_NAME_ = AGSymbol.jAlloc("import:alias:exclude:");
  155. private static final AGSymbol _SRC_PARAM_ = AGSymbol.jAlloc("sourceObject");
  156. private static final AGSymbol _ALIAS_PARAM_ = AGSymbol.jAlloc("aliases");
  157. private static final AGSymbol _EXCLUDE_PARAM_ = AGSymbol.jAlloc("exclude");
  158. */
  159. /*protected static final PrimitiveMethod _PRIM_IMPORT_ = new PrimitiveMethod(_IMPORT_NAME_, NATTable.atValue(new ATObject[] { _SRC_PARAM_ })) {
  160. public ATObject base_apply(ATTable arguments, ATContext ctx) throws InterpreterException {
  161. ATObject sourceObject = arguments.base_at(NATNumber.ONE);
  162. return performImport(sourceObject, ctx, new Hashtable(), OBJLexicalRoot.getDefaultExcludedSlots());
  163. }
  164. };*/
  165. /**
  166. * def import: sourceObject alias: [ `oldname -> `newname , ... ]
  167. */
  168. /*protected static final PrimitiveMethod _PRIM_IMPORT_ALIAS_ = new PrimitiveMethod(_IMPORT_ALIAS_NAME_, NATTable.atValue(new ATObject[] { _SRC_PARAM_, _ALIAS_PARAM_ })) {
  169. public ATObject base_apply(ATTable arguments, ATContext ctx) throws InterpreterException {
  170. ATObject sourceObject = arguments.base_at(NATNumber.ONE);
  171. ATObject aliases = arguments.base_at(NATNumber.atValue(2));
  172. return performImport(sourceObject, ctx, preprocessAliases(aliases.base_asTable()), OBJLexicalRoot.getDefaultExcludedSlots());
  173. }
  174. };*/
  175. /**
  176. * def import: sourceObject excludes: [ `name1, `name2, ... ]
  177. */
  178. /*protected static final PrimitiveMethod _PRIM_IMPORT_EXCLUDE_ = new PrimitiveMethod(_IMPORT_EXCLUDE_NAME_, NATTable.atValue(new ATObject[] { _SRC_PARAM_, _EXCLUDE_PARAM_ })) {
  179. public ATObject base_apply(ATTable arguments, ATContext ctx) throws InterpreterException {
  180. ATObject sourceObject = arguments.base_at(NATNumber.ONE);
  181. ATObject exclusions = arguments.base_at(NATNumber.atValue(2));
  182. return performImport(sourceObject, ctx, new Hashtable(), preprocessExcludes(exclusions.base_asTable()));
  183. }
  184. };*/
  185. /**
  186. * def import: sourceObject alias: [ `oldname -> `newname, ... ] excludes: [ `name1, `name2, ... ]
  187. */
  188. /*protected static final PrimitiveMethod _PRIM_IMPORT_ALIAS_EXCLUDE_ = new PrimitiveMethod(_IMPORT_ALIAS_EXCLUDE_NAME_,
  189. NATTable.atValue(new ATObject[] { _SRC_PARAM_, _ALIAS_PARAM_, _EXCLUDE_PARAM_ })) {
  190. public ATObject base_apply(ATTable arguments, ATContext ctx) throws InterpreterException {
  191. ATObject sourceObject = arguments.base_at(NATNumber.ONE);
  192. ATObject aliases = arguments.base_at(NATNumber.atValue(2));
  193. ATObject exclusions = arguments.base_at(NATNumber.atValue(3));
  194. return performImport(sourceObject, ctx, preprocessAliases(aliases.base_asTable()), preprocessExcludes(exclusions.base_asTable()));
  195. }
  196. };*/
  197. /**
  198. * Invoked whenever a new true AmbientTalk object is created that should
  199. * represent the root. This gives the lexical root a chance to install its
  200. * primitive methods.
  201. */
  202. /*public static void initializeRoot(NATObject root) {
  203. try {
  204. // add import: native
  205. root.meta_addMethod(_PRIM_IMPORT_);
  206. // add import:alias: native
  207. root.meta_addMethod(_PRIM_IMPORT_ALIAS_);
  208. // add import:exclude: native
  209. root.meta_addMethod(_PRIM_IMPORT_EXCLUDE_);
  210. // add import:alias:exclude: native
  211. root.meta_addMethod(_PRIM_IMPORT_ALIAS_EXCLUDE_);
  212. } catch (InterpreterException e) {
  213. Logging.Init_LOG.fatal("Failed to initialize the root!", e);
  214. }
  215. }*/
  216. /* ----------------------
  217. * -- Global variables --
  218. * ---------------------- */
  219. /**
  220. * <tt>nil</tt> evaluates to the nil object, which is
  221. * the empty, dynamic parent of all AmbientTalk objects.
  222. */
  223. public ATNil base_nil() {
  224. return Evaluator.getNil();
  225. }
  226. /**
  227. * <tt>true</tt> evaluates to the unique boolean true object.
  228. */
  229. public ATBoolean base_true() {
  230. return NATBoolean._TRUE_;
  231. }
  232. /**
  233. * <tt>false</tt> evaluates to the unique boolean false object.
  234. */
  235. public ATBoolean base_false() {
  236. return NATBoolean._FALSE_;
  237. }
  238. /**
  239. * <tt>/</tt> evaluates to the global namespace. It is
  240. * simply an alias for <tt>lobby</tt>.
  241. * @see #base_lobby()
  242. */
  243. public ATObject base__opdiv_() {
  244. return base_lobby();
  245. }
  246. /**
  247. * <tt>lobby</tt> evaluates to the global namespace object.
  248. * For each <tt>name=path</tt> entry on AmbientTalk's
  249. * <i>object path</i>, the lobby object contains a slot
  250. * <tt>name</tt> bound to a namespace object bound to
  251. * the directory referred to by <tt>path</tt>.
  252. * <p>
  253. * Accessing the lobby allows loading in AmbientTalk source code
  254. * from external files.
  255. */
  256. public ATObject base_lobby() {
  257. return Evaluator.getLobbyNamespace();
  258. }
  259. /**
  260. * <tt>root</tt> evaluates to the global lexical scope object.
  261. * This is the top-level object in which the definitions of
  262. * the file <tt>at/init/init.at</tt> are evaluated. All code
  263. * is assumed to be "nested" in the lexical root, so all definitions
  264. * of this object are lexically accessible.
  265. */
  266. public ATObject base_root() {
  267. return Evaluator.getGlobalLexicalScope();
  268. }
  269. /**
  270. * <tt>jlobby</tt> evaluates to the Java namespace root. It is a
  271. * special object which is part of the symbiosis infrastructure of
  272. * AmbientTalk. <tt>jlobby</tt> acts like an object that has field
  273. * names that correspond to Java package names. By selecting fields
  274. * from this object, an appropriate Java package can be created
  275. * from which a Java class can be accessed. Only the Java classes
  276. * accessible in the Java classpath are accessible.
  277. *
  278. * Example:
  279. * <code>jlobby.java.util.Vector</code> evaluates to a reference to
  280. * the Java <tt>Vector</tt> class.
  281. */
  282. public ATObject base_jlobby() {
  283. return Evaluator.getJLobbyRoot();
  284. }
  285. /**
  286. * <tt>network</tt> evaluates to the unique network control object.
  287. * It is a simple native object with two methods:
  288. * <ul>
  289. * <li><tt>network.online()</tt> makes the interpreter go online. This allows
  290. * publications of local actors to be discovered by remote objects and vice versa.
  291. * <li><tt>network.offline()</tt> makes the interpreter go offline. All
  292. * remote references to remote objects will become disconnected.
  293. * </ul>
  294. */
  295. public ATObject base_network() {
  296. return OBJNetwork._INSTANCE_;
  297. }
  298. /**
  299. * <tt>defaultMirror</tt> evaluates to the default mirror on objects. This
  300. * is the mirror encapsulating the standard AmbientTalk object semantics.
  301. * That is, it is a mirror with similar behaviour as the mirror created by
  302. * executing: <code>reflect: (object: { ... })</code>.
  303. *
  304. * The default mirror is an object with a read-only <tt>base</tt> field
  305. * that signifies the base-level object of this mirror. The main purpose
  306. * of this object is to serve as a prototype whose methods can be overridden
  307. * by custom mirrors. The syntax:
  308. * <pre>
  309. * mirror: { ... }
  310. * </pre>
  311. * is syntactic sugar for:
  312. * <pre>
  313. * extend: defaultMirror with: { ... }
  314. * </pre>
  315. *
  316. * Note that the default mirror is typed with the <tt>/.at.types.Mirror</tt> type.
  317. */
  318. public ATObject base_defaultMirror() {
  319. return Evaluator.getMirrorRoot();
  320. }
  321. /* ------------------------
  322. * -- Control Structures --
  323. * ------------------------ */
  324. /**
  325. * The <tt>if:then:</tt> control structure. Usage:
  326. * <pre>if: cond then: consequent</pre>
  327. *
  328. * pseudo-implementation:
  329. * <pre>cond.ifTrue: consequent</pre>
  330. *
  331. * Note that the consequent parameter should be a <i>closure</i>, i.e.
  332. * the caller is responsible for delaying the evaluation of the consequent!
  333. *
  334. * @param cond a boolean object
  335. * @param consequent a closure containing the code to execute if the boolean is true
  336. * @return if <tt>cond</tt> is true, the value of applying the consequent, <tt>nil</tt> otherwise
  337. */
  338. public ATObject base_if_then_(ATBoolean cond, ATClosure consequent) throws InterpreterException {
  339. return cond.base_ifTrue_(consequent);
  340. }
  341. /**
  342. * The <tt>if:then:else:</tt> control structure. Usage:
  343. * <pre>if: cond then: consequent else: alternative</pre>
  344. *
  345. * pseudo-implementation:
  346. * <pre>cond.ifTrue: consequent ifFalse: alternative</pre>
  347. *
  348. * Note that the consequent and alternative parameters should be <i>closures</i>, i.e.
  349. * the caller is responsible for delaying the evaluation of these arguments!
  350. *
  351. * @param cond a boolean object
  352. * @param consequent a closure containing the code to execute if the boolean is true
  353. * @param alternative a closure containing the code to execute if the boolean is false
  354. * @return the value of consequent if the boolean is true, the value of the alternative otherwise.
  355. */
  356. public ATObject base_if_then_else_(ATBoolean cond, ATClosure consequent, ATClosure alternative) throws InterpreterException {
  357. return cond.base_ifTrue_ifFalse_(consequent, alternative);
  358. }
  359. /**
  360. * The <tt>while:do:</tt> control structure. Usage:
  361. * <pre>while: condition do: body</pre>
  362. *
  363. * pseudo-implementation:
  364. * <pre>condition.whileTrue: body</pre>
  365. *
  366. * Note that <i>both</i> the condition and the body should be <i>closures</i>, because
  367. * they represent pieces of code that have to be executed repeatedly. Because of traditional
  368. * syntax, novice programmers are inclined to make the mistake of writing, e.g.:
  369. * <pre>while: (i < 10) do: { i := i + 1 }</pre>
  370. * Which is wrong because the first parameter should evaluate to a closure that itself
  371. * returns a boolean value, not to a boolean value directly.
  372. *
  373. * @param condition a closure expected to return a boolean object
  374. * @param body a closure containing the code to execute as long as the condition closure returns true
  375. * @return if conditions is true at least once, the last value of body, <tt>nil</tt> otherwise.
  376. */
  377. public ATObject base_while_do_(ATClosure condition, ATClosure body) throws InterpreterException {
  378. return condition.base_whileTrue_(body);
  379. }
  380. /**
  381. * The <tt>foreach:in:</tt> control structure. Usage:
  382. *
  383. * <pre>foreach: body in: table</pre>
  384. *
  385. * pseudo-implementation:
  386. * <pre>table.each: body</pre>
  387. *
  388. * Example: <code>[1,2,3].each: { |i| system.println(i) }</code>
  389. *
  390. * @param body a one-arity closure that is to be applied to each element of the table
  391. * @param tab a table to apply the body closure to
  392. * @return <tt>nil</tt>, by default
  393. */
  394. public ATObject base_foreach_in_(ATClosure body, ATTable tab) throws InterpreterException {
  395. return tab.base_each_(body);
  396. }
  397. /**
  398. * The <tt>do:if:</tt> control structure. Usage:
  399. * <pre>do: body if: condition</pre>
  400. *
  401. * pseudo-implementation:
  402. * <pre>condition.ifTrue: body</pre>
  403. *
  404. * In Ruby, this kind of control structure is called a <i>statement modifier</i>.
  405. *
  406. * @param body a zero-argument closure to execute if the condition is true
  407. * @param condition a boolean value
  408. * @return the result of invoking body if the condition is true or nil if the
  409. * condition is false
  410. */
  411. public ATObject base_do_if_(ATClosure body, ATBoolean condition) throws InterpreterException {
  412. return condition.base_ifTrue_(body);
  413. }
  414. /**
  415. * The <tt>do:unless:</tt> control structure. Usage:
  416. * <pre>do: body unless: condition</pre>
  417. *
  418. * pseudo-implementation:
  419. * <pre>condition.ifFalse: body</pre>
  420. *
  421. * In Ruby, this kind of control structure is called a <i>statement modifier</i>.
  422. * Example: <code>do: { file.close() } unless: (nil == file)</code>
  423. *
  424. * @param body a zero-argument closure to execute only if the condition is false
  425. * @param condition a boolean value
  426. * @return the result of invoking body if the condition is false, nil otherwise
  427. */
  428. public ATObject base_do_unless_(ATClosure body, ATBoolean condition) throws InterpreterException {
  429. return condition.base_ifFalse_(body);
  430. }
  431. /**
  432. * The <tt>let:</tt> construct. Usage:
  433. * <pre>let: { |var := value| body }</pre>
  434. *
  435. * pseudo-implementation:
  436. * <pre>closure()</pre>
  437. *
  438. * <tt>let:</tt> allows for the easy creation of temporary local variables.
  439. * This construct should be used in conjunction with a closure that declares optional
  440. * parameters. Because the closure will be invoked with zero arguments, all of the
  441. * parameters will be given their corresponding default initial value. The parameters
  442. * are defined local to the closure's body.
  443. *
  444. * AmbientTalk's <tt>let:</tt> behaves like Scheme's <tt>let*</tt> and <tt>letrec</tt>,
  445. * i.e. the following is legal:
  446. * <pre>let: {
  447. * |var1 := value1,
  448. * var2 := var1,
  449. * var3 := { ... var3() ... }|
  450. * ...
  451. *}</pre>
  452. *
  453. * @param body a closure which is supposed to declare some optional parameters
  454. * @return the result of invoking the body closure
  455. */
  456. public ATObject base_let_(ATClosure body) throws InterpreterException {
  457. return body.base_apply(NATTable.EMPTY);
  458. }
  459. /* ------------------------------------------
  460. * -- Actor Creation and accessing Methods --
  461. * ------------------------------------------ */
  462. /**
  463. * The <tt>actor: closure</tt> construct.
  464. *
  465. * The semantics of actor creation is as follows:
  466. * <ul>
  467. * <li> Mandatory parameters to the block of initialization code are treated as lexically visible
  468. * variables that have to remain available in the new actor behaviour. Hence, these variables
  469. * are evaluated to values immediately at creation-time and parameter-passed to the new actor.
  470. * <li> The closure containing the initialization code is unpacked, its lexical scope is disregarded
  471. * and the unwrapped method is serialized and sent to the new actor, which can use it to
  472. * initialize his behaviour object.
  473. * <li>The creating actor waits for the created actor to spawn a new behaviour and to return a far
  474. * reference to this behaviour. From that point on, the creating actor can run in parallel with
  475. * the created actor, which only then evaluates the initialization code to initialize its behaviour.
  476. * </ul>
  477. *
  478. * @param closure the closure whose parameters define lexical fields to be copied and whose
  479. * method specifies the code of the new actor's behaviour object
  480. * @return a far reference to the behaviour of the new actor
  481. */
  482. public ATObject base_actor_(ATClosure closure) throws InterpreterException {
  483. ATMethod method = closure.base_method();
  484. ATObject copiedBindings;
  485. // if no variables were specified to pass along to the new actor, calculate the
  486. // set of free variables for the actor
  487. if (method.base_parameters().base_isEmpty().asNativeBoolean().javaValue) {
  488. // introduce a private scope object that will hold copies
  489. // of the lexically free variables of the actor
  490. copiedBindings = new NATObject(OBJLexicalRoot._INSTANCE_, new ATTypeTag[] { NativeTypeTags._ISOLATE_ });
  491. // calculate the set of free variables of the initialization expression
  492. Set freeVars = method.base_bodyExpression().impl_freeVariables();
  493. // add all these free variables manually as fields to a custom
  494. Iterator it = freeVars.iterator();
  495. while (it.hasNext()) {
  496. ATSymbol freeVar = (ATSymbol) it.next();
  497. // extra check to weed out special variables like "super" and variables available in the lexical root
  498. if (! (Evaluator.getGlobalLexicalScope().meta_respondsTo(freeVar).asNativeBoolean().javaValue
  499. || OBJLexicalRoot._INSTANCE_.meta_respondsTo(freeVar).asNativeBoolean().javaValue)) {
  500. // lookup the variable in the lexical scope
  501. try {
  502. ATClosure accessor = closure.base_context().base_lexicalScope().impl_lookup(freeVar);
  503. // only add the variable if it refers to a field, rather than to a method
  504. if (accessor instanceof NativeClosure.Accessor) {
  505. copiedBindings.meta_defineField(freeVar, accessor.base_apply(NATTable.EMPTY));
  506. }
  507. } catch(XUndefinedSlot exc) {
  508. // silently ignore lexically free variables which cannot be found
  509. // the assumption is that these variables will be bound by means of
  510. // import statements
  511. Logging.Actor_LOG.warn("Undefined lexically free var while constructing actor: "+exc.getFieldName());
  512. }
  513. }
  514. }
  515. } else {
  516. copiedBindings = Evaluator.evalMandatoryPars(
  517. method.base_parameters(),
  518. closure.base_context());
  519. }
  520. Packet serializedBindings = new Packet("actor-bindings", copiedBindings);
  521. Packet serializedInitCode = new Packet("actor-initcode", method);
  522. return ELVirtualMachine.currentVM().createActor(serializedBindings, serializedInitCode);
  523. }
  524. /**
  525. * <tt>reflectOnActor</tt> evaluates to the mirror on the actor executing this code.
  526. * The actor mirror is an object whose behaviour is consulted for operations
  527. * such as creating and sending asynchronous messages or creating mirrors on
  528. * other objects. It can be replaced by a custom mirror by means of the actor
  529. * mirror's <tt>getExplicitActorMirror</tt> method.
  530. */
  531. public ATActorMirror base_reflectOnActor() throws InterpreterException {
  532. return ELActor.currentActor().getImplicitActorMirror().base_getExplicitActorMirror();
  533. }
  534. /**
  535. * The <tt>export: object as: topic</tt> construct. Pseudo-implementation:
  536. * <pre>actor.provide(topic, object)</pre>
  537. *
  538. * This construct enables the given object to become discoverable by objects
  539. * in other actors by means of the topic type.
  540. *
  541. * @param object the object to export to remote actors' objects
  542. * @param topic a type denoting the abstract 'publication topic' for this object's publication
  543. * @return a publication object whose <tt>cancel</tt> method can be used to cancel the publication.
  544. */
  545. public ATObject base_export_as_(ATObject object, ATTypeTag topic) throws InterpreterException {
  546. return ELActor.currentActor().getImplicitActorMirror().base_provide(topic, object);
  547. }
  548. /**
  549. * The <tt>when: topic discovered: handler</tt> construct. Pseudo-implementation:
  550. * <pre>actor.require(topic, handler, false)</pre>
  551. *
  552. * When an object is exported by <i>another</i> actor under topic, this construct triggers
  553. * the given code, passing a reference to the exported object as argument to the closure.
  554. *
  555. * Once the code block has run once, it will not be triggered again.
  556. *
  557. * @param topic the abstract 'subscription topic' used to find an exported object
  558. * @param handler a one-argument closure to apply to a discovered exported object
  559. * @return a subscription object whose <tt>cancel</tt> method can be used to cancel the subscription,
  560. * such that the handler will no longer be invoked. Beware, however, that at the time the
  561. * subscription is cancelled, a request to apply the closure may already have been scheduled
  562. * for execution by the current actor. This request is not cancelled by invoking the <tt>cancel</tt> method.
  563. */
  564. public ATObject base_when_discovered_(ATTypeTag topic, ATClosure handler) throws InterpreterException {
  565. return ELActor.currentActor().getImplicitActorMirror().base_require(topic, handler, NATBoolean._FALSE_);
  566. }
  567. /**
  568. * The <tt>whenever: topic discovered: handler</tt> construct. Pseudo-implementation:
  569. * <pre>actor.require(topic, handler, true)</pre>
  570. *
  571. * When an object is exported by <i>another</i> actor under topic, this construct triggers
  572. * the given code, passing a reference to the exported object as argument to the closure.
  573. *
  574. * The code block can be fired multiple times upon discovering multiple exported objects.
  575. * To stop the block from triggering upon new publications, it must be explicitly cancelled
  576. *
  577. * @param topic the abstract 'subscription topic' used to find an exported object
  578. * @param handler a one-argument closure to apply to any discovered exported object
  579. * @return a subscription object whose <tt>cancel</tt> method can be used to cancel the subscription,
  580. * such that the handler will no longer be invoked. Beware, however, that at the time the
  581. * subscription is cancelled, a request to apply the closure may already have been scheduled
  582. * for execution by the current actor. This request is not cancelled by invoking the <tt>cancel</tt> method.
  583. */
  584. public ATObject base_whenever_discovered_(ATTypeTag topic, ATClosure handler) throws InterpreterException {
  585. return ELActor.currentActor().getImplicitActorMirror().base_require(topic, handler, NATBoolean._TRUE_);
  586. }
  587. /**
  588. * The <tt>whenever: farReference disconnected: listener</tt> construct.
  589. * When the far reference is broken due to network disconnections, triggers the zero-arity listener
  590. * closure. It is possible to register listeners on local far references. These may trigger if the
  591. * local actor takes its object offline. In this case, these listeners will trigger as well.
  592. *
  593. * @param farReference a native far reference
  594. * @param listener a zero-arity closure to invoke if the far reference becomes disconnected
  595. * @return a subscription object whose <tt>cancel</tt> method can be used to cancel future
  596. * notifications of the listener.
  597. */
  598. public ATObject base_whenever_disconnected_(ATFarReference farReference, ATClosure listener) throws InterpreterException {
  599. farReference.asNativeFarReference().addDisconnectionListener(listener);
  600. return new NATFarReference.NATDisconnectionSubscription(farReference.asNativeFarReference(), listener);
  601. }
  602. /**
  603. * The <tt>whenever: farReference reconnected: listener</tt> construct.
  604. * When the remote reference is reinstated after a network disconnection, trigger the zero-arity
  605. * listener. Although it is allowed to register these listeners on local far references,
  606. * these are normally not invoked because the only possibility for a local far ref to become
  607. * disconnected is because the object was taken offline, and this is a permanent disconnect.
  608. *
  609. * @param farReference a native far reference
  610. * @param listener a zero-arity closure to invoke if the far reference becomes reconnected
  611. * @return a subscription object whose <tt>cancel</tt> method can be used to cancel future
  612. * notifications of the listener.
  613. */
  614. public ATObject base_whenever_reconnected_(ATFarReference farReference, ATClosure listener) throws InterpreterException {
  615. farReference.asNativeFarReference().addReconnectionListener(listener);
  616. return new NATFarReference.NATReconnectionSubscription(farReference.asNativeFarReference(), listener);
  617. }
  618. /**
  619. * The <tt>when: farReference takenOffline:</tt> construct.
  620. * When the (remote/local) far reference is broken because the object referenced was
  621. * taken offline, trigger the code.
  622. *
  623. * @param farReference a native far reference
  624. * @param listener a zero-arity closure to invoke if the referenced object has been taken offline.
  625. * @return a subscription object whose <tt>cancel</tt> method can be used to cancel future
  626. * notifications of the listener.
  627. */
  628. public ATObject base_when_takenOffline_(ATFarReference farReference, ATClosure listener) throws InterpreterException {
  629. farReference.asNativeFarReference().addTakenOfflineListener(listener);
  630. return new NATFarReference.NATExpiredSubscription(farReference.asNativeFarReference(), listener);
  631. }
  632. /**
  633. * The <tt>retract: farReference</tt> construct.
  634. * Retracts all currently unsent messages from the far reference's outbox.
  635. * This has the side effect that the returned messages will <b>not</b> be sent
  636. * automatically anymore, the programmer is responsible to explicitly resend
  637. * all messages that were retracted but still need to be sent.
  638. *
  639. * Note that the returned messages are copies of the original.
  640. * @param farReference the far reference of which to retract outgoing message sends
  641. * @return a table containing copies of all messages that were sent to this far reference, but
  642. * not yet transmitted by the far reference to its referent.
  643. */
  644. public ATTable base_retract_(ATFarReference farReference) throws InterpreterException {
  645. return farReference.meta_retractUnsentMessages();
  646. }
  647. /* -----------------------------
  648. * -- Object Creation Methods --
  649. * ----------------------------- */
  650. /**
  651. * The <tt>object:</tt> object creation primitive.
  652. * This construct creates a new AmbientTalk object where:
  653. * <ul>
  654. * <li>The object is initialized with the <i>code</i> of the argument closure.
  655. * <li>The object's <b>lexical parent</b> is the lexical scope of the argument closure.
  656. * <li>The object's <b>dynamic parent</b> is <tt>nil</tt>.
  657. * <li>The object's <b>parent type</b> is <b>SHARES-A</b> (i.e. it is not an extension of its parent).
  658. * <li>The object's <b>types</b> is <tt>[]</tt> (i.e. it has no types).
  659. * <li>The object's <b>mirror</b> is the <tt>defaultMirror</tt> on objects (i.e. it is an object
  660. * with a 'native' metaobject protocol).
  661. * </ul>
  662. *
  663. * Example: <code>object: { def x := 1; }</code>
  664. * <p>
  665. * Pseudo-implementation:
  666. * <pre>object: code childOf: nil extends: false taggedAs: [] mirroredBy: defaultMirror</pre>
  667. *
  668. * The closure used to initialize the object may contain formal parameters. The closure
  669. * will always be invoked with <i>its own mandatory formal parameters</i>. E.g., a closure
  670. * <code>{ |x| nil }</code> is invoked as <code>{ |x| nil }(x)</code>. The net effect of this
  671. * mechanic is that if <tt>x</tt> is a lexically visible variable at the object-creation
  672. * site, the value of the variable will be copied into a copy with the same name which
  673. * resides in the newly created object. This mechanic is primarily useful for copying surrounding
  674. * variables within the object, e.g. for isolates which lose access to their surrounding scope.
  675. * <p>
  676. * Also, if the closure has optional parameters, they will always be triggered.
  677. * The expressions to initialize the formal parameters are <i>evaluated</i>
  678. * in the context of the closure's lexical scope but are <i>added</i> to the newly created object.
  679. *
  680. * @param code a closure containing both the code with which to initialize the object and the new object's lexical parent
  681. * @return a new AmbientTalk object with the properties defined above.
  682. * @see #base_object_childOf_extends_taggedAs_mirroredBy_(ATClosure, ATObject, ATBoolean, ATTable, ATObject)
  683. */
  684. public ATObject base_object_(ATClosure code) throws InterpreterException {
  685. return base_object_childOf_extends_taggedAs_mirroredBy_(
  686. code,
  687. Evaluator.getNil(),
  688. NATBoolean._FALSE_ /* SHARES-A link */,
  689. NATTable.EMPTY,
  690. base_defaultMirror());
  691. }
  692. /**
  693. * The <tt>extend:with:</tt> object creation primitive.
  694. * This construct creates a new AmbientTalk object where:
  695. * <ul>
  696. * <li>The object is initialized with the <i>code</i> of the argument closure.
  697. * <li>The object's <b>lexical parent</b> is the lexical scope of the argument closure.
  698. * <li>The object's <b>dynamic parent</b> is the argument object.
  699. * <li>The object's <b>parent type</b> is <b>IS-A</b> (i.e. it is an extension of its parent).
  700. * <li>The object's <b>types</b> is <tt>[]</tt> (i.e. it has no types).
  701. * <li>The object's <b>mirror</b> is the <tt>defaultMirror</tt> on objects (i.e. it is an object
  702. * with a 'native' metaobject protocol).
  703. * </ul>
  704. *
  705. * Example: <code>extend: parent with: { def x := 1; }</code>
  706. * <p>
  707. * Pseudo-implementation:
  708. * <pre>object: code childOf: parent extends: true taggedAs: [] mirroredBy: defaultMirror</pre>
  709. *
  710. * @param parent the dynamic parent object of the newly created object.
  711. * @param code a closure containing both the code with which to initialize the object and the new object's lexical parent
  712. * @return a new AmbientTalk object with the properties defined above.
  713. * @see #base_object_(ATClosure)
  714. * @see #base_object_childOf_extends_taggedAs_mirroredBy_(ATClosure, ATObject, ATBoolean, ATTable, ATObject)
  715. */
  716. public ATObject base_extend_with_(ATObject parent, ATClosure code) throws InterpreterException {
  717. return base_object_childOf_extends_taggedAs_mirroredBy_(
  718. code,
  719. parent,
  720. NATBoolean._TRUE_ /* IS-A link */,
  721. NATTable.EMPTY,
  722. base_defaultMirror());
  723. }
  724. /**
  725. * The <tt>extend:with:taggedAs:</tt> object creation primitive.
  726. * This construct creates a new AmbientTalk object where:
  727. * <ul>
  728. * <li>The object is initialized with the <i>code</i> of the argument closure.
  729. * <li>The object's <b>lexical parent</b> is the lexical scope of the argument closure.
  730. * <li>The object's <b>dynamic parent</b> is the argument object.
  731. * <li>The object's <b>parent type</b> is <b>IS-A</b> (i.e. it is an extension of its parent).
  732. * <li>The object's <b>types</b> are initialized to the argument types table.
  733. * <li>The object's <b>mirror</b> is the <tt>defaultMirror</tt> on objects (i.e. it is an object
  734. * with a 'native' metaobject protocol).
  735. * </ul>
  736. *
  737. * Example: <code>extend: parent with: { def x := 1; } taggedAs: [foo,bar]</code>
  738. * <p>
  739. * Pseudo-implementation:
  740. * <pre>object: code childOf: parent extends: true taggedAs: types mirroredBy: defaultMirror</pre>
  741. *
  742. * @param parent the dynamic parent object of the newly created object.
  743. * @param code a closure containing both the code with which to initialize the object and the new object's lexical parent.
  744. * @param types a table of types with which to type the newly created object.
  745. * @return a new AmbientTalk object with the properties defined above.
  746. * @see #base_object_(ATClosure)
  747. * @see #base_object_childOf_extends_taggedAs_mirroredBy_(ATClosure, ATObject, ATBoolean, ATTable, ATObject)
  748. */
  749. public ATObject base_extend_with_taggedAs_(ATObject parent, ATClosure code, ATTable types) throws InterpreterException {
  750. return base_object_childOf_extends_taggedAs_mirroredBy_(
  751. code,
  752. parent,
  753. NATBoolean._TRUE_ /* IS-A link */,
  754. types,
  755. base_defaultMirror());
  756. }
  757. /**
  758. * The <tt>extend:with:mirroredBy:</tt> object creation primitive.
  759. * This construct creates a new AmbientTalk object where:
  760. * <ul>
  761. * <li>The object is initialized with the <i>code</i> of the argument closure.
  762. * <li>The object's <b>lexical parent</b> is the lexical scope of the argument closure.
  763. * <li>The object's <b>dynamic parent</b> is the argument object.
  764. * <li>The object's <b>parent type</b> is <b>IS-A</b> (i.e. it is an extension of its parent).
  765. * <li>The object's <b>types</b> are set to <tt>[]</tt> (i.e. the object has no types).
  766. * <li>The object's <b>mirror</b> is the given mirror. This means that this object is a <i>mirage</i>
  767. * whose metaobject protocol is entirely dictated by the given mirror.
  768. * </ul>
  769. *
  770. * Example: <code>extend: parent with: { def x := 1; } mirroredBy: (mirror: {...})</code>
  771. * <p>
  772. * Pseudo-implementation:
  773. * <pre>object: code childOf: parent extends: true taggedAs: [] mirroredBy: mirror</pre>
  774. *
  775. * @param parent the dynamic parent object of the newly created object.
  776. * @param code a closure containing both the code with which to initialize the object and the new object's lexical parent.
  777. * @param mirror the mirror of the newly created mirage object.
  778. * @return a new AmbientTalk object with the properties defined above.
  779. * @see #base_object_(ATClosure)
  780. * @see #base_object_childOf_extends_taggedAs_mirroredBy_(ATClosure, ATObject, ATBoolean, ATTable, ATObject)
  781. */
  782. public ATObject base_extend_with_mirroredBy_(ATObject parent, ATClosure code, ATObject mirror) throws InterpreterException {
  783. return base_object_childOf_extends_taggedAs_mirroredBy_(
  784. code,
  785. parent,
  786. NATBoolean._TRUE_ /* IS-A link */,
  787. NATTable.EMPTY,
  788. mirror);
  789. }
  790. /**
  791. * The <tt>extend:with:taggedAs:mirroredBy:</tt> object creation primitive.
  792. * This construct creates a new AmbientTalk object where:
  793. * <ul>
  794. * <li>The object is initialized with the <i>code</i> of the argument closure.
  795. * <li>The object's <b>lexical parent</b> is the lexical scope of the argument closure.
  796. * <li>The object's <b>dynamic parent</b> is the argument object.
  797. * <li>The object's <b>parent type</b> is <b>IS-A</b> (i.e. it is an extension of its parent).
  798. * <li>The object's <b>types</b> are initialized to the argument types table.
  799. * <li>The object's <b>mirror</b> is the given argument mirror. This means that the newly
  800. * created object is a <i>mirage</i> whose metaobject protocol is dictated by the given mirror.
  801. * </ul>
  802. *
  803. * Example: <code>extend: parent with: { def x := 1; } taggedAs: [foo,bar] mirroredBy: mirror</code>
  804. * <p>
  805. * Pseudo-implementation:
  806. * <pre>object: code childOf: parent extends: true taggedAs: types mirroredBy: mirror</pre>
  807. *
  808. * @param parent the dynamic parent object of the newly created object.
  809. * @param code a closure containing both the code with which to initialize the object and the new object's lexical parent.
  810. * @param types a table of types with which to type the newly created object.
  811. * @param the mirror object of the newly created mirage object.
  812. * @return a new AmbientTalk object with the properties defined above.
  813. * @see #base_object_(ATClosure)
  814. * @see #base_object_childOf_extends_taggedAs_mirroredBy_(ATClosure, ATObject, ATBoolean, ATTable, ATObject)
  815. */
  816. public ATObject base_extend_with_taggedAs_mirroredBy_(ATObject parent, ATClosure code, ATTable types, ATObject mirror) throws InterpreterException {
  817. return base_object_childOf_extends_taggedAs_mirroredBy_(
  818. code,
  819. parent,
  820. NATBoolean._TRUE_ /* IS-A link */,
  821. types,
  822. mirror);
  823. }
  824. /**
  825. * The <tt>share:with:</tt> object creation primitive.
  826. * This construct creates a new AmbientTalk object where:
  827. * <ul>
  828. * <li>The object is initialized with the <i>code</i> of the argument closure.
  829. * <li>The object's <b>lexical parent</b> is the lexical scope of the argument closure.
  830. * <li>The object's <b>dynamic parent</b> is the argument object.
  831. * <li>The object's <b>parent type</b> is <b>SHARES-A</b> (i.e. it is not an extension of its parent).
  832. * <li>The object's <b>types</b> is <tt>[]</tt> (i.e. it has no types).
  833. * <li>The object's <b>mirror</b> is the <tt>defaultMirror</tt> on objects (i.e. it is an object
  834. * with a 'native' metaobject protocol).
  835. * </ul>
  836. *
  837. * Example: <code>share: parent with: { def x := 1; }</code>
  838. * <p>
  839. * Pseudo-implementation:
  840. * <pre>object: code childOf: parent extends: false taggedAs: [] mirroredBy: defaultMirror</pre>
  841. *
  842. * @param parent the dynamic parent object of the newly created object.
  843. * @param code a closure containing both the code with which to initialize the object and the new object's lexical parent
  844. * @return a new AmbientTalk object with the properties defined above.
  845. * @see #base_object_(ATClosure)
  846. * @see #base_object_childOf_extends_taggedAs_mirroredBy_(ATClosure, ATObject, ATBoolean, ATTable, ATObject)
  847. */
  848. public ATObject base_share_with_(ATObject parent, ATClosure code) throws InterpreterException {
  849. return base_object_childOf_extends_taggedAs_mirroredBy_(
  850. code,
  851. parent,
  852. NATBoolean._FALSE_ /* SHARES-A link */,
  853. NATTable.EMPTY,
  854. base_defaultMirror());
  855. }
  856. /**
  857. * The <tt>share:with:taggedAs:</tt> object creation primitive.
  858. * This construct creates a new AmbientTalk object where:
  859. * <ul>
  860. * <li>The object is initialized with the <i>code</i> of the argument closure.
  861. * <li>The object's <b>lexical parent</b> is the lexical scope of the argument closure.
  862. * <li>The object's <b>dynamic parent</b> is the argument object.
  863. * <li>The object's <b>parent type</b> is <b>SHARES-A</b> (i.e. it is not an extension of its parent).
  864. * <li>The object's <b>types</b> are initialized to the argument types table.
  865. * <li>The object's <b>mirror</b> is the <tt>defaultMirror</tt> on objects (i.e. it is an object
  866. * with a 'native' metaobject protocol).
  867. * </ul>
  868. *
  869. * Example: <code>share: parent with: { def x := 1; } taggedAs: [foo,bar]</code>
  870. * <p>
  871. * Pseudo-implementation:
  872. * <pre>object: code childOf: parent extends: false taggedAs: types mirroredBy: defaultMirror</pre>
  873. *
  874. * @param parent the dynamic parent object of the newly created object.
  875. * @param code a closure containing both the code with which to initialize the object and the new object's lexical parent.
  876. * @param types a table of types with which to type the newly created object.
  877. * @return a new AmbientTalk object with the properties defined above.
  878. * @see #base_object_(ATClosure)
  879. * @see #base_object_childOf_extends_taggedAs_mirroredBy_(ATClosure, ATObject, ATBoolean, ATTable, ATObject)
  880. */
  881. public ATObject base_share_with_taggedAs_(ATObject parent, ATClosure code, ATTable types) throws InterpreterException {
  882. return base_object_childOf_extends_taggedAs_mirroredBy_(
  883. code,
  884. parent,
  885. NATBoolean._FALSE_ /* SHARES-A link */,
  886. types,
  887. base_defaultMirror());
  888. }
  889. /**
  890. * The <tt>share:with:mirroredBy:</tt> object creation primitive.
  891. * This construct creates a new AmbientTalk object where:
  892. * <ul>
  893. * <li>The object is initialized with the <i>code</i> of the argument closure.
  894. * <li>The object's <b>lexical parent</b> is the lexical scope of the argument closure.
  895. * <li>The object's <b>dynamic parent</b> is the argument object.
  896. * <li>The object's <b>parent type</b> is <b>SHARES-A</b> (i.e. it is not an extension of its parent).
  897. * <li>The object's <b>types</b> are set to <tt>[]</tt> (i.e. the object has no types).
  898. * <li>The object's <b>mirror</b> is the given mirror. This means that this object is a <i>mirage</i>
  899. * whose metaobject protocol is entirely dictated by the given mirror.
  900. * </ul>
  901. *
  902. * Example: <code>share: parent with: { def x := 1; } mirroredBy: (mirror: {...})</code>
  903. * <p>
  904. * Pseudo-implementation:
  905. * <pre>object: code childOf: parent extends: false taggedAs: [] mirroredBy: mirror</pre>
  906. *
  907. * @param parent the dynamic parent object of the newly created object.
  908. * @param code a closure containing both the code with which to initialize the object and the new object's lexical parent.
  909. * @param mirror the mirror of the newly created mirage object.
  910. * @return a new AmbientTalk object with the properties defined above.
  911. * @see #base_object_(ATClosure)
  912. * @see #base_object_childOf_extends_taggedAs_mirroredBy_(ATClosure, ATObject, ATBoolean, ATTable, ATObject)
  913. */
  914. public ATObject base_share_with_mirroredBy_(ATObject parent, ATClosure code, ATObject mirror) throws InterpreterException {
  915. return base_object_childOf_extends_taggedAs_mirroredBy_(
  916. code,
  917. parent,
  918. NATBoolean._FALSE_ /* SHARES-A link */,
  919. NATTable.EMPTY,
  920. mirror);
  921. }
  922. /**
  923. * The <tt>share:with:taggedAs:mirroredBy:</tt> object creation primitive.
  924. * This construct creates a new AmbientTalk object where:
  925. * <ul>
  926. * <li>The object is initialized with the <i>code</i> of the argument closure.
  927. * <li>The object's <b>lexical parent</b> is the lexical scope of the argument closure.
  928. * <li>The object's <b>dynamic parent</b> is the argument object.
  929. * <li>The object's <b>parent type</b> is <b>SHARES-A</b> (i.e. it is not an extension of its parent).
  930. * <li>The object's <b>types</b> are initialized to the argument types table.
  931. * <li>The object's <b>mirror</b> is the given argument mirror. This means that the newly
  932. * created object is a <i>mirage</i> whose metaobject protocol is dictated by the given mirror.
  933. * </ul>
  934. *
  935. * Example: <code>share: parent with: { def x := 1; } taggedAs: [foo,bar] mirroredBy: mirror</code>
  936. * <p>
  937. * Pseudo-implementation:
  938. * <pre>object: code childOf: parent extends: false taggedAs: types mirroredBy: mirror</pre>
  939. *
  940. * @param parent the dynamic parent object of the newly created object.
  941. * @param code a closure containing both the code with which to initialize the object and the new object's lexical parent.
  942. * @param types a table of types with which to type the newly created object.
  943. * @param mirror the mirror object of the newly created mirage object.
  944. * @return a new AmbientTalk object with the properties defined above.
  945. * @see #base_object_(ATClosure)
  946. * @see #base_object_childOf_extends_taggedAs_mirroredBy_(ATClosure, ATObject, ATBoolean, ATTable, ATObject)
  947. */
  948. public ATObject base_share_with_taggedAs_mirroredBy_(ATObject parent, ATClosure code, ATTable types, ATObject mirror) throws InterpreterException {
  949. return base_object_childOf_extends_taggedAs_mirroredBy_(
  950. code,
  951. parent,
  952. NATBoolean._FALSE_ /* SHARES-A link */,
  953. types,
  954. mirror);
  955. }
  956. /**
  957. * The <tt>object:taggedAs:</tt> object creation primitive.
  958. * This construct creates a new AmbientTalk object where:
  959. * <ul>
  960. * <li>The object is initialized with the <i>code</i> of the argument closure.
  961. * <li>The object's <b>lexical parent</b> is the lexical scope of the argument closure.
  962. * <li>The object's <b>dynamic parent</b> is <tt>nil</tt>.
  963. * <li>The object's <b>parent type</b> is <b>SHARES-A</b> (i.e. it is not an extension of its parent).
  964. * <li>The object's <b>types</b> are initialized to the argument types table.
  965. * <li>The object's <b>mirror</b> is <tt>defaultMirror</tt> (i.e. the object has the
  966. * default metaobject protocol).
  967. * </ul>
  968. *
  969. * Example: <code>object: { def x := 1; } taggedAs: [foo,bar]</code>
  970. * <p>
  971. * Pseudo-implementation:
  972. * <pre>object: code childOf: nil extends: false taggedAs: types mirroredBy: defaultMirror</pre>
  973. *
  974. * @param code a closure containing both the code with which to initialize the object and the new object's lexical parent.
  975. * @param types a table of type tags with which to type the newly created object.
  976. * @return a new AmbientTalk object with the properties defined above.
  977. * @see #base_object_(ATClosure)
  978. * @see #base_object_childOf_extends_taggedAs_mirroredBy_(ATClosure, ATObject, ATBoolean, ATTable, ATObject)
  979. */
  980. public ATObject base_object_taggedAs_(ATClosure code, ATTable types) throws InterpreterException {
  981. return base_object_childOf_extends_taggedAs_mirroredBy_(
  982. code,
  983. Evaluator.getNil(),
  984. NATBoolean._FALSE_ /* SHARES-A link */,
  985. types,
  986. base_defaultMirror());
  987. }
  988. /**
  989. * The <tt>isolate:</tt> object creation primitive.
  990. * This construct creates a new AmbientTalk object where:
  991. * <ul>
  992. * <li>The object is initialized with the <i>code</i> of the argument closure.
  993. * <li>The object's <b>lexical parent</b> is initialized to the lexical scope of the argument closure,
  994. * but because it is typed as an isolate, the parent link is replaced by a link to the lexical <tt>root</tt>.
  995. * <li>The object's <b>dynamic parent</b> is <tt>nil</tt>.
  996. * <li>The object's <b>parent type</b> is <b>SHARES-A</b> (i.e. it is not an extension of its parent).
  997. * <li>The object's <b>types</b> are initialized to <tt>[/.at.types.Isolate]</tt>, i.e.
  998. * the object is typed as an isolate.
  999. * <li>The object's <b>mirror</b> is <tt>defaultMirror</tt> (i.e. the object has the
  1000. * default metaobject protocol).
  1001. * </ul>
  1002. *
  1003. * Example: <code>isolate: { def x := 1; }</code>
  1004. * <p>
  1005. * Pseudo-implementation:
  1006. * <pre>object: code childOf: nil extends: false taggedAs: [/.at.types.Isolate] mirroredBy: defaultMirror</pre>
  1007. *
  1008. * An isolate is an object without a proper lexical parent. It is as if the isolate is always
  1009. * defined at top-level. However, lexically visible variables can be retained by copying them into the isolate
  1010. * by means of formal parameters to the argument closure. Isolate objects are passed by-copy during
  1011. * inter-actor parameter and result passing.
  1012. *
  1013. * @param code a closure containing both the code with which to initialize the object and the new object's lexical parent.
  1014. * @return a new AmbientTalk object with the properties defined above.
  1015. * @see #base_object_(ATClosure)
  1016. * @see #base_object_childOf_extends_taggedAs_mirroredBy_(ATClosure, ATObject, ATBoolean, ATTable, ATObject)
  1017. */
  1018. public ATObject base_isolate_(ATClosure code) throws InterpreterException {
  1019. return base_object_taggedAs_(code, NATTable.of(NativeTypeTags._ISOLATE_));
  1020. }
  1021. /**
  1022. * The <tt>mirror:</tt> object creation primitive.
  1023. * This construct creates a new AmbientTalk object where:
  1024. * <ul>
  1025. * <li>The object is initialized with the <i>code</i> of the argument closure.
  1026. * <li>The object's <b>lexical parent</b> is the lexical scope of the argument closure.
  1027. * <li>The object's <b>dynamic parent</b> is <tt>defaultMirror</tt>.
  1028. * <li>The object's <b>parent type</b> is <b>IS-A</b> (i.e. it is an extension of its parent).
  1029. * <li>The object's <b>types</b> are initialized to <tt>[]</tt>.
  1030. * <li>The object's <b>mirror</b> is <tt>defaultMirror</tt> (i.e. the object has the
  1031. * default metaobject protocol).
  1032. * </ul>
  1033. *
  1034. * Example: <code>mirror: { def x := 1; }</code>
  1035. * <p>
  1036. * Pseudo-implementation:
  1037. * <pre>object: code childOf: defaultMirror extends: true taggedAs: [] mirroredBy: defaultMirror</pre>
  1038. *
  1039. * This construct is mere syntactic sugar for creating an extension of the default mirror root.
  1040. * It follows that AmbientTalk mirrors are plain AmbientTalk objects. They simply need to implement
  1041. * the entire metaobject protocol, and the easiest means to achieve this is by extending the default mirror.
  1042. * Also keep in mind that the mirror is an extension object. This is important because the default
  1043. * mirror has <i>state</i>, being the <tt>base</tt> field that points to the base-level object
  1044. * being mirrorred. Hence, always make sure that, if overriding <tt>init</tt>, the parent's
  1045. * <tt>init</tt> method is invoked with the appropriate <tt>base</tt> value.
  1046. *
  1047. * @param code a closure containing both the code with which to initialize the object and the new object's lexical parent.
  1048. * @return a new AmbientTalk object with the properties defined above.
  1049. * @see #base_object_(ATClosure)
  1050. * @see #base_object_childOf_extends_taggedAs_mirroredBy_(ATClosure, ATObject, ATBoolean, ATTable, ATObject)
  1051. */
  1052. public ATObject base_mirror_(ATClosure code) throws InterpreterException {
  1053. return base_object_childOf_extends_taggedAs_mirroredBy_(
  1054. code,
  1055. base_defaultMirror(),
  1056. NATBoolean._TRUE_ /* IS-A link */,
  1057. NATTable.EMPTY,
  1058. base_defaultMirror());
  1059. }
  1060. /**
  1061. * The <tt>object:mirroredBy:</tt> object creation primitive.
  1062. * This construct creates a new AmbientTalk object where:
  1063. * <ul>
  1064. * <li>The object is initialized with the <i>code</i> of the argument closure.
  1065. * <li>The object's <b>lexical parent</b> is the lexical scope of the argument closure.
  1066. * <li>The object's <b>dynamic parent</b> is <tt>nil</tt>.
  1067. * <li>The object's <b>parent type</b> is <b>SHARES-A</b> (i.e. it is not an extension of its parent).
  1068. * <li>The object's <b>types</b> are set to <tt>[]</tt> (i.e. the object has no types).
  1069. * <li>The object's <b>mirror</b> is the given mirror. This means that this object is a <i>mirage</i>
  1070. * whose metaobject protocol is entirely dictated by the given mirror.
  1071. * </ul>
  1072. *
  1073. * Example: <code>object: { def x := 1; } mirroredBy: (mirror: {...})</code>
  1074. * <p>
  1075. * Pseudo-implementation:
  1076. * <pre>object: code childOf: nil extends: false taggedAs: [] mirroredBy: mirror</pre>
  1077. *
  1078. * This primitive allows the construction of so-called <i>mirage</i> objects which are
  1079. * AmbientTalk objects whose metaobject protocol behaviour is dictated by a custom mirror
  1080. * object.
  1081. *
  1082. * @param code a closure containing both the code with which to initialize the object and the new object's lexical parent.
  1083. * @param mirror the mirror prototype of the newly created mirage object, or a constructor closure.
  1084. * @return a new AmbientTalk object with the properties defined above.
  1085. * @see #base_object_(ATClosure)
  1086. * @see #base_object_childOf_extends_taggedAs_mirroredBy_(ATClosure, ATObject, ATBoolean, ATTable, ATObject)
  1087. */
  1088. public ATObject base_object_mirroredBy_(ATClosure code, ATObject mirror) throws InterpreterException {
  1089. return base_object_childOf_extends_taggedAs_mirroredBy_(
  1090. code,
  1091. Evaluator.getNil(),
  1092. NATBoolean._FALSE_ /* SHARES-A link */,
  1093. NATTable.EMPTY,
  1094. mirror);
  1095. }
  1096. /**
  1097. * The <tt>object:taggedAs:mirroredBy:</tt> object creation primitive.
  1098. * This construct creates a new AmbientTalk object where:
  1099. * <ul>
  1100. * <li>The object is initialized with the <i>code</i> of the argument closure.
  1101. * <li>The object's <b>lexical parent</b> is the lexical scope of the argument closure.
  1102. * <li>The object's <b>dynamic parent</b> is <tt>nil</tt>.
  1103. * <li>The object's <b>parent type</b> is <b>SHARES-A</b> (i.e. it is not an extension of its parent).
  1104. * <li>The object's <b>types</b> are set to the argument types.
  1105. * <li>The object's <b>mirror</b> is a clone of given mirror, or the return value of a constructor closure. This means that this object is a <i>mirage</i>
  1106. * whose metaobject protocol is entirely dictated by the given mirror.
  1107. * </ul>
  1108. *
  1109. * Example: <code>object: { def x := 1; } taggedAs: [foo,bar] mirroredBy: (mirror: {...})</code>
  1110. * <p>
  1111. * Pseudo-implementation:
  1112. * <pre>object: code childOf: nil extends: false taggedAs: types mirroredBy: mirror</pre>
  1113. *
  1114. * @param code a closure containing both the code with which to initialize the object and the new object's lexical parent.
  1115. * @param types a table of types with which to type the newly created object.
  1116. * @param mirror the mirror of the newly created mirage object.
  1117. * @return a new AmbientTalk object with the properties defined above.
  1118. * @see #base_object_(ATClosure)
  1119. * @see #base_object_childOf_extends_taggedAs_mirroredBy_(ATClosure, ATObject, ATBoolean, ATTable, ATObject)
  1120. */
  1121. public ATObject base_object_taggedAs_mirroredBy_(ATClosure code, ATTable types, ATObject mirror) throws InterpreterException {
  1122. return base_object_childOf_extends_taggedAs_mirroredBy_(
  1123. code,
  1124. Evaluator.getNil(),
  1125. NATBoolean._FALSE_ /* SHARES-A link */,
  1126. types,
  1127. mirror);
  1128. }
  1129. /**
  1130. * The <tt>object:childOf:extends:taggedAs:mirroredBy:</tt> object creation primitive.
  1131. * This construct creates a new AmbientTalk object where:
  1132. * <ul>
  1133. * <li>The object is initialized with the <i>code</i> of the argument closure.
  1134. * <li>The object's <b>lexical parent</b> is the lexical scope of the argument closure.
  1135. * <li>The object's <b>dynamic parent</b> is the argument parent object.
  1136. * <li>The object's <b>parent type</b> is the argument parent type, true being <tt>IS-A</tt>, false being <tt>SHARES-A</tt>.
  1137. * <li>The object's <b>types</b> are set to the argument types table.
  1138. * <li>The object's <b>mirror</b> is a clone of the given mirror prototype,
  1139. * or the return value of the given constructor closure. This means that this object is a <i>mirage</i>
  1140. * whose metaobject protocol is entirely dictated by the given mirror, if the mirror is not <tt>defaultMirror</tt>.
  1141. * </ul>
  1142. *
  1143. * Example: <code>object: { def x := 1; } childOf: parent extends: true taggedAs: [foo,bar] mirroredBy: mirror</code>
  1144. * <p>
  1145. * Pseudo-implementation:
  1146. * <pre>let o = OBJECT(parent,code.lexicalParent,parentType,types);
  1147. * code.applyInScope(o, code.mandatoryPars);
  1148. * o
  1149. * </pre>
  1150. *
  1151. * @param code a closure containing both the code with which to initialize the object and the new object's lexical parent.
  1152. * @param parent the dynamic parent object of the newly created object.
  1153. * @param parentType a boolean denoting whether or not the object is an extension of its dynamic parent.
  1154. * @param types a table of types with which the newly created object should be typed.
  1155. * @param mirror the mirror of the newly created object.
  1156. * @return a new AmbientTalk object with the properties defined above.
  1157. * @see #base_object_(ATClosure) for more information about the properties of the passed closure.
  1158. */
  1159. public ATObject base_object_childOf_extends_taggedAs_mirroredBy_(ATClosure code, ATObject parent, ATBoolean parentType, ATTable types, ATObject mirror) throws InterpreterException {
  1160. ATTypeTag[] typeArray = NATTypeTag.toTypeTagArray(types);
  1161. boolean parentRelation = parentType.asNativeBoolean().javaValue;
  1162. NATObject newObject;
  1163. // if the mirror is a 'default' mirror...
  1164. if (mirror instanceof NATMirrorRoot) {
  1165. // then create a native object
  1166. newObject = new NATObject(parent, // dynamic parent
  1167. code.base_context().base_lexicalScope(), // lexical parent
  1168. parentRelation, // IS-A or SHARES-A
  1169. typeArray); // initial types
  1170. } else {
  1171. // else create a mirage mirrored by the custom mirror
  1172. newObject = NATMirage.createMirage(code, parent, parentRelation, typeArray, mirror);
  1173. }
  1174. newObject.initializeWithCode(code);
  1175. return newObject;
  1176. }
  1177. /**
  1178. * The <tt>reflect:</tt> construct. This construct returns a mirror on an object.
  1179. *
  1180. * pseudo-implementation:
  1181. * <pre>actor.createMirror(reflectee)</pre>
  1182. *
  1183. * An actor can change its default mirror creation policy by installing a new
  1184. * actor protocol that overrides <tt>createMirror</tt>.
  1185. *
  1186. * @param reflectee the object to reflect upon
  1187. * @return a mirror reflecting on the given object
  1188. * @see ATActorMirror#base_createMirror(ATObject) for the details about mirror creation on objects.
  1189. */
  1190. public ATObject base_reflect_(ATObject reflectee) throws InterpreterException {
  1191. return base_reflectOnActor().base_createMirror(reflectee);
  1192. }
  1193. /**
  1194. * The <tt>clone:</tt> language construct. Returns a clone of an object.
  1195. *
  1196. * Care must be taken when cloning a mirror. If a mirror would simply be cloned
  1197. * using the regular cloning semantics, its base field would be <b>shared</b>
  1198. * between the clone and the original mirror (because of shallow copy semantics).
  1199. * However, the base object will still be tied to the original mirror, not the clone.
  1200. * Therefore, the clone: operator is implemented as follows:
  1201. *
  1202. * <pre>def clone: obj {
  1203. * if: (is: obj taggedAs: Mirror) then: {
  1204. * reflect: (clone: obj.base)
  1205. * } else: {
  1206. * (reflect: obj).clone()
  1207. * }
  1208. * }</pre>
  1209. *
  1210. * The default cloning semantics ensures that all fields of the object are shallow-copied.
  1211. * Because methods are immutable, a clone and its original object share their method dictionary,
  1212. * but whenever a change is made to the dictionary, the changer creates a local copy of the
  1213. * dictionary as to not modify any clones. Hence, each object is truly stand-alone and independent
  1214. * of its clone.
  1215. *
  1216. * @param original the object to copy
  1217. * @return a clone of the given object (default semantics results in a shallow copy)
  1218. */
  1219. public ATObject base_clone_(ATObject original) throws InterpreterException {
  1220. if (original.meta_isTaggedAs(NativeTypeTags._MIRROR_).asNativeBoolean().javaValue) {
  1221. return base_reflect_(base_clone_(original.impl_invokeAccessor(original, NATMirrorRoot._BASE_NAME_, NATTable.EMPTY)));
  1222. } else {
  1223. return original.meta_clone();
  1224. }
  1225. }
  1226. /**
  1227. * The <tt>takeOffline:</tt> construct.
  1228. * Removes an object from the export table of an actor. This ensures that the object
  1229. * is no longer remotely accessible. This method is the cornerstone of distributed
  1230. * garbage collection in AmbientTalk. When an object is taken offline, remote clients
  1231. * that would still access it perceive this as if the object had become permanently
  1232. * disconnected.
  1233. *
  1234. * @return <tt>nil</tt>.
  1235. */
  1236. public ATNil base_takeOffline_ (ATObject object) throws InterpreterException{
  1237. ELActor.currentActor().takeOffline(object);
  1238. return Evaluator.getNil();
  1239. }
  1240. /**
  1241. * The <tt>disconnect:</tt> construct.
  1242. * When an object is manually disconnected, remote clients
  1243. * will percieve this as if the object was physically disconnected.
  1244. * This allows per-object disconnects rather than per-actor disconnects.
  1245. *
  1246. * @return a disconnected object whose <tt>reconnect</tt> method can be used to reconnect (and re-publish) the disconnected object.
  1247. */
  1248. public ATObject base_disconnect_ (ATObject object) throws InterpreterException{
  1249. return ELActor.currentActor().disconnect(object);
  1250. }
  1251. /* -------------------
  1252. * -- Type Support -
  1253. * ------------------- */
  1254. /**
  1255. * The <tt>is: object taggedAs: type</tt> construct.
  1256. * @return true if the given object is typed with the given type, false otherwise
  1257. */
  1258. public ATBoolean base_is_taggedAs_(ATObject object, ATTypeTag type) throws InterpreterException {
  1259. return object.meta_isTaggedAs(type);
  1260. }
  1261. /**
  1262. * The <tt>tagsOf: object</tt> construct.
  1263. * @return a table of all of the <i>local</i> types of an object.
  1264. */
  1265. public ATTable base_tagsOf_(ATObject object) throws InterpreterException {
  1266. return object.meta_typeTags();
  1267. }
  1268. /* -------------------------------
  1269. * -- Exception Handling Support -
  1270. * ------------------------------- */
  1271. /**
  1272. * The <tt>try: { tryBlock } finally: { finallyBlock }</tt> construct.
  1273. *
  1274. * Applies the tryBlock closure (to <tt>[]</tt>).
  1275. * Whether the tryBlock raises an exception or not, the finallyBlock closure is guaranteed to be applied either
  1276. * after normal termination of the tryBlock or when an exception is propagated from the tryBlock.
  1277. */
  1278. public ATObject base_try_finally_(ATClosure tryBlock, ATClosure finallyBlock) throws InterpreterException {
  1279. try {
  1280. return tryBlock.base_apply(NATTable.EMPTY);
  1281. } finally {
  1282. finallyBlock.base_apply(NATTable.EMPTY);
  1283. }
  1284. }
  1285. /**
  1286. * The <tt>try: { tryBlock } usingHandlers: [ handler1, handler2, ... ] finally: { finallyBlock }</tt> construct.
  1287. *
  1288. * Applies the tryBlock closure (to <tt>[]</tt>) and handles exceptions using the given exception handlers.
  1289. * Whether the tryBlock raises an exception or not, the finallyBlock closure is guaranteed to be applied either
  1290. * after the termination of the tryBlock or the execution of a fitting handler either before the exception is
  1291. * propagated if no matching handler is provided. This construct is the most general means of doing exception
  1292. * handling in AmbientTalk.
  1293. *
  1294. * The handlers given in the handler table represent first-class handler objects,
  1295. * which should respond to the <tt>canHandle</tt> message.
  1296. * @see ATHandler for the interface to which a handler object has to adhere
  1297. */
  1298. public ATObject base_try_usingHandlers_finally_(ATClosure tryBlock, ATTable exceptionHandlers, ATClosure finallyBlock) throws InterpreterException {
  1299. try {
  1300. return tryBlock.base_apply(NATTable.EMPTY);
  1301. } catch(InterpreterException e) {
  1302. ATObject[] handlers = exceptionHandlers.asNativeTable().elements_;
  1303. // find the appropriate handler
  1304. for (int i = 0; i < handlers.length; i++) {
  1305. ATHandler handler = handlers[i].asHandler();
  1306. ATObject exc = e.getAmbientTalkRepresentation();
  1307. if (handler.base_canHandle(exc).asNativeBoolean().javaValue) {
  1308. return handler.base_handle(exc);
  1309. };
  1310. }
  1311. // no handler found, re-throw the exception
  1312. throw e;
  1313. } finally {
  1314. finallyBlock.base_apply(NATTable.EMPTY);
  1315. }
  1316. }
  1317. /**
  1318. * The <tt>try: { tryBlock } usingHandlers: [ handler1, handler2, ... ]</tt> construct.
  1319. *
  1320. * Ad hoc code for tryBlocks which have an empty finally block
  1321. * @see OBJLexicalRoot#base_try_usingHandlers_finally_(ATClosure, ATTable, ATClosure)
  1322. */
  1323. public ATObject base_try_usingHandlers_(ATClosure tryBlock, ATTable exceptionHandlers) throws InterpreterException {
  1324. // An ad hoc version is provided since not using a finally block is a lot cheaper
  1325. // when we know for sure we won't be needing one.
  1326. try {
  1327. return tryBlock.base_apply(NATTable.EMPTY);
  1328. } catch(InterpreterException e) {
  1329. ATObject[] handlers = exceptionHandlers.asNativeTable().elements_;
  1330. // find the appropriate handler
  1331. for (int i = 0; i < handlers.length; i++) {
  1332. ATHandler handler = handlers[i].asHandler();
  1333. ATObject exc = e.getAmbientTalkRepresentation();
  1334. if (handler.base_canHandle(exc).asNativeBoolean().javaValue) {
  1335. return handler.base_handle(exc);
  1336. };
  1337. }
  1338. // no handler found, re-throw the exception
  1339. throw e;
  1340. }
  1341. }
  1342. /**
  1343. * The <tt>try: { tryBlock} using: handler</tt> construct.
  1344. *
  1345. * Ad-hoc code for one exception handler.
  1346. *
  1347. * @see #base_try_usingHandlers_(ATClosure, ATTable)
  1348. */
  1349. public ATObject base_try_using_(ATClosure tryBlock, ATHandler handler) throws InterpreterException {
  1350. try {
  1351. return tryBlock.base_apply(NATTable.EMPTY);
  1352. } catch(InterpreterException e) {
  1353. ATObject exc = e.getAmbientTalkRepresentation();
  1354. if (handler.base_canHandle(exc).asNativeBoolean().javaValue) {
  1355. return handler.base_handle(exc);
  1356. } else {
  1357. throw e;
  1358. }
  1359. }
  1360. }
  1361. /**
  1362. * The <tt>try: { tryBlock} using: handler finally: { finallyBlock }</tt> construct.
  1363. *
  1364. * Ad-hoc code for one exception handler.
  1365. *
  1366. * @see #base_try_usingHandlers_finally_(ATClosure, ATTable, ATClosure)
  1367. */
  1368. public ATObject base_try_using_finally_(ATClosure tryBlock, ATHandler handler, ATClosure finallyBlock) throws InterpreterException {
  1369. try {
  1370. return tryBlock.base_apply(NATTable.EMPTY);
  1371. } catch(InterpreterException e) {
  1372. ATObject exc = e.getAmbientTalkRepresentation();
  1373. if (handler.base_canHandle(exc).asNativeBoolean().javaValue) {
  1374. return handler.base_handle(exc);
  1375. } else {
  1376. throw e;
  1377. }
  1378. } finally {
  1379. finallyBlock.base_apply(NATTable.EMPTY);
  1380. }
  1381. }
  1382. /**
  1383. * The <tt>try: { tryBlock} using: handler1 using: handler2</tt> construct.
  1384. *
  1385. * Ad-hoc code for two exception handlers.
  1386. * @see #base_try_usingHandlers_(ATClosure, ATTable)
  1387. */
  1388. public ATObject base_try_using_using_(ATClosure tryBlock, ATHandler hdl1, ATHandler hdl2) throws InterpreterException {
  1389. return base_try_usingHandlers_(tryBlock, NATTable.atValue(new ATObject[] { hdl1, hdl2 }));
  1390. }
  1391. /**
  1392. * The <tt>try: { tryBlock} using: handler1 using: handler2 finally: { finallyBlock }</tt> construct.
  1393. *
  1394. * Ad-hoc code for two exception handlers.
  1395. * @see #base_try_usingHandlers_(ATClosure, ATTable)
  1396. */
  1397. public ATObject base_try_using_using_finally_(ATClosure tryBlock, ATHandler hdl1, ATHandler hdl2, ATClosure finallyBlock) throws InterpreterException {
  1398. return base_try_usingHandlers_finally_(tryBlock, NATTable.atValue(new ATObject[] { hdl1, hdl2 }), finallyBlock);
  1399. }
  1400. /**
  1401. * The <tt>try: { tryBlock} using: hdl1 using: hdl2 using: hdl3</tt> construct.
  1402. *
  1403. * Ad-hoc code for three exception handlers
  1404. * @see #base_try_usingHandlers_(ATClosure, ATTable)
  1405. */
  1406. public ATObject base_try_using_using_using_(ATClosure tryBlock, ATHandler hdl1, ATHandler hdl2, ATHandler hdl3) throws InterpreterException {
  1407. return base_try_usingHandlers_(tryBlock, NATTable.atValue(new ATObject[] { hdl1, hdl2, hdl3 }));
  1408. }
  1409. /**
  1410. * The <tt>try: { tryBlock} using: hdl1 using: hdl2 using: hdl3 finally: { finallyBlock }</tt> construct.
  1411. *
  1412. * Ad-hoc code for three exception handlers.
  1413. * @see #base_try_usingHandlers_(ATClosure, ATTable)
  1414. */
  1415. public ATObject base_try_using_using_using_finally_(ATClosure tryBlock, ATHandler hdl1, ATHandler hdl2, ATHandler hdl3, ATClosure finallyBlock) throws InterpreterException {
  1416. return base_try_usingHandlers_finally_(tryBlock, NATTable.atValue(new ATObject[] { hdl1, hdl2, hdl3 }), finallyBlock);
  1417. }
  1418. /**
  1419. * The <tt>try: { tryBlock} catch: type using: { |e| replacementCode }</tt>
  1420. *
  1421. * 'Syntactic sugar' for one "in-line", native handler.
  1422. * @see #base_try_usingHandlers_(ATClosure, ATTable)
  1423. */
  1424. public ATObject base_try_catch_using_(ATClosure tryBlock, ATTypeTag filter, ATClosure replacementCode) throws InterpreterException {
  1425. return base_try_using_(tryBlock, new NATHandler(filter, replacementCode));
  1426. }
  1427. /**
  1428. * The <tt>try: { tryBlock} catch: type using: { |e| replacementCode } finally: { finallyBlock }</tt>
  1429. *
  1430. * 'Syntactic sugar' for one "in-line", native handler.
  1431. * @see #base_try_usingHandlers_(ATClosure, ATTable)
  1432. */
  1433. public ATObject base_try_catch_using_finally_(ATClosure tryBlock, ATTypeTag filter, ATClosure replacementCode, ATClosure finallyBlock) throws InterpreterException {
  1434. return base_try_using_finally_(tryBlock, new NATHandler(filter, replacementCode), finallyBlock);
  1435. }
  1436. /**
  1437. * The <tt>try:catch:using:catch:using:</tt> construct.
  1438. *
  1439. * <pre>try: {
  1440. * tryBlock
  1441. * } catch: type using: { |e|
  1442. * replacementCode
  1443. * } catch: type2 using: { |e|
  1444. * replacementCode2
  1445. * }</pre>
  1446. *
  1447. * 'Syntactic sugar' for two in-line handlers
  1448. * @see #base_try_usingHandlers_(ATClosure, ATTable)
  1449. */
  1450. public ATObject base_try_catch_using_catch_using_( ATClosure tryBlock,
  1451. ATTypeTag filter1, ATClosure hdl1,
  1452. ATTypeTag filter2, ATClosure hdl2) throws InterpreterException {
  1453. return base_try_using_using_(tryBlock, new NATHandler(filter1, hdl1), new NATHandler(filter2, hdl2));
  1454. }
  1455. /**
  1456. * The <tt>try:catch:using:catch:using:finally:</tt> construct.
  1457. *
  1458. * <pre>try: {
  1459. * tryBlock
  1460. * } catch: type using: { |e|
  1461. * replacementCode
  1462. * } catch: type2 using: { |e|
  1463. * replacementCode2
  1464. * } finally: {
  1465. * finalizationCode
  1466. * }</pre>
  1467. *
  1468. * 'Syntactic sugar' for two in-line handlers
  1469. * @see #base_try_usingHandlers_(ATClosure, ATTable)
  1470. */
  1471. public ATObject base_try_catch_using_catch_using_finally_( ATClosure tryBlock,
  1472. ATTypeTag filter1, ATClosure hdl1,
  1473. ATTypeTag filter2, ATClosure hdl2,
  1474. ATClosure finallyBlock) throws InterpreterException {
  1475. return base_try_using_using_finally_(tryBlock, new NATHandler(filter1, hdl1), new NATHandler(filter2, hdl2), finallyBlock);
  1476. }
  1477. /**
  1478. * The <tt>try:catch:using:catch:using:catch:using:</tt> construct.
  1479. *
  1480. * <pre>try: {
  1481. * tryBlock
  1482. * } catch: type using: { |e|
  1483. * replacementCode
  1484. * } catch: type2 using: { |e|
  1485. * replacementCode2
  1486. * } catch: type3 using: { |e|
  1487. * replacementCode3
  1488. * }</pre>
  1489. *
  1490. * 'Syntactic sugar' for three in-line handlers
  1491. * @see #base_try_usingHandlers_(ATClosure, ATTable)
  1492. */
  1493. public ATObject base_try_catch_using_catch_using_catch_using_(ATClosure tryBlock,
  1494. ATTypeTag filter1, ATClosure hdl1,
  1495. ATTypeTag filter2, ATClosure hdl2,
  1496. ATTypeTag filter3, ATClosure hdl3) throws InterpreterException {
  1497. return base_try_using_using_using_(tryBlock, new NATHandler(filter1, hdl1), new NATHandler(filter2, hdl2), new NATHandler(filter3, hdl3));
  1498. }
  1499. /**
  1500. * The <tt>try:catch:using:catch:using:catch:using:finally:</tt> construct.
  1501. *
  1502. * <pre>try: {
  1503. * tryBlock
  1504. * } catch: type using: { |e|
  1505. * replacementCode
  1506. * } catch: type2 using: { |e|
  1507. * replacementCode2
  1508. * } catch: type3 using: { |e|
  1509. * replacementCode3
  1510. * }</pre>
  1511. *
  1512. * 'Syntactic sugar' for three in-line handlers
  1513. * @see #base_try_usingHandlers_(ATClosure, ATTable)
  1514. */
  1515. public ATObject base_try_catch_using_catch_using_catch_using_finally_(ATClosure tryBlock,
  1516. ATTypeTag filter1, ATClosure hdl1,
  1517. ATTypeTag filter2, ATClosure hdl2,
  1518. ATTypeTag filter3, ATClosure hdl3,
  1519. ATClosure finallyBlock) throws InterpreterException {
  1520. return base_try_using_using_using_finally_(tryBlock, new NATHandler(filter1, hdl1), new NATHandler(filter2, hdl2), new NATHandler(filter3, hdl3), finallyBlock);
  1521. }
  1522. /**
  1523. * The <tt>handle: type with: { |e| replacementCode }</tt> construct.
  1524. *
  1525. * @return a first-class handler from a filter prototype and some handler code.
  1526. * @see ATHandler for the interface to which a handler object responds.
  1527. */
  1528. public ATObject base_handle_with_(ATTypeTag filter, ATClosure replacementCode) {
  1529. return new NATHandler(filter, replacementCode);
  1530. }
  1531. /**
  1532. * The <tt>raise: exception</tt> construct.
  1533. *
  1534. * Raises an exception which can be caught by dynamically installed try-catch-using blocks.
  1535. * @see #base_try_usingHandlers_(ATClosure, ATTable)
  1536. */
  1537. public ATNil base_raise_(ATObject anExceptionObject) throws InterpreterException {
  1538. throw Evaluator.asNativeException(anExceptionObject);
  1539. }
  1540. /* --------------------
  1541. * -- Unary Operators -
  1542. * -------------------- */
  1543. /**
  1544. * The unary <tt>!</tt> primitive.
  1545. * <pre>!b == b.not()</pre>
  1546. * @param b the boolean to negate.
  1547. * @return the negation of the boolean.
  1548. */
  1549. public ATBoolean base__opnot_(ATBoolean b) throws InterpreterException {
  1550. return b.base_not();
  1551. }
  1552. /**
  1553. * The unary <tt>-</tt> primitive.
  1554. * <pre>-NUM(n) == 0 - n</pre>
  1555. *
  1556. * @param n a number or a fraction to negate.
  1557. */
  1558. public ATNumeric base__opmns_(ATNumeric n) throws InterpreterException {
  1559. return NATNumber.ZERO.base__opmns_(n);
  1560. }
  1561. /**
  1562. * The unary <tt>+</tt> primitive.
  1563. * <pre>+NBR(n) == NBR(n)</pre>
  1564. */
  1565. public ATNumber base__oppls_(ATNumber n) throws InterpreterException {
  1566. return n;
  1567. }
  1568. /* -------------------
  1569. * -- Miscellaneous --
  1570. * ------------------- */
  1571. /**
  1572. * The <tt>read:</tt> metaprogramming construct. Parses the given text string into an
  1573. * abstract syntax tree.
  1574. *
  1575. * Example: <code>read: "x" => `x</code>
  1576. */
  1577. public ATAbstractGrammar base_read_(ATText source) throws InterpreterException {
  1578. return NATParser._INSTANCE_.base_parse(source);
  1579. }
  1580. /**
  1581. * The <tt>eval:in:</tt> metaprogramming construct.
  1582. * Evaluates the given AST in the context of the given object, returning its value.
  1583. *
  1584. * Example: <code>eval: `x in: object: { def x := 1 } => 1</code>
  1585. *
  1586. * This is a "dangerous" operation in the sense that lexical encapsulation of the given
  1587. * object can be violated.
  1588. */
  1589. public ATObject base_eval_in_(ATAbstractGrammar ast, ATObject obj) throws InterpreterException {
  1590. return ast.meta_eval(new NATContext(obj, obj));
  1591. }
  1592. /**
  1593. * The <tt>print:</tt> metaprogramming construct.
  1594. * This construct invokes the object mirror's <tt>print</tt> method.
  1595. *
  1596. * @return a text string being a human-readable representation of the given object.
  1597. */
  1598. public ATText base_print_(ATObject obj) throws InterpreterException {
  1599. return obj.meta_print();
  1600. }
  1601. /**
  1602. * The <tt>asCode:</tt> metaprogramming construct.
  1603. * This construct invokes the object mirror's <tt>asCode</tt> method.
  1604. *
  1605. * @return a text string being the source code representation of the given object.
  1606. */
  1607. public ATText base_asCode_(ATObject obj) throws InterpreterException {
  1608. return obj.meta_asCode();
  1609. }
  1610. /**
  1611. * Compare the receiver object to the <tt>root</tt> object.
  1612. * the reason for this custom implementation: during the execution
  1613. * of this method, 'this' should refer to the global lexical scope object (the root),
  1614. * not to the OBJLexicalRoot instance.
  1615. *
  1616. * When invoking one of these methods lexically, the receiver is always 'root'
  1617. * For example, <code>==(obj)</code> is equivalent to <code>root == obj</code> (or "root.==(obj)")
  1618. */
  1619. public ATBoolean base__opeql__opeql_(ATObject comparand) throws InterpreterException {
  1620. return Evaluator.getGlobalLexicalScope().base__opeql__opeql_(comparand);
  1621. }
  1622. /**
  1623. * Instantiate the <tt>root</tt> object. I.e. <code>new()</code> is equivalent
  1624. * to <tt>root.new()</tt>.
  1625. */
  1626. /*public ATObject base_new(ATObject[] initargs) throws InterpreterException {
  1627. // root.new(@initargs)
  1628. ATObject root = Evaluator.getGlobalLexicalScope();
  1629. return root.meta_invoke(root,NATNil._NEW_NAME_,NATTable.atValue(initargs));
  1630. }*/
  1631. /**
  1632. * After deserialization, ensure that the lexical root remains unique.
  1633. */
  1634. public ATObject meta_resolve() throws InterpreterException {
  1635. return OBJLexicalRoot._INSTANCE_;
  1636. }
  1637. public NATText meta_print() throws InterpreterException {
  1638. return NATText.atValue("lexroot");
  1639. }
  1640. /**
  1641. * This hashmap stores all native top-level lexical methods.
  1642. * It is populated when this class is loaded, and shared between all
  1643. * AmbientTalk actors on this VM. This is safe, since {@link DirectNativeMethod}
  1644. * instances are all immutable.
  1645. */
  1646. private static final HashMap<String, ATMethod> _meths = new HashMap<String, ATMethod>();
  1647. static {
  1648. _meths.put("nil", new DirectNativeMethod("nil") {
  1649. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1650. if (ctx.base_receiver() != _INSTANCE_) {
  1651. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1652. }
  1653. checkArity(args, 0);
  1654. return _INSTANCE_.base_nil();
  1655. }
  1656. });
  1657. _meths.put("true", new DirectNativeMethod("true") {
  1658. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1659. if (ctx.base_receiver() != _INSTANCE_) {
  1660. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1661. }
  1662. checkArity(args, 0);
  1663. return _INSTANCE_.base_true();
  1664. }
  1665. });
  1666. _meths.put("false", new DirectNativeMethod("false") {
  1667. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1668. if (ctx.base_receiver() != _INSTANCE_) {
  1669. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1670. }
  1671. checkArity(args, 0);
  1672. return _INSTANCE_.base_false();
  1673. }
  1674. });
  1675. _meths.put("lobby", new DirectNativeMethod("lobby") {
  1676. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1677. if (ctx.base_receiver() != _INSTANCE_) {
  1678. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1679. }
  1680. checkArity(args, 0);
  1681. return _INSTANCE_.base_lobby();
  1682. }
  1683. });
  1684. _meths.put("/", _meths.get("lobby"));
  1685. _meths.put("root", new DirectNativeMethod("root") {
  1686. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1687. if (ctx.base_receiver() != _INSTANCE_) {
  1688. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1689. }
  1690. checkArity(args, 0);
  1691. return _INSTANCE_.base_root();
  1692. }
  1693. });
  1694. _meths.put("jlobby", new DirectNativeMethod("jlobby") {
  1695. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1696. if (ctx.base_receiver() != _INSTANCE_) {
  1697. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1698. }
  1699. checkArity(args, 0);
  1700. return _INSTANCE_.base_jlobby();
  1701. }
  1702. });
  1703. _meths.put("network", new DirectNativeMethod("network") {
  1704. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1705. if (ctx.base_receiver() != _INSTANCE_) {
  1706. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1707. }
  1708. checkArity(args, 0);
  1709. return _INSTANCE_.base_network();
  1710. }
  1711. });
  1712. _meths.put("defaultMirror", new DirectNativeMethod("defaultMirror") {
  1713. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1714. if (ctx.base_receiver() != _INSTANCE_) {
  1715. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1716. }
  1717. checkArity(args, 0);
  1718. return _INSTANCE_.base_defaultMirror();
  1719. }
  1720. });
  1721. _meths.put("if:then:", new DirectNativeMethod("if:then:") {
  1722. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1723. if (ctx.base_receiver() != _INSTANCE_) {
  1724. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1725. }
  1726. checkArity(args, 2);
  1727. ATBoolean cond = get(args, 1).asBoolean();
  1728. ATClosure consequent = get(args, 2).asClosure();
  1729. return _INSTANCE_.base_if_then_(cond, consequent);
  1730. }
  1731. });
  1732. _meths.put("if:then:else:", new DirectNativeMethod("if:then:else:") {
  1733. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1734. if (ctx.base_receiver() != _INSTANCE_) {
  1735. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1736. }
  1737. checkArity(args, 3);
  1738. ATBoolean cond = get(args, 1).asBoolean();
  1739. ATClosure consequent = get(args, 2).asClosure();
  1740. ATClosure alternative = get(args, 3).asClosure();
  1741. return _INSTANCE_.base_if_then_else_(cond, consequent, alternative);
  1742. }
  1743. });
  1744. _meths.put("while:do:", new DirectNativeMethod("while:do:") {
  1745. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1746. if (ctx.base_receiver() != _INSTANCE_) {
  1747. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1748. }
  1749. checkArity(args, 2);
  1750. ATClosure condition = get(args, 1).asClosure();
  1751. ATClosure body = get(args, 2).asClosure();
  1752. return _INSTANCE_.base_while_do_(condition, body);
  1753. }
  1754. });
  1755. _meths.put("foreach:in:", new DirectNativeMethod("foreach:in:") {
  1756. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1757. if (ctx.base_receiver() != _INSTANCE_) {
  1758. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1759. }
  1760. checkArity(args, 2);
  1761. ATClosure body = get(args, 1).asClosure();
  1762. ATTable tab = get(args, 2).asTable();
  1763. return _INSTANCE_.base_foreach_in_(body, tab);
  1764. }
  1765. });
  1766. _meths.put("do:if:", new DirectNativeMethod("do:if:") {
  1767. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1768. if (ctx.base_receiver() != _INSTANCE_) {
  1769. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1770. }
  1771. checkArity(args, 2);
  1772. ATClosure body = get(args, 1).asClosure();
  1773. ATBoolean condition = get(args, 2).asBoolean();
  1774. return _INSTANCE_.base_do_if_(body, condition);
  1775. }
  1776. });
  1777. _meths.put("do:unless:", new DirectNativeMethod("do:unless:") {
  1778. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1779. if (ctx.base_receiver() != _INSTANCE_) {
  1780. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1781. }
  1782. checkArity(args, 2);
  1783. ATClosure body = get(args, 1).asClosure();
  1784. ATBoolean condition = get(args, 2).asBoolean();
  1785. return _INSTANCE_.base_do_unless_(body, condition);
  1786. }
  1787. });
  1788. _meths.put("let:", new DirectNativeMethod("let:") {
  1789. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1790. if (ctx.base_receiver() != _INSTANCE_) {
  1791. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1792. }
  1793. checkArity(args, 1);
  1794. ATClosure body = get(args, 1).asClosure();
  1795. return _INSTANCE_.base_let_(body);
  1796. }
  1797. });
  1798. _meths.put("actor:", new DirectNativeMethod("actor:") {
  1799. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1800. if (ctx.base_receiver() != _INSTANCE_) {
  1801. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1802. }
  1803. checkArity(args, 1);
  1804. ATClosure closure = get(args, 1).asClosure();
  1805. return _INSTANCE_.base_actor_(closure);
  1806. }
  1807. });
  1808. _meths.put("reflectOnActor", new DirectNativeMethod("reflectOnActor") {
  1809. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1810. if (ctx.base_receiver() != _INSTANCE_) {
  1811. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1812. }
  1813. checkArity(args, 0);
  1814. return _INSTANCE_.base_reflectOnActor();
  1815. }
  1816. });
  1817. _meths.put("export:as:", new DirectNativeMethod("export:as:") {
  1818. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1819. if (ctx.base_receiver() != _INSTANCE_) {
  1820. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1821. }
  1822. checkArity(args, 2);
  1823. ATObject object = get(args, 1);
  1824. ATTypeTag topic = get(args, 2).asTypeTag();
  1825. return _INSTANCE_.base_export_as_(object, topic);
  1826. }
  1827. });
  1828. _meths.put("when:discovered:", new DirectNativeMethod("when:discovered:") {
  1829. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1830. if (ctx.base_receiver() != _INSTANCE_) {
  1831. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1832. }
  1833. checkArity(args, 2);
  1834. ATTypeTag topic = get(args, 1).asTypeTag();
  1835. ATClosure handler = get(args, 2).asClosure();
  1836. return _INSTANCE_.base_when_discovered_(topic, handler);
  1837. }
  1838. });
  1839. _meths.put("whenever:discovered:", new DirectNativeMethod("whenever:discovered:") {
  1840. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1841. if (ctx.base_receiver() != _INSTANCE_) {
  1842. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1843. }
  1844. checkArity(args, 2);
  1845. ATTypeTag topic = get(args, 1).asTypeTag();
  1846. ATClosure handler = get(args, 2).asClosure();
  1847. return _INSTANCE_.base_whenever_discovered_(topic, handler);
  1848. }
  1849. });
  1850. _meths.put("whenever:disconnected:", new DirectNativeMethod("whenever:disconnected:") {
  1851. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1852. if (ctx.base_receiver() != _INSTANCE_) {
  1853. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1854. }
  1855. checkArity(args, 2);
  1856. ATFarReference farReference = get(args, 1).asFarReference();
  1857. ATClosure listener = get(args, 2).asClosure();
  1858. return _INSTANCE_.base_whenever_disconnected_(farReference, listener);
  1859. }
  1860. });
  1861. _meths.put("whenever:reconnected:", new DirectNativeMethod("whenever:reconnected:") {
  1862. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1863. if (ctx.base_receiver() != _INSTANCE_) {
  1864. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1865. }
  1866. checkArity(args, 2);
  1867. ATFarReference farReference = get(args, 1).asFarReference();
  1868. ATClosure listener = get(args, 2).asClosure();
  1869. return _INSTANCE_.base_whenever_reconnected_(farReference, listener);
  1870. }
  1871. });
  1872. _meths.put("when:takenOffline:", new DirectNativeMethod("when:takenOffline:") {
  1873. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1874. if (ctx.base_receiver() != _INSTANCE_) {
  1875. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1876. }
  1877. checkArity(args, 2);
  1878. ATFarReference farReference = get(args, 1).asFarReference();
  1879. ATClosure listener = get(args, 2).asClosure();
  1880. return _INSTANCE_.base_when_takenOffline_(farReference, listener);
  1881. }
  1882. });
  1883. _meths.put("retract:", new DirectNativeMethod("retract:") {
  1884. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1885. if (ctx.base_receiver() != _INSTANCE_) {
  1886. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1887. }
  1888. checkArity(args, 1);
  1889. ATFarReference farReference = get(args, 1).asFarReference();
  1890. return _INSTANCE_.base_retract_(farReference);
  1891. }
  1892. });
  1893. _meths.put("object:", new DirectNativeMethod("object:") {
  1894. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1895. if (ctx.base_receiver() != _INSTANCE_) {
  1896. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1897. }
  1898. checkArity(args, 1);
  1899. ATClosure code = get(args, 1).asClosure();
  1900. return _INSTANCE_.base_object_(code);
  1901. }
  1902. });
  1903. _meths.put("extend:with:", new DirectNativeMethod("extend:with:") {
  1904. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1905. if (ctx.base_receiver() != _INSTANCE_) {
  1906. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1907. }
  1908. checkArity(args, 2);
  1909. ATObject parent = get(args, 1);
  1910. ATClosure code = get(args, 2).asClosure();
  1911. return _INSTANCE_.base_extend_with_(parent, code);
  1912. }
  1913. });
  1914. _meths.put("extend:with:taggedAs:", new DirectNativeMethod("extend:with:taggedAs:") {
  1915. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1916. if (ctx.base_receiver() != _INSTANCE_) {
  1917. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1918. }
  1919. checkArity(args, 3);
  1920. ATObject parent = get(args, 1);
  1921. ATClosure code = get(args, 2).asClosure();
  1922. ATTable types = get(args, 3).asTable();
  1923. return _INSTANCE_.base_extend_with_taggedAs_(parent, code, types);
  1924. }
  1925. });
  1926. _meths.put("extend:with:mirroredBy:", new DirectNativeMethod("extend:with:mirroredBy:") {
  1927. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1928. if (ctx.base_receiver() != _INSTANCE_) {
  1929. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1930. }
  1931. checkArity(args, 3);
  1932. ATObject parent = get(args, 1);
  1933. ATClosure code = get(args, 2).asClosure();
  1934. ATObject mirror = get(args, 3);
  1935. return _INSTANCE_.base_extend_with_mirroredBy_(parent, code, mirror);
  1936. }
  1937. });
  1938. _meths.put("extend:with:taggedAs:mirroredBy:", new DirectNativeMethod("extend:with:taggedAs:mirroredBy:") {
  1939. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1940. if (ctx.base_receiver() != _INSTANCE_) {
  1941. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1942. }
  1943. checkArity(args, 4);
  1944. ATObject parent = get(args, 1);
  1945. ATClosure code = get(args, 2).asClosure();
  1946. ATTable types = get(args, 3).asTable();
  1947. ATObject mirror = get(args, 4);
  1948. return _INSTANCE_.base_extend_with_taggedAs_mirroredBy_(parent, code, types, mirror);
  1949. }
  1950. });
  1951. _meths.put("share:with:", new DirectNativeMethod("share:with:") {
  1952. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1953. if (ctx.base_receiver() != _INSTANCE_) {
  1954. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1955. }
  1956. checkArity(args, 2);
  1957. ATObject parent = get(args, 1);
  1958. ATClosure code = get(args, 2).asClosure();
  1959. return _INSTANCE_.base_share_with_(parent, code);
  1960. }
  1961. });
  1962. _meths.put("share:with:taggedAs:", new DirectNativeMethod("share:with:taggedAs:") {
  1963. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1964. if (ctx.base_receiver() != _INSTANCE_) {
  1965. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1966. }
  1967. checkArity(args, 3);
  1968. ATObject parent = get(args, 1);
  1969. ATClosure code = get(args, 2).asClosure();
  1970. ATTable types = get(args, 3).asTable();
  1971. return _INSTANCE_.base_share_with_taggedAs_(parent, code, types);
  1972. }
  1973. });
  1974. _meths.put("share:with:mirroredBy:", new DirectNativeMethod("share:with:mirroredBy:") {
  1975. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1976. if (ctx.base_receiver() != _INSTANCE_) {
  1977. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1978. }
  1979. checkArity(args, 3);
  1980. ATObject parent = get(args, 1);
  1981. ATClosure code = get(args, 2).asClosure();
  1982. ATObject mirror = get(args, 3);
  1983. return _INSTANCE_.base_share_with_mirroredBy_(parent, code, mirror);
  1984. }
  1985. });
  1986. _meths.put("share:with:taggedAs:mirroredBy:", new DirectNativeMethod("share:with:taggedAs:mirroredBy:") {
  1987. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  1988. if (ctx.base_receiver() != _INSTANCE_) {
  1989. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  1990. }
  1991. checkArity(args, 4);
  1992. ATObject parent = get(args, 1);
  1993. ATClosure code = get(args, 2).asClosure();
  1994. ATTable types = get(args, 3).asTable();
  1995. ATObject mirror = get(args, 4);
  1996. return _INSTANCE_.base_share_with_taggedAs_mirroredBy_(parent, code, types, mirror);
  1997. }
  1998. });
  1999. _meths.put("object:taggedAs:", new DirectNativeMethod("object:taggedAs:") {
  2000. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2001. if (ctx.base_receiver() != _INSTANCE_) {
  2002. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2003. }
  2004. checkArity(args, 2);
  2005. ATClosure code = get(args, 1).asClosure();
  2006. ATTable types = get(args, 2).asTable();
  2007. return _INSTANCE_.base_object_taggedAs_(code, types);
  2008. }
  2009. });
  2010. _meths.put("isolate:", new DirectNativeMethod("isolate:") {
  2011. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2012. if (ctx.base_receiver() != _INSTANCE_) {
  2013. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2014. }
  2015. checkArity(args, 1);
  2016. ATClosure code = get(args, 1).asClosure();
  2017. return _INSTANCE_.base_isolate_(code);
  2018. }
  2019. });
  2020. _meths.put("mirror:", new DirectNativeMethod("mirror:") {
  2021. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2022. if (ctx.base_receiver() != _INSTANCE_) {
  2023. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2024. }
  2025. checkArity(args, 1);
  2026. ATClosure code = get(args, 1).asClosure();
  2027. return _INSTANCE_.base_mirror_(code);
  2028. }
  2029. });
  2030. _meths.put("object:mirroredBy:", new DirectNativeMethod("object:mirroredBy:") {
  2031. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2032. if (ctx.base_receiver() != _INSTANCE_) {
  2033. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2034. }
  2035. checkArity(args, 2);
  2036. ATClosure code = get(args, 1).asClosure();
  2037. ATObject mirror = get(args, 2);
  2038. return _INSTANCE_.base_object_mirroredBy_(code, mirror);
  2039. }
  2040. });
  2041. _meths.put("object:taggedAs:mirroredBy:", new DirectNativeMethod("object:taggedAs:mirroredBy:") {
  2042. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2043. if (ctx.base_receiver() != _INSTANCE_) {
  2044. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2045. }
  2046. checkArity(args, 3);
  2047. ATClosure code = get(args, 1).asClosure();
  2048. ATTable types = get(args, 2).asTable();
  2049. ATObject mirror = get(args, 3);
  2050. return _INSTANCE_.base_object_taggedAs_mirroredBy_(code, types, mirror);
  2051. }
  2052. });
  2053. _meths.put("object:childOf:extends:taggedAs:mirroredBy:", new DirectNativeMethod("object:childOf:extends:taggedAs:mirroredBy:") {
  2054. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2055. if (ctx.base_receiver() != _INSTANCE_) {
  2056. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2057. }
  2058. checkArity(args, 5);
  2059. ATClosure code = get(args, 1).asClosure();
  2060. ATObject parent = get(args, 2);
  2061. ATBoolean parentType = get(args, 3).asBoolean();
  2062. ATTable types = get(args, 4).asTable();
  2063. ATObject mirror = get(args, 5);
  2064. return _INSTANCE_.base_object_childOf_extends_taggedAs_mirroredBy_(code, parent, parentType, types, mirror);
  2065. }
  2066. });
  2067. _meths.put("reflect:", new DirectNativeMethod("reflect:") {
  2068. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2069. if (ctx.base_receiver() != _INSTANCE_) {
  2070. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2071. }
  2072. checkArity(args, 1);
  2073. ATObject reflectee = get(args, 1);
  2074. return _INSTANCE_.base_reflect_(reflectee);
  2075. }
  2076. });
  2077. _meths.put("clone:", new DirectNativeMethod("clone:") {
  2078. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2079. if (ctx.base_receiver() != _INSTANCE_) {
  2080. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2081. }
  2082. checkArity(args, 1);
  2083. ATObject original = get(args, 1);
  2084. return _INSTANCE_.base_clone_(original);
  2085. }
  2086. });
  2087. _meths.put("takeOffline:", new DirectNativeMethod("takeOffline:") {
  2088. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2089. if (ctx.base_receiver() != _INSTANCE_) {
  2090. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2091. }
  2092. checkArity(args, 1);
  2093. ATObject object = get(args, 1);
  2094. return _INSTANCE_.base_takeOffline_(object);
  2095. }
  2096. });
  2097. _meths.put("disconnect:", new DirectNativeMethod("disconnect:") {
  2098. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2099. if (ctx.base_receiver() != _INSTANCE_) {
  2100. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2101. }
  2102. checkArity(args, 1);
  2103. ATObject object = get(args, 1);
  2104. return _INSTANCE_.base_disconnect_(object);
  2105. }
  2106. });
  2107. _meths.put("is:taggedAs:", new DirectNativeMethod("is:taggedAs:") {
  2108. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2109. if (ctx.base_receiver() != _INSTANCE_) {
  2110. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2111. }
  2112. checkArity(args, 2);
  2113. ATObject object = get(args, 1);
  2114. ATTypeTag type = get(args, 2).asTypeTag();
  2115. return _INSTANCE_.base_is_taggedAs_(object, type);
  2116. }
  2117. });
  2118. _meths.put("tagsOf:", new DirectNativeMethod("tagsOf:") {
  2119. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2120. if (ctx.base_receiver() != _INSTANCE_) {
  2121. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2122. }
  2123. checkArity(args, 1);
  2124. ATObject object = get(args, 1);
  2125. return _INSTANCE_.base_tagsOf_(object);
  2126. }
  2127. });
  2128. _meths.put("try:finally:", new DirectNativeMethod("try:finally:") {
  2129. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2130. if (ctx.base_receiver() != _INSTANCE_) {
  2131. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2132. }
  2133. checkArity(args, 2);
  2134. ATClosure tryBlock = get(args, 1).asClosure();
  2135. ATClosure finallyBlock = get(args, 2).asClosure();
  2136. return _INSTANCE_.base_try_finally_(tryBlock, finallyBlock);
  2137. }
  2138. });
  2139. _meths.put("try:usingHandlers:finally:", new DirectNativeMethod("try:usingHandlers:finally:") {
  2140. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2141. if (ctx.base_receiver() != _INSTANCE_) {
  2142. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2143. }
  2144. checkArity(args, 3);
  2145. ATClosure tryBlock = get(args, 1).asClosure();
  2146. ATTable exceptionHandlers = get(args, 2).asTable();
  2147. ATClosure finallyBlock = get(args, 3).asClosure();
  2148. return _INSTANCE_.base_try_usingHandlers_finally_(tryBlock, exceptionHandlers, finallyBlock);
  2149. }
  2150. });
  2151. _meths.put("try:usingHandlers:", new DirectNativeMethod("try:usingHandlers:") {
  2152. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2153. if (ctx.base_receiver() != _INSTANCE_) {
  2154. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2155. }
  2156. checkArity(args, 2);
  2157. ATClosure tryBlock = get(args, 1).asClosure();
  2158. ATTable exceptionHandlers = get(args, 2).asTable();
  2159. return _INSTANCE_.base_try_usingHandlers_(tryBlock, exceptionHandlers);
  2160. }
  2161. });
  2162. _meths.put("try:using:", new DirectNativeMethod("try:using:") {
  2163. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2164. if (ctx.base_receiver() != _INSTANCE_) {
  2165. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2166. }
  2167. checkArity(args, 2);
  2168. ATClosure tryBlock = get(args, 1).asClosure();
  2169. ATHandler handler = get(args, 2).asHandler();
  2170. return _INSTANCE_.base_try_using_(tryBlock, handler);
  2171. }
  2172. });
  2173. _meths.put("try:using:finally:", new DirectNativeMethod("try:using:finally:") {
  2174. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2175. if (ctx.base_receiver() != _INSTANCE_) {
  2176. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2177. }
  2178. checkArity(args, 3);
  2179. ATClosure tryBlock = get(args, 1).asClosure();
  2180. ATHandler handler = get(args, 2).asHandler();
  2181. ATClosure finallyBlock = get(args, 3).asClosure();
  2182. return _INSTANCE_.base_try_using_finally_(tryBlock, handler, finallyBlock);
  2183. }
  2184. });
  2185. _meths.put("try:using:using:", new DirectNativeMethod("try:using:using:") {
  2186. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2187. if (ctx.base_receiver() != _INSTANCE_) {
  2188. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2189. }
  2190. checkArity(args, 3);
  2191. ATClosure tryBlock = get(args, 1).asClosure();
  2192. ATHandler hdl1 = get(args, 2).asHandler();
  2193. ATHandler hdl2 = get(args, 3).asHandler();
  2194. return _INSTANCE_.base_try_using_using_(tryBlock, hdl1, hdl2);
  2195. }
  2196. });
  2197. _meths.put("try:using:using:finally:", new DirectNativeMethod("try:using:using:finally:") {
  2198. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2199. if (ctx.base_receiver() != _INSTANCE_) {
  2200. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2201. }
  2202. checkArity(args, 4);
  2203. ATClosure tryBlock = get(args, 1).asClosure();
  2204. ATHandler hdl1 = get(args, 2).asHandler();
  2205. ATHandler hdl2 = get(args, 3).asHandler();
  2206. ATClosure finallyBlock = get(args, 4).asClosure();
  2207. return _INSTANCE_.base_try_using_using_finally_(tryBlock, hdl1, hdl2, finallyBlock);
  2208. }
  2209. });
  2210. _meths.put("try:using:using:using:", new DirectNativeMethod("try:using:using:using:") {
  2211. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2212. if (ctx.base_receiver() != _INSTANCE_) {
  2213. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2214. }
  2215. checkArity(args, 4);
  2216. ATClosure tryBlock = get(args, 1).asClosure();
  2217. ATHandler hdl1 = get(args, 2).asHandler();
  2218. ATHandler hdl2 = get(args, 3).asHandler();
  2219. ATHandler hdl3 = get(args, 4).asHandler();
  2220. return _INSTANCE_.base_try_using_using_using_(tryBlock, hdl1, hdl2, hdl3);
  2221. }
  2222. });
  2223. _meths.put("try:using:using:using:finally:", new DirectNativeMethod("try:using:using:using:finally:") {
  2224. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2225. if (ctx.base_receiver() != _INSTANCE_) {
  2226. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2227. }
  2228. checkArity(args, 5);
  2229. ATClosure tryBlock = get(args, 1).asClosure();
  2230. ATHandler hdl1 = get(args, 2).asHandler();
  2231. ATHandler hdl2 = get(args, 3).asHandler();
  2232. ATHandler hdl3 = get(args, 4).asHandler();
  2233. ATClosure finallyBlock = get(args, 5).asClosure();
  2234. return _INSTANCE_.base_try_using_using_using_finally_(tryBlock, hdl1, hdl2, hdl3, finallyBlock);
  2235. }
  2236. });
  2237. _meths.put("try:catch:using:", new DirectNativeMethod("try:catch:using:") {
  2238. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2239. if (ctx.base_receiver() != _INSTANCE_) {
  2240. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2241. }
  2242. checkArity(args, 3);
  2243. ATClosure tryBlock = get(args, 1).asClosure();
  2244. ATTypeTag filter = get(args, 2).asTypeTag();
  2245. ATClosure replacementCode = get(args, 3).asClosure();
  2246. return _INSTANCE_.base_try_catch_using_(tryBlock, filter, replacementCode);
  2247. }
  2248. });
  2249. _meths.put("try:catch:using:finally:", new DirectNativeMethod("try:catch:using:finally:") {
  2250. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2251. if (ctx.base_receiver() != _INSTANCE_) {
  2252. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2253. }
  2254. checkArity(args, 4);
  2255. ATClosure tryBlock = get(args, 1).asClosure();
  2256. ATTypeTag filter = get(args, 2).asTypeTag();
  2257. ATClosure replacementCode = get(args, 3).asClosure();
  2258. ATClosure finallyBlock = get(args, 4).asClosure();
  2259. return _INSTANCE_.base_try_catch_using_finally_(tryBlock, filter, replacementCode, finallyBlock);
  2260. }
  2261. });
  2262. _meths.put("try:catch:using:catch:using:", new DirectNativeMethod("try:catch:using:catch:using:") {
  2263. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2264. if (ctx.base_receiver() != _INSTANCE_) {
  2265. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2266. }
  2267. checkArity(args, 5);
  2268. ATClosure tryBlock = get(args, 1).asClosure();
  2269. ATTypeTag filter1 = get(args, 2).asTypeTag();
  2270. ATClosure hdl1 = get(args, 3).asClosure();
  2271. ATTypeTag filter2 = get(args, 4).asTypeTag();
  2272. ATClosure hdl2 = get(args, 5).asClosure();
  2273. return _INSTANCE_.base_try_catch_using_catch_using_(tryBlock, filter1, hdl1, filter2, hdl2);
  2274. }
  2275. });
  2276. _meths.put("try:catch:using:catch:using:finally:", new DirectNativeMethod("try:catch:using:catch:using:finally:") {
  2277. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2278. if (ctx.base_receiver() != _INSTANCE_) {
  2279. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2280. }
  2281. checkArity(args, 6);
  2282. ATClosure tryBlock = get(args, 1).asClosure();
  2283. ATTypeTag filter1 = get(args, 2).asTypeTag();
  2284. ATClosure hdl1 = get(args, 3).asClosure();
  2285. ATTypeTag filter2 = get(args, 4).asTypeTag();
  2286. ATClosure hdl2 = get(args, 5).asClosure();
  2287. ATClosure finallyBlock = get(args, 6).asClosure();
  2288. return _INSTANCE_.base_try_catch_using_catch_using_finally_(tryBlock, filter1, hdl1, filter2, hdl2, finallyBlock);
  2289. }
  2290. });
  2291. _meths.put("handle:with:", new DirectNativeMethod("handle:with:") {
  2292. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2293. if (ctx.base_receiver() != _INSTANCE_) {
  2294. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2295. }
  2296. checkArity(args, 2);
  2297. ATTypeTag filter = get(args, 1).asTypeTag();
  2298. ATClosure replacementCode = get(args, 2).asClosure();
  2299. return _INSTANCE_.base_handle_with_(filter, replacementCode);
  2300. }
  2301. });
  2302. _meths.put("raise:", new DirectNativeMethod("raise:") {
  2303. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2304. if (ctx.base_receiver() != _INSTANCE_) {
  2305. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2306. }
  2307. checkArity(args, 1);
  2308. ATObject anExceptionObject = get(args, 1);
  2309. return _INSTANCE_.base_raise_(anExceptionObject);
  2310. }
  2311. });
  2312. _meths.put("!", new DirectNativeMethod("!") {
  2313. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2314. if (ctx.base_receiver() != _INSTANCE_) {
  2315. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2316. }
  2317. checkArity(args, 1);
  2318. ATBoolean b = get(args, 1).asBoolean();
  2319. return _INSTANCE_.base__opnot_(b);
  2320. }
  2321. });
  2322. _meths.put("-", new DirectNativeMethod("-") {
  2323. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2324. if (ctx.base_receiver() != _INSTANCE_) {
  2325. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2326. }
  2327. checkArity(args, 1);
  2328. ATNumeric n = get(args, 1).asNativeNumeric();
  2329. return _INSTANCE_.base__opmns_(n);
  2330. }
  2331. });
  2332. _meths.put("+", new DirectNativeMethod("+") {
  2333. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2334. if (ctx.base_receiver() != _INSTANCE_) {
  2335. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2336. }
  2337. checkArity(args, 1);
  2338. ATNumber n = get(args, 1).asNumber();
  2339. return _INSTANCE_.base__oppls_(n);
  2340. }
  2341. });
  2342. _meths.put("read:", new DirectNativeMethod("read:") {
  2343. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2344. if (ctx.base_receiver() != _INSTANCE_) {
  2345. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2346. }
  2347. checkArity(args, 1);
  2348. ATText source = get(args, 1).asNativeText();
  2349. return _INSTANCE_.base_read_(source);
  2350. }
  2351. });
  2352. _meths.put("eval:in:", new DirectNativeMethod("eval:in:") {
  2353. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2354. if (ctx.base_receiver() != _INSTANCE_) {
  2355. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2356. }
  2357. checkArity(args, 2);
  2358. ATAbstractGrammar ast = get(args, 1).asAbstractGrammar();
  2359. ATObject obj = get(args, 2);
  2360. return _INSTANCE_.base_eval_in_(ast, obj);
  2361. }
  2362. });
  2363. _meths.put("print:", new DirectNativeMethod("print:") {
  2364. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2365. if (ctx.base_receiver() != _INSTANCE_) {
  2366. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2367. }
  2368. checkArity(args, 1);
  2369. ATObject obj = get(args, 1);
  2370. return _INSTANCE_.base_print_(obj);
  2371. }
  2372. });
  2373. _meths.put("asCode:", new DirectNativeMethod("asCode:") {
  2374. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2375. if (ctx.base_receiver() != _INSTANCE_) {
  2376. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2377. }
  2378. checkArity(args, 1);
  2379. ATObject obj = get(args, 1);
  2380. return _INSTANCE_.base_asCode_(obj);
  2381. }
  2382. });
  2383. _meths.put("==", new DirectNativeMethod("==") {
  2384. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  2385. if (ctx.base_receiver() != _INSTANCE_) {
  2386. throw new XIllegalOperation("native top-level method invoked on illegal object: "+ctx.base_receiver());
  2387. }
  2388. checkArity(args, 1);
  2389. ATObject comparand = get(args, 1);
  2390. return _INSTANCE_.base__opeql__opeql_(comparand);
  2391. }
  2392. });
  2393. }
  2394. /**
  2395. * Overrides the default AmbientTalk native object behavior of extracting native
  2396. * methods based on the 'base_' naming convention. Instead, the lexical root uses
  2397. * an explicit hashmap of native methods. This is much faster than the default
  2398. * behavior, which requires reflection.
  2399. */
  2400. protected boolean hasLocalMethod(ATSymbol atSelector) throws InterpreterException {
  2401. if (_meths.containsKey(atSelector.base_text().asNativeText().javaValue)) {
  2402. return true;
  2403. } else {
  2404. return super.hasLocalMethod(atSelector);
  2405. }
  2406. }
  2407. /**
  2408. * @see OBJLexicalRoot#hasLocalMethod(ATSymbol)
  2409. */
  2410. protected ATMethod getLocalMethod(ATSymbol selector) throws InterpreterException {
  2411. ATMethod val = _meths.get(selector.base_text().asNativeText().javaValue);
  2412. if (val == null) {
  2413. return super.getLocalMethod(selector);
  2414. //throw new XSelectorNotFound(selector, this);
  2415. }
  2416. return val;
  2417. }
  2418. }