X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Fcompilation%2FTypeChecking.java;h=3118142df09740dce51ead4cf262f058f0b11b0b;hp=97266d6e9781e16d2c5d77ba4d0107b80f8ee251;hb=e73c1660b2f4d2a03784451e9e6afe1552b00877;hpb=969bd23cab98a79ca9101af33334000879fb60c5 diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeChecking.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeChecking.java index 97266d6e9..3118142df 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeChecking.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeChecking.java @@ -5,16 +5,13 @@ import static org.simantics.scl.compiler.elaboration.expressions.Expressions.app import static org.simantics.scl.compiler.elaboration.expressions.Expressions.lambda; import static org.simantics.scl.compiler.elaboration.expressions.Expressions.loc; import static org.simantics.scl.compiler.elaboration.expressions.Expressions.vars; -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 java.util.Collection; import java.util.Collections; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; +import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous; import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder; import org.simantics.scl.compiler.elaboration.expressions.ETransformation; import org.simantics.scl.compiler.elaboration.expressions.EVariable; @@ -28,7 +25,6 @@ import org.simantics.scl.compiler.elaboration.relations.SCLRelation; import org.simantics.scl.compiler.elaboration.rules.MappingRelation; import org.simantics.scl.compiler.elaboration.rules.TransformationRule; 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.constraints.ConstraintEnvironment; import org.simantics.scl.compiler.internal.elaboration.constraints.ConstraintSolver; @@ -42,18 +38,22 @@ import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.kinds.Kinds; import org.simantics.scl.compiler.types.util.Polarity; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public class TypeChecking { - final ErrorLog errorLog; + final CompilationContext compilationContext; final Environment environment; final ConcreteModule module; ConstraintEnvironment ce; TypeCheckingScheduler scheduler; - public TypeChecking(ErrorLog errorLog, Environment environment, - ConcreteModule module) { - this.errorLog = errorLog; - this.environment = environment; + public TypeChecking(CompilationContext compilationContext, ConcreteModule module) { + this.compilationContext = compilationContext; + this.environment = compilationContext.environment; this.module = module; } @@ -97,6 +97,8 @@ public class TypeChecking { context.pushEffectUpperBound(expression.location, Types.PROC); expression = expression.checkType(context, value.getType()); context.popEffectUpperBound(); + for(EAmbiguous overloaded : context.overloadedExpressions) + overloaded.assertResolved(compilationContext.errorLog); value.setExpression(expression); ArrayList constraintDemand = context.getConstraintDemand(); @@ -125,7 +127,7 @@ public class TypeChecking { for(Constraint c : red.unsolvedConstraints) if(c.constraint.isGround()) - errorLog.log(c.getDemandLocation(), "There is no instance for <"+c.constraint+">."); + compilationContext.errorLog.log(c.getDemandLocation(), "There is no instance for <"+c.constraint+">."); ArrayList fe = new ArrayList(red.unsolvedConstraints.size()); for(Constraint c : red.unsolvedConstraints) @@ -199,30 +201,43 @@ public class TypeChecking { @Override public void run() { Type type = value.getType(); + Expression expression = value.getExpression(); + int errorCountBeforeTypeChecking = compilationContext.errorLog.getErrorCount(); + int functionArity = expression.getSyntacticFunctionArity(); + try { ArrayList vars = new ArrayList(); type = Types.removeForAll(type, vars); ArrayList givenConstraints = new ArrayList(); type = Types.removePred(type, givenConstraints); - TypingContext context = new TypingContext(errorLog, environment); + TypingContext context = new TypingContext(compilationContext); context.pushEffectUpperBound(expression.location, Types.PROC); expression = expression.checkType(context, type); context.popEffectUpperBound(); + for(EAmbiguous overloaded : context.overloadedExpressions) + overloaded.assertResolved(compilationContext.errorLog); expression.getType().addPolarity(Polarity.POSITIVE); context.solveSubsumptions(expression.getLocation()); + + if(compilationContext.errorLog.getErrorCount() != errorCountBeforeTypeChecking) { + int typeArity = Types.getArity(type); + if(typeArity != functionArity) + compilationContext.errorLog.log(value.definitionLocation, "Possible problem: type declaration has " + typeArity + " parameter types, but function definition has " + functionArity + " parameters."); + } + ArrayList demands = context.getConstraintDemand(); if(!demands.isEmpty() || !givenConstraints.isEmpty()) { ReducedConstraints red = ConstraintSolver.solve(ce, givenConstraints, demands, true); givenConstraints.clear(); for(Constraint c : red.unsolvedConstraints) { - errorLog.log(c.getDemandLocation(), + compilationContext.errorLog.log(c.getDemandLocation(), "Constraint <"+c.constraint+"> is not given and cannot be derived."); } - if(errorLog.isEmpty()) { // To prevent exceptions + if(compilationContext.errorLog.isEmpty()) { // To prevent exceptions expression = ExpressionAugmentation.augmentSolved( red.solvedConstraints, expression); @@ -232,13 +247,13 @@ public class TypeChecking { } } else { - if(errorLog.isEmpty()) // To prevent exceptions + if(compilationContext.errorLog.isEmpty()) // To prevent exceptions expression = expression.decomposeMatching(); } expression = expression.closure(vars.toArray(new TVar[vars.size()])); value.setExpression(expression); } catch(Exception e) { - errorLog.log(expression.location, e); + compilationContext.errorLog.log(expression.location, e); } } }); @@ -329,7 +344,7 @@ public class TypeChecking { public void typeCheck() { ce = new ConstraintEnvironment(environment); - scheduler = new TypeCheckingScheduler(errorLog, environment); + scheduler = new TypeCheckingScheduler(compilationContext); typeCheckValues(); typeCheckRelations(); @@ -417,7 +432,7 @@ public class TypeChecking { for(MappingRelation mappingRelation : module.getMappingRelations()) for(Type parameterType : mappingRelation.parameterTypes) if(!parameterType.isGround()) { - errorLog.log(mappingRelation.location, "Parameter types of the mapping relation are not completely determined."); + compilationContext.errorLog.log(mappingRelation.location, "Parameter types of the mapping relation are not completely determined."); break; } }