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;
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;
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;
}
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<EVariable> constraintDemand = context.getConstraintDemand();
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<Variable> fe = new ArrayList<Variable>(red.unsolvedConstraints.size());
for(Constraint c : red.unsolvedConstraints)
@Override
public void run() {
Type type = value.getType();
+
Expression expression = value.getExpression();
+ int errorCountBeforeTypeChecking = compilationContext.errorLog.getErrorCount();
+ int functionArity = expression.getSyntacticFunctionArity();
+
try {
ArrayList<TVar> vars = new ArrayList<TVar>();
type = Types.removeForAll(type, vars);
ArrayList<TPred> givenConstraints = new ArrayList<TPred>();
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<EVariable> 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.hasNoErrors()) { // To prevent exceptions
expression = ExpressionAugmentation.augmentSolved(
red.solvedConstraints,
expression);
}
}
else {
- if(errorLog.isEmpty()) // To prevent exceptions
+ if(compilationContext.errorLog.hasNoErrors()) // 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);
}
}
});
public void typeCheck() {
ce = new ConstraintEnvironment(environment);
- scheduler = new TypeCheckingScheduler(errorLog, environment);
+ scheduler = new TypeCheckingScheduler(compilationContext);
typeCheckValues();
typeCheckRelations();
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;
}
}