/interpreter/tags/at2-build060407/src/edu/vub/at/objects/natives/grammar/AGDefFunction.java

http://ambienttalk.googlecode.com/ · Java · 118 lines · 53 code · 11 blank · 54 comment · 2 complexity · 401c9c090cf851bb3b0bfa36ab08522c MD5 · raw file

  1. /**
  2. * AmbientTalk/2 Project
  3. * AGDefFunction.java created on 26-jul-2006 at 15:44:08
  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.grammar;
  29. import edu.vub.at.eval.Evaluator;
  30. import edu.vub.at.exceptions.InterpreterException;
  31. import edu.vub.at.objects.ATContext;
  32. import edu.vub.at.objects.ATObject;
  33. import edu.vub.at.objects.ATTable;
  34. import edu.vub.at.objects.grammar.ATBegin;
  35. import edu.vub.at.objects.grammar.ATDefMethod;
  36. import edu.vub.at.objects.grammar.ATSymbol;
  37. import edu.vub.at.objects.natives.NATClosure;
  38. import edu.vub.at.objects.natives.NATMethod;
  39. import edu.vub.at.objects.natives.NATText;
  40. /**
  41. * The native implementation of a function definition abstract grammar element.
  42. * This AG element covers both method and closure definition.
  43. *
  44. * @author tvc
  45. */
  46. public final class AGDefFunction extends NATAbstractGrammar implements ATDefMethod {
  47. private final ATSymbol selectorExp_;
  48. private final ATTable argumentExps_;
  49. private final ATBegin bodyStmts_;
  50. public AGDefFunction(ATSymbol sel, ATTable args, ATBegin bdy) {
  51. selectorExp_ = sel;
  52. argumentExps_ = args;
  53. bodyStmts_ = bdy;
  54. }
  55. public ATSymbol base_getSelector() {
  56. return selectorExp_;
  57. }
  58. public ATTable base_getArguments() {
  59. return argumentExps_;
  60. }
  61. public ATBegin base_getBodyExpression() {
  62. return bodyStmts_;
  63. }
  64. /**
  65. * Defines a new function (method or closure) in the current scope.
  66. * If a function definition is executed in the context of an object,
  67. * a new method is created. If, however, the function definition
  68. * is executed in the context of a call frame (i.e. its definition
  69. * is nested within a method/function) then a closure is created instead.
  70. *
  71. * The return value of a function definition is always a closure encapsulating the function.
  72. *
  73. * AGDEFFUN(nam,par,bdy).eval(ctx) =
  74. * if ctx.scope.isCallFrame
  75. * ctx.scope.defineField(nam, AGCLO(AGMTH(nam,par,bdy), ctx))
  76. * else
  77. * ctx.scope.addMethod(nam, AGMTH(nam,par,bdy))
  78. *
  79. */
  80. public ATObject meta_eval(ATContext ctx) throws InterpreterException {
  81. ATObject current = ctx.base_getLexicalScope();
  82. if (current.isCallFrame()) {
  83. NATClosure clo = new NATClosure(new NATMethod(selectorExp_, argumentExps_, bodyStmts_), ctx);
  84. current.meta_defineField(selectorExp_, clo);
  85. return clo;
  86. } else {
  87. current.meta_addMethod(new NATMethod(selectorExp_, argumentExps_, bodyStmts_));
  88. return current.meta_select(current, selectorExp_);
  89. }
  90. }
  91. /**
  92. * Quoting a function definition results in a new quoted function definition.
  93. *
  94. * AGDEFFUN(nam,par,bdy).quote(ctx) = AGDEFFUN(nam.quote(ctx), par.quote(ctx), bdy.quote(ctx))
  95. */
  96. public ATObject meta_quote(ATContext ctx) throws InterpreterException {
  97. return new AGDefFunction(selectorExp_.meta_quote(ctx).asSymbol(),
  98. argumentExps_.meta_quote(ctx).asTable(),
  99. bodyStmts_.meta_quote(ctx).asBegin());
  100. }
  101. public NATText meta_print() throws InterpreterException {
  102. return NATText.atValue("def " +
  103. selectorExp_.meta_print().javaValue +
  104. Evaluator.printAsList(argumentExps_).javaValue +
  105. " { " + bodyStmts_.meta_print().javaValue + " }");
  106. }
  107. }