X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Fcompilation%2FTypeCheckingScheduler.java;fp=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Fcompilation%2FTypeCheckingScheduler.java;h=c3fb2dda7076d74f0e9924e8eed00197e950f557;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeCheckingScheduler.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeCheckingScheduler.java new file mode 100644 index 000000000..c3fb2dda7 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeCheckingScheduler.java @@ -0,0 +1,117 @@ +package org.simantics.scl.compiler.compilation; + +import gnu.trove.impl.Constants; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + +import java.util.ArrayList; + +import org.simantics.scl.compiler.elaboration.contexts.TypingContext; +import org.simantics.scl.compiler.elaboration.expressions.Variable; +import org.simantics.scl.compiler.elaboration.modules.SCLValue; +import org.simantics.scl.compiler.environment.Environment; +import org.simantics.scl.compiler.errors.ErrorLog; +import org.simantics.scl.compiler.internal.elaboration.constraints.Constraint; +import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents; +import org.simantics.scl.compiler.types.TPred; +import org.simantics.scl.compiler.types.TVar; + +/** + * Schedules the order of type checking. + * + * @author Hannu Niemistö + */ +public class TypeCheckingScheduler { + final ErrorLog errorLog; + final Environment environment; + + ArrayList definitions = new ArrayList(); + ArrayList postTypeCheckingRunnables = new ArrayList(); + + public TypeCheckingScheduler(ErrorLog errorLog, Environment environment) { + this.errorLog = errorLog; + this.environment = environment; + } + + public void addTypeInferableDefinition(TypeInferableDefinition definition) { + definitions.add(definition); + } + + public void addPostTypeCheckingRunnable(Runnable runnable) { + postTypeCheckingRunnables.add(runnable); + } + + public void schedule() { + final TObjectIntHashMap allRefs = + new TObjectIntHashMap(definitions.size(), Constants.DEFAULT_LOAD_FACTOR, -1); + + for(int i=0;i(); + + for(int c : component) + definitions.get(c).initializeTypeChecking(context); + for(int c : component) + definitions.get(c).checkType(context); + context.solveSubsumptions(definitions.get(component[0]).getLocation()); + for(int c : component) + definitions.get(c).solveConstraints(); + + THashSet varSet = new THashSet(); + for(int c : component) + definitions.get(c).collectFreeTypeVariables(varSet); + TVar[] vars = varSet.toArray(new TVar[varSet.size()]); + + THashSet constraintSet = new THashSet(); + for(int c : component) + for(Variable evidence : definitions.get(c).getFreeEvidence()) + constraintSet.add((TPred)evidence.getType()); + TPred[] constraints = constraintSet.toArray(new TPred[constraintSet.size()]); + + THashMap constraintMap = null; + for(TPred constraint : constraints) + if(constraint.containsMetaVars()) { + if(constraintMap == null) { + constraintMap = new THashMap(); + for(int c : component) + for(Constraint cons : definitions.get(c).getUnsolvedConstraints()) + constraintMap.put(cons.constraint, cons); + } + Constraint cons = constraintMap.get(constraint); + errorLog.log(cons.getDemandLocation(), + "Constrain " + constraint + + " contains free variables not mentioned in the type of the value."); + } + + for(int c : component) + definitions.get(c).injectEvidence(vars, constraints); + } +}