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