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