]> gerrit.simantics Code Review - simantics/platform.git/blob
0ad3096b237a9c0d3279af6295f87f7b9c15f2a7
[simantics/platform.git] /
1 package org.simantics.scl.compiler.internal.elaboration.decomposed;
2
3 import java.util.ArrayList;
4
5 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
6 import org.simantics.scl.compiler.elaboration.expressions.ELambdaType;
7 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
8 import org.simantics.scl.compiler.elaboration.expressions.Expression;
9 import org.simantics.scl.compiler.elaboration.expressions.Variable;
10 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
11 import org.simantics.scl.compiler.types.TVar;
12 import org.simantics.scl.compiler.types.Type;
13 import org.simantics.scl.compiler.types.Types;
14
15 public class DecomposedExpression {
16     public final TVar[] typeParameters;
17     public final Variable[] parameters;
18     public final Type[] parameterTypes;
19     public final Type effect;
20     public final Type returnType;
21     public final Expression body;
22     
23     public DecomposedExpression(TVar[] typeParameters, Variable[] parameters,
24             Type[] parameterTypes, Type effect, Type returnType, Expression body) {
25         super();
26         if(SCLCompilerConfiguration.DEBUG)
27             if(effect == null)
28                 throw new InternalCompilerError();
29         this.typeParameters = typeParameters;
30         this.parameters = parameters;
31         this.parameterTypes = parameterTypes;
32         this.effect = effect;
33         this.returnType = returnType;
34         this.body = body;
35     }
36
37     public static DecomposedExpression decompose(Expression expression) {
38         ArrayList<TVar> typeParameterList = new ArrayList<TVar>();
39         ArrayList<Variable> parameterList = new ArrayList<Variable>();
40         Type effect = Types.NO_EFFECTS;
41         while(true) {
42             if(expression instanceof ESimpleLambda) {
43                 ESimpleLambda lambda = (ESimpleLambda)expression;
44                 parameterList.add(lambda.parameter);
45                 expression = lambda.value;
46                 if(Types.canonical(effect) != Types.NO_EFFECTS)
47                     throw new InternalCompilerError();
48                 effect = Types.simplifyFinalEffect(lambda.getLocalEffect());
49             } 
50             else if(expression instanceof ELambdaType) {
51                 ELambdaType lambda = (ELambdaType)expression;
52                 expression = lambda.value;
53                 for(TVar parameter : lambda.parameters)
54                     typeParameterList.add(parameter);
55             }
56             else 
57                 break;
58         }      
59         
60         TVar[] typeParameters = typeParameterList.isEmpty() ? TVar.EMPTY_ARRAY : 
61             typeParameterList.toArray(new TVar[typeParameterList.size()]);
62         Variable[] parameters = parameterList.toArray(new Variable[parameterList.size()]);
63         Type[] parameterTypes = Types.getTypes(parameters);
64         Type returnType = expression.getType();
65         
66         return new DecomposedExpression(
67                 typeParameters, parameters, 
68                 parameterTypes, effect, returnType, 
69                 expression);
70     }
71 }