--- /dev/null
+package org.simantics.scl.compiler.internal.elaboration.decomposed;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
+import org.simantics.scl.compiler.elaboration.expressions.ELambdaType;\r
+import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
+import org.simantics.scl.compiler.top.SCLCompilerConfiguration;\r
+import org.simantics.scl.compiler.types.TVar;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+\r
+public class DecomposedExpression {\r
+ public final TVar[] typeParameters;\r
+ public final Variable[] parameters;\r
+ public final Type[] parameterTypes;\r
+ public final Type effect;\r
+ public final Type returnType;\r
+ public final Expression body;\r
+ \r
+ public DecomposedExpression(TVar[] typeParameters, Variable[] parameters,\r
+ Type[] parameterTypes, Type effect, Type returnType, Expression body) {\r
+ super();\r
+ if(SCLCompilerConfiguration.DEBUG)\r
+ if(effect == null)\r
+ throw new InternalCompilerError();\r
+ this.typeParameters = typeParameters;\r
+ this.parameters = parameters;\r
+ this.parameterTypes = parameterTypes;\r
+ this.effect = effect;\r
+ this.returnType = returnType;\r
+ this.body = body;\r
+ }\r
+\r
+ public static DecomposedExpression decompose(Expression expression) {\r
+ ArrayList<TVar> typeParameterList = new ArrayList<TVar>();\r
+ ArrayList<Variable> parameterList = new ArrayList<Variable>();\r
+ Type effect = Types.NO_EFFECTS;\r
+ while(true) {\r
+ if(expression instanceof ESimpleLambda) {\r
+ ESimpleLambda lambda = (ESimpleLambda)expression;\r
+ parameterList.add(lambda.parameter);\r
+ expression = lambda.value;\r
+ if(Types.canonical(effect) != Types.NO_EFFECTS)\r
+ throw new InternalCompilerError();\r
+ effect = Types.simplifyFinalEffect(lambda.getLocalEffect());\r
+ } \r
+ else if(expression instanceof ELambdaType) {\r
+ ELambdaType lambda = (ELambdaType)expression;\r
+ expression = lambda.value;\r
+ for(TVar parameter : lambda.parameters)\r
+ typeParameterList.add(parameter);\r
+ }\r
+ else \r
+ break;\r
+ } \r
+ \r
+ TVar[] typeParameters = typeParameterList.isEmpty() ? TVar.EMPTY_ARRAY : \r
+ typeParameterList.toArray(new TVar[typeParameterList.size()]);\r
+ Variable[] parameters = parameterList.toArray(new Variable[parameterList.size()]);\r
+ Type[] parameterTypes = Types.getTypes(parameters);\r
+ Type returnType = expression.getType();\r
+ \r
+ return new DecomposedExpression(\r
+ typeParameters, parameters, \r
+ parameterTypes, effect, returnType, \r
+ expression);\r
+ }\r
+}\r