1 package org.simantics.scl.compiler.internal.elaboration.decomposed;
3 import java.util.ArrayList;
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.errors.ErrorLog;
11 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
12 import org.simantics.scl.compiler.types.TVar;
13 import org.simantics.scl.compiler.types.Type;
14 import org.simantics.scl.compiler.types.Types;
16 public class DecomposedExpression {
17 public final TVar[] typeParameters;
18 public final Variable[] parameters;
19 public final Type[] parameterTypes;
20 public final Type effect;
21 public final Type returnType;
22 public final Expression body;
24 public DecomposedExpression(TVar[] typeParameters, Variable[] parameters,
25 Type[] parameterTypes, Type effect, Type returnType, Expression body) {
27 if(SCLCompilerConfiguration.DEBUG)
29 throw new InternalCompilerError();
30 this.typeParameters = typeParameters;
31 this.parameters = parameters;
32 this.parameterTypes = parameterTypes;
34 this.returnType = returnType;
38 public static DecomposedExpression decompose(ErrorLog errorLog, Expression expression) {
39 ArrayList<TVar> typeParameterList = new ArrayList<TVar>();
40 ArrayList<Variable> parameterList = new ArrayList<Variable>();
41 Type effect = Types.NO_EFFECTS;
43 if(expression instanceof ESimpleLambda) {
44 ESimpleLambda lambda = (ESimpleLambda)expression;
45 parameterList.add(lambda.parameter);
46 if(Types.canonical(effect) != Types.NO_EFFECTS)
47 errorLog.logWarning(expression.location, "Encountered nested lambdas where outermost lambda contains effects. The reason is probably in the subsumption solver and code should be OK.");
48 expression = lambda.value;
49 effect = Types.simplifyFinalEffect(lambda.getLocalEffect());
51 else if(expression instanceof ELambdaType) {
52 ELambdaType lambda = (ELambdaType)expression;
53 expression = lambda.value;
54 for(TVar parameter : lambda.parameters)
55 typeParameterList.add(parameter);
61 TVar[] typeParameters = typeParameterList.isEmpty() ? TVar.EMPTY_ARRAY :
62 typeParameterList.toArray(new TVar[typeParameterList.size()]);
63 Variable[] parameters = parameterList.toArray(new Variable[parameterList.size()]);
64 Type[] parameterTypes = Types.getTypes(parameters);
65 Type returnType = expression.getType();
67 return new DecomposedExpression(
68 typeParameters, parameters,
69 parameterTypes, effect, returnType,