--- /dev/null
+package org.simantics.scl.compiler.internal.elaboration.constraints;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.elaboration.expressions.ELambda;
+import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
+import org.simantics.scl.compiler.elaboration.expressions.ESimpleLet;
+import org.simantics.scl.compiler.elaboration.expressions.Expression;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+
+public class ExpressionAugmentation {
+
+ private static Expression augmentSolvedAux(ArrayList<Constraint> solved, Expression expression) {
+ long loc = expression.getLocation();
+ for(int i=solved.size()-1;i>=0;--i) {
+ Constraint c = solved.get(i);
+ Type type = expression.getType();
+ expression = new ESimpleLet(loc, c.evidence, c.generate(loc), expression);
+ expression.setType(type);
+ }
+ return expression;
+ }
+
+ public static Expression augmentSolved(
+ ArrayList<Constraint> solved, Expression expression) {
+ // Decompose complex lambda to simple lambdas and matching
+ if(expression instanceof ELambda)
+ expression = expression.decomposeMatching();
+
+ // Inject generation of solved constraints inside the lambdas
+ if(expression instanceof ESimpleLambda) {
+ ESimpleLambda cur = (ESimpleLambda)expression;
+ while(cur.value instanceof ESimpleLambda)
+ cur = (ESimpleLambda)cur.value;
+ cur.value = augmentSolvedAux(solved, cur.value);
+ }
+ else
+ expression = augmentSolvedAux(solved, expression);
+
+ return expression;
+ }
+
+ public static Expression augmentUnsolved(
+ ArrayList<Constraint> unsolved, Expression expression) {
+ long loc = expression.getLocation();
+
+ for(int i=unsolved.size()-1;i>=0;--i) {
+ Constraint c = unsolved.get(i);
+ Type type = expression.getType();
+ expression = new ESimpleLambda(loc, c.evidence, expression);
+ expression.setType(Types.constrained(c.constraint, type));
+ }
+ return expression;
+ }
+}