package org.simantics.scl.compiler.elaboration.expressions; import java.util.ArrayList; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.compilation.CompilationContext; import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.references.BoundVar; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; import org.simantics.scl.compiler.internal.codegen.writer.RecursiveDefinitionWriter; import org.simantics.scl.compiler.internal.elaboration.decomposed.DecomposedExpression; import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; import org.simantics.scl.compiler.types.kinds.Kinds; import gnu.trove.map.hash.TObjectIntHashMap; import gnu.trove.set.hash.TIntHashSet; /** * Generated maily from EPreLet */ public class ELet extends Expression { public Assignment[] assignments; public Expression in; public ELet(long loc, Assignment[] assignments, Expression in) { super(loc); this.assignments = assignments; this.in = in; } @Override public void collectVars(TObjectIntHashMap allVars, TIntHashSet vars) { for(Assignment assign : assignments) assign.value.collectVars(allVars, vars); in.collectVars(allVars, vars); } @Override protected void updateType() throws MatchException { setType(in.getType()); } /** * Splits let */ @Override public Expression simplify(SimplificationContext context) { // Simplify assignments for(Assignment assignment : assignments) { assignment.value = assignment.value.simplify(context); } // Find strongly connected components final TObjectIntHashMap allVars = new TObjectIntHashMap( 2*assignments.length, 0.5f, -1); for(int i=0;i components = new ArrayList(Math.max(10, assignments.length)); new StronglyConnectedComponents(assignments.length) { @Override protected int[] findDependencies(int u) { TIntHashSet vars = new TIntHashSet(); assignments[u].value.collectVars(allVars, vars); if(vars.contains(u)) isRecursive[u] = true; return vars.toArray(); } @Override protected void reportComponent(int[] component) { components.add(component); } }.findComponents(); // Simplify in Expression result = in.simplify(context); // Handle each component for(int j=components.size()-1;j>=0;--j) { int[] component = components.get(j); boolean recursive = component.length > 1 || isRecursive[component[0]]; if(recursive) { Assignment[] cAssignments = new Assignment[component.length]; for(int i=0;i