001: package gnu.expr;
002:
003: import gnu.bytecode.*;
004: import gnu.kawa.reflect.Invoke;
005:
006: public class InlineCalls extends ExpWalker {
007: public static void inlineCalls(Expression exp, Compilation comp) {
008: InlineCalls walker = new InlineCalls(comp);
009: walker.walk(exp);
010: }
011:
012: public InlineCalls(Compilation comp) {
013: setContext(comp);
014: }
015:
016: protected Expression walkApplyExp(ApplyExp exp) {
017: super .walkApplyExp(exp);
018: return walkApplyOnly(exp);
019: }
020:
021: /** Walk an ApplyExp assuming function and arguments have been walked. */
022: public Expression walkApplyOnly(ApplyExp exp) {
023: return exp.func.inline(exp, this , null);
024: }
025:
026: protected Expression walkReferenceExp(ReferenceExp exp) {
027: Declaration decl = exp.getBinding();
028: if (decl != null && decl.getFlag(Declaration.IS_CONSTANT)
029: && decl.field == null) {
030: Expression dval = decl.getValue();
031: if (dval instanceof QuoteExp
032: && dval != QuoteExp.undefined_exp)
033: return walkQuoteExp((QuoteExp) dval);
034: }
035: return super .walkReferenceExp(exp);
036: }
037:
038: protected Expression walkIfExp(IfExp exp) {
039: Expression test = exp.test.walk(this );
040: if (test instanceof ReferenceExp) {
041: Declaration decl = ((ReferenceExp) test).getBinding();
042: if (decl != null) {
043: Expression value = decl.getValue();
044: if (value instanceof QuoteExp
045: && value != QuoteExp.undefined_exp)
046: test = value;
047: }
048: }
049: if (test instanceof QuoteExp) {
050: return walk(comp.getLanguage().isTrue(
051: ((QuoteExp) test).getValue()) ? exp.then_clause
052: : exp.else_clause == null ? QuoteExp.voidExp
053: : exp.else_clause);
054: }
055: exp.test = test;
056: if (exitValue == null)
057: exp.then_clause = walk(exp.then_clause);
058: if (exitValue == null && exp.else_clause != null)
059: exp.else_clause = walk(exp.else_clause);
060: return exp;
061: }
062:
063: protected Expression walkLetExp(LetExp exp) {
064: Declaration decl = exp.firstDecl();
065: int n = exp.inits.length;
066: for (int i = 0; i < n; i++, decl = decl.nextDecl()) {
067: Expression init0 = exp.inits[i];
068: Expression init = walk(init0);
069: exp.inits[i] = init;
070: Expression dvalue = decl.value;
071: if (dvalue == init0) {
072: decl.value = dvalue = init;
073: if (!decl.getFlag(Declaration.TYPE_SPECIFIED))
074: decl.setType(dvalue.getType());
075: }
076: }
077:
078: if (exitValue == null)
079: exp.body = (Expression) walk(exp.body);
080: if (exp.body instanceof ReferenceExp) {
081: ReferenceExp ref = (ReferenceExp) exp.body;
082: Declaration d = ref.getBinding();
083: if (d != null && d.context == exp
084: && !ref.getDontDereference()) {
085: if (n == 1)
086: return exp.inits[0];
087: // Can also optimize if n > 1, but have to check if any
088: // other inits can cause side-effects. Probably not worth it.
089: }
090: }
091: return exp;
092: }
093:
094: protected Expression walkLambdaExp(LambdaExp exp) {
095: Declaration firstDecl = exp.firstDecl();
096: if (firstDecl != null && firstDecl.isThisParameter()
097: && !exp.isClassMethod() && firstDecl.getType() == null) {
098: firstDecl.setType(comp.mainClass);
099: }
100: return walkScopeExp(exp);
101: }
102:
103: /*
104: protected Expression walkSetExp (SetExp exp)
105: {
106: super.walkExp(exp);
107: if (decl != null && ! decl.getFlag(Declaration.TYPE_SPECIFIED))
108: {
109: // This is a kludge to handle the a #!rest parameter that
110: // is implicitly declared to be a Scheme <list>, but may be
111: // assinged some other value, which is a legal Scheme idiom.
112: // We could set implicitly set the parameter type to <list>,
113: // but doing so improves type inference in the common case.
114: Type declType = decl.getType();
115: if (declType != null && ! exp.new_value.getType().isSubtype(declType))
116: decl.setType(Type.pointer_type);
117: }
118: return exp;
119: }
120: */
121: }
|