01: package gnu.expr;
02:
03: /** Sets up the firstChild/nextSibling links of each LambdaExp.
04: * Setup 'outer' links of ScopeExp and its sub-classes.
05: * Also generates a class name for each ClassExp and registers each class.
06: * Also, if lambda is bound to a unique declaration, make that its name.
07: */
08:
09: public class ChainLambdas extends ExpWalker {
10: Compilation comp;
11: ScopeExp currentScope;
12:
13: public static void chainLambdas(Expression exp, Compilation comp) {
14: ChainLambdas walker = new ChainLambdas();
15: walker.comp = comp;
16: exp.walk(walker);
17: //or: walter.walkExpression(exp);
18: }
19:
20: protected Expression walkScopeExp(ScopeExp exp) {
21: ScopeExp saveScope = currentScope;
22: try {
23: /* Nice: We keep outer if it exists. This is used for Nice classes,
24: whose outer is the 'fun' class which holds the anonymous
25: functions occuring in the class methods (overriding of
26: native methods).
27: */
28: if (exp.outer == null)
29: exp.outer = currentScope;
30: currentScope = exp;
31: exp.walkChildren(this );
32: return exp;
33: } finally {
34: currentScope = saveScope;
35: }
36: }
37:
38: protected Expression walkLambdaExp(LambdaExp exp) {
39: LambdaExp parent = currentLambda;
40: if (parent != null && !(parent instanceof ClassExp)) {
41: exp.nextSibling = parent.firstChild;
42: parent.firstChild = exp;
43: }
44:
45: ScopeExp saveScope = currentScope;
46: try {
47: exp.outer = currentScope;
48: currentScope = exp;
49: exp.walkChildrenOnly(this );
50: } finally {
51: currentScope = saveScope;
52: }
53: exp.walkProperties(this );
54:
55: // Put list of children in proper order.
56: LambdaExp prev = null, child = exp.firstChild;
57: while (child != null) {
58: LambdaExp next = child.nextSibling;
59: child.nextSibling = prev;
60: prev = child;
61: child = next;
62: }
63: exp.firstChild = prev;
64:
65: if (exp.getName() == null && exp.nameDecl != null)
66: exp.setName(exp.nameDecl.getName());
67: return exp;
68: }
69:
70: protected Expression walkClassExp(ClassExp exp) {
71: LambdaExp parent = currentLambda;
72: if (parent != null && !(parent instanceof ClassExp)) {
73: exp.nextSibling = parent.firstChild;
74: parent.firstChild = exp;
75: }
76:
77: walkScopeExp(exp);
78:
79: // Give name to object class.
80: exp.getCompiledClassType(comp);
81: comp.addClass(exp.type);
82: if (exp.isMakingClassPair()) {
83: exp.instanceType.setName(exp.type.getName() + "$class");
84: comp.addClass(exp.instanceType);
85: }
86: return exp;
87: }
88: }
|