ThisExp.java 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. package gnu.expr;
  2. import gnu.bytecode.*;
  3. import gnu.mapping.*;
  4. /** Evaluates to the "this" implicit variable.
  5. * This is currently neither robust nor general. FIXME!
  6. */
  7. public class ThisExp extends ReferenceExp
  8. {
  9. /** Non-interned name for implicit 'this' variable. */
  10. public static final String THIS_NAME = new String("$this$");
  11. /** When evaluating, return the context.
  12. * This is used for the "context" of a Macro.
  13. */
  14. static int EVAL_TO_CONTEXT = NEXT_AVAIL_FLAG;
  15. /** The class which this refers to. */
  16. ScopeExp context;
  17. /** If this is being used to pass the context instance to a Macro. */
  18. public final boolean isForContext ()
  19. {
  20. return (flags & EVAL_TO_CONTEXT) != 0;
  21. }
  22. @Override
  23. public void apply (CallContext ctx)
  24. throws Throwable
  25. {
  26. if (isForContext())
  27. ctx.writeValue(context);
  28. else
  29. super.apply(ctx);
  30. }
  31. public ScopeExp getContextScope () { return context; }
  32. public ThisExp ()
  33. {
  34. super(THIS_NAME);
  35. }
  36. public ThisExp(ScopeExp context)
  37. {
  38. this();
  39. this.context = context;
  40. }
  41. public ThisExp (Declaration binding)
  42. {
  43. super(THIS_NAME, binding);
  44. }
  45. public ThisExp (ClassType type)
  46. {
  47. this(new Declaration(THIS_NAME, type));
  48. }
  49. public static ThisExp makeGivingContext (ScopeExp context)
  50. {
  51. ThisExp exp = new ThisExp(context);
  52. exp.flags |= EVAL_TO_CONTEXT;
  53. return exp;
  54. }
  55. public void compile (Compilation comp, Target target)
  56. {
  57. if (target instanceof IgnoreTarget)
  58. return;
  59. if (isForContext())
  60. {
  61. // This is an extension used by define_syntax.
  62. CodeAttr code = comp.getCode();
  63. ScopeExp context = getContextScope();
  64. if (context instanceof ModuleExp
  65. && ((ModuleExp) context).isStatic())
  66. comp.loadClassRef(((LambdaExp) context).getCompiledClassType(comp));
  67. else if (comp.method.getStaticFlag())
  68. code.emitGetStatic(comp.moduleInstanceMainField);
  69. else
  70. code.emitPushThis();
  71. target.compileFromStack(comp, getType());
  72. }
  73. else
  74. {
  75. super.compile(comp, target);
  76. }
  77. }
  78. protected <R,D> R visit (ExpVisitor<R,D> visitor, D d)
  79. {
  80. return visitor.visitThisExp(this, d);
  81. }
  82. protected final gnu.bytecode.Type calculateType()
  83. {
  84. if (binding != null)
  85. return binding.getType();
  86. if (context instanceof ClassExp || context instanceof ModuleExp)
  87. return context.getType();
  88. return Type.pointer_type;
  89. }
  90. }