]> gerrit.simantics Code Review - simantics/platform.git/blob
6319e58b25d07dbc749059cfbd42a793b29a3627
[simantics/platform.git] /
1 package org.simantics.scl.compiler.elaboration.macros;
2
3 import gnu.trove.map.hash.THashMap;
4
5 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
6 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
7 import org.simantics.scl.compiler.elaboration.expressions.EApply;
8 import org.simantics.scl.compiler.elaboration.expressions.ELambda;
9 import org.simantics.scl.compiler.elaboration.expressions.ELambdaType;
10 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
11 import org.simantics.scl.compiler.elaboration.expressions.Expression;
12 import org.simantics.scl.compiler.elaboration.expressions.Variable;
13 import org.simantics.scl.compiler.types.TVar;
14 import org.simantics.scl.compiler.types.Type;
15
16 /**
17  * This is a macro rule that replaces an application with
18  * the definition of the function.
19  * @author Hannu Niemistö
20  */
21 public class StandardMacroRule implements MacroRule {
22     Expression baseExpression;
23     int arity;
24     
25     public StandardMacroRule() {
26     }
27     
28     public void setBaseExpression(Expression baseExpression) {
29         this.baseExpression = baseExpression;
30         
31         Expression cur = baseExpression;
32         while(true) {
33             if(cur instanceof ELambdaType) {
34                 cur = ((ELambdaType)cur).value;                
35             }
36             else if(cur instanceof ELambda) {
37                 ELambda lambda = (ELambda)cur;
38                 arity += lambda.getCases()[0].getPatterns().length;
39                 break;
40             }
41             else if(cur instanceof ESimpleLambda) {
42                 ESimpleLambda lambda = (ESimpleLambda)cur;
43                 cur = lambda.value;
44                 ++arity;
45             }
46             else
47                 break;
48         }
49     }
50
51     @Override
52     public Expression apply(SimplificationContext context,
53             Type[] typeParameters, EApply apply) {
54         if(apply.getParameters().length < arity)
55             return null;
56         THashMap<TVar, Type> tvarMap = new THashMap<TVar, Type>();
57         THashMap<Variable, Expression> varMap = new THashMap<Variable, Expression>();
58         
59         Expression baseExpr = baseExpression;
60         /*System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
61         TypeUnparsingContext tuc = new TypeUnparsingContext();
62         System.out.println("initial1 = " + baseExpr.toString(tuc));
63         */
64         {
65             int typeParameterId = 0;
66             while(typeParameterId < typeParameters.length) {            
67                 ELambdaType lambda = (ELambdaType)baseExpr;
68                 for(TVar var : lambda.parameters)                    
69                     tvarMap.put(var, typeParameters[typeParameterId++]);
70                 baseExpr = lambda.value;
71             }
72         }
73         for(Expression parameter : apply.getParameters()) {
74             if(baseExpr instanceof ELambda)
75                 baseExpr = ((ELambda)baseExpr).decomposeMatching();
76             ESimpleLambda lambda = (ESimpleLambda)baseExpr;
77             varMap.put(lambda.parameter, parameter);
78             baseExpr = lambda.value;
79         }
80         
81         /*
82         
83         System.out.println("initial2 = " + baseExpr.toString(tuc));
84         
85         System.out.print("tvarMap={");
86         boolean first = true;
87         for(Map.Entry<TVar, Type> entry : tvarMap.entrySet()) {
88             if(first)
89                 first = false;
90             else
91                 System.out.print(", ");
92             System.out.print(entry.getKey().toString(tuc));
93             System.out.print(" = ");
94             System.out.print(entry.getValue().toString(tuc));
95         }
96         System.out.println("}");
97         System.out.println("varMap = " + varMap);
98         */
99         baseExpr = baseExpr.replace(new ReplaceContext(tvarMap, varMap, null));
100         
101         //System.out.println("final = " + baseExpr.toString(tuc));
102         
103         return baseExpr;
104     }
105
106 }