X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Fcompilation%2FTypeCheckingOld.java;fp=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Fcompilation%2FTypeCheckingOld.java;h=c5ef57384459d46a7353607600b1fb2adfad7faa;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeCheckingOld.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeCheckingOld.java new file mode 100644 index 000000000..c5ef57384 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeCheckingOld.java @@ -0,0 +1,349 @@ +package org.simantics.scl.compiler.compilation; + +import static org.simantics.scl.compiler.elaboration.expressions.Expressions.apply; +import static org.simantics.scl.compiler.elaboration.expressions.Expressions.applyTypes; +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 org.simantics.scl.compiler.elaboration.contexts.TypingContext; +import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder; +import org.simantics.scl.compiler.elaboration.expressions.EVariable; +import org.simantics.scl.compiler.elaboration.expressions.Expression; +import org.simantics.scl.compiler.elaboration.expressions.Variable; +import org.simantics.scl.compiler.elaboration.modules.SCLValue; +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.errors.Locations; +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.internal.elaboration.constraints.ExpressionAugmentation; +import org.simantics.scl.compiler.internal.elaboration.constraints.ReducedConstraints; +import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents; +import org.simantics.scl.compiler.module.ConcreteModule; +import org.simantics.scl.compiler.types.TPred; +import org.simantics.scl.compiler.types.TVar; +import org.simantics.scl.compiler.types.Type; +import org.simantics.scl.compiler.types.Types; +import org.simantics.scl.compiler.types.kinds.Kinds; +import org.simantics.scl.compiler.types.util.Polarity; + +public class TypeCheckingOld { + public static final boolean PRINT_VALUES = false; + + ErrorLog errorLog; + Environment environment; + ConcreteModule module; + + ConstraintEnvironment ce; + ArrayList valuesWithoutTypeAnnotation = new ArrayList(); + ArrayList valuesWithTypeAnnotation = new ArrayList(); + + public TypeCheckingOld(ErrorLog errorLog, Environment environment, + ConcreteModule module) { + this.errorLog = errorLog; + this.environment = environment; + this.module = module; + } + + public void typeCheck() { + ce = new ConstraintEnvironment(environment); + groupValueDefinitionsByDependency(); + typeCheckValuesWithoutTypeAnnotations(); + typeCheckValuesWithTypeAnnotations(); + typeCheckRules(); + } + + private void groupValueDefinitionsByDependency() { + // Collect all untyped names + final ArrayList values = new ArrayList(); + for(SCLValue value : module.getValues()) { + if(value.getExpression() != null) { + if(value.getType() == null) + values.add(value); + else + valuesWithTypeAnnotation.add(value); + } + } + + // Create inverse + final TObjectIntHashMap allRefs = + new TObjectIntHashMap(values.size()*2, 0.5f, -1); + for(int i=0;i(); + for(SCLValue value : group) + context.recursiveValues.add(value); + + @SuppressWarnings("unchecked") + ArrayList[] constraintDemands = new ArrayList[group.length]; + + @SuppressWarnings("unchecked") + ArrayList[] recursiveReferences = new ArrayList[group.length]; + for(int i=0;i(); + + SCLValue value = group[i]; + Expression expression = value.getExpression(); + expression = expression.checkType(context, value.getType()); + value.setExpression(expression); + + ArrayList constraintDemand = context.getConstraintDemand(); + if(!constraintDemand.isEmpty()) { + constraintDemands[i] = constraintDemand; + context.resetConstraintDemand(); + } + + recursiveReferences[i] = context.recursiveReferences; + } + + for(Type type : Types.getTypes(group)) + type.addPolarity(Polarity.POSITIVE); + context.solveSubsumptions(group[0].getExpression().getLocation()); + ArrayList allUnsolvedConstraints = new ArrayList(); + + @SuppressWarnings("unchecked") + ArrayList[] freeEvidence = new ArrayList[group.length]; + for(int i=0;i(0), constraintDemands[i], + true /*!Types.isFunction(expression.getType())*/); + + expression = ExpressionAugmentation.augmentSolved( + red.solvedConstraints, + expression); + value.setExpression(expression); + value.setType(expression.getType()); + + for(Constraint c : red.unsolvedConstraints) + if(c.constraint.isGround()) { + errorLog.log(c.getDemandLocation(), "There is no instance for <"+c.constraint+">."); + } + + ArrayList fe = new ArrayList(red.unsolvedConstraints.size()); + for(Constraint c : red.unsolvedConstraints) { + allUnsolvedConstraints.add(c); + fe.add(c.evidence); + } + freeEvidence[i] = fe; + } + else { + group[i].setExpression(group[i].getExpression().decomposeMatching()); + freeEvidence[i] = new ArrayList(0); + } + } + + THashSet varSet = new THashSet(); + for(int i=0;i constraintSet = new THashSet(); + for(int i=0;i fe = freeEvidence[i]; + THashMap indexedEvidence = new THashMap(fe.size()); + for(Variable v : fe) + indexedEvidence.put((TPred)v.getType(), v); + fe.clear(); + for(TPred c : constraints) { + Variable var = indexedEvidence.get(c); + if(var == null) { + // These are variables that are not directly needed in + // this definition but in the definitions that are + // recursively called + var = new Variable("evX"); + var.setType(c); + fe.add(var); + } + fe.add(var); + } + + // Add evidence parameters to the functions + SCLValue value = group[i]; + value.setExpression(lambda(Types.NO_EFFECTS, fe, value.getExpression()) + .closure(vars)); + value.setType(Types.forAll(vars, + Types.constrained(constraints, value.getType()))); + + // Add evidence parameters to recursive calls + for(EPlaceholder ref : recursiveReferences[i]) { + ref.expression = loc(ref.expression.location, apply( + Types.NO_EFFECTS, + applyTypes(ref.expression, vars), + vars(fe))); + } + } + } + } + + private void typeCheckValuesWithTypeAnnotations() { + ArrayList givenConstraints = new ArrayList(); + for(SCLValue value : valuesWithTypeAnnotation) { + Type type = value.getType(); + if(type != null) { + if(PRINT_VALUES) { + System.out.println("---------------------------------------------"); + System.out.println("--- " + value.getName() + " :: " + type); + } + Expression expression = value.getExpression(); + ArrayList vars = new ArrayList(); + type = Types.removeForAll(type, vars); + type = Types.removePred(type, givenConstraints); + + /*System.out.println("---------------------------------------------"); + TypeUnparsingContext tuc = new TypeUnparsingContext(); + System.out.println("--- " + value.getName() + " :: " + type.toString(tuc)); + for(TPred t : givenConstraints) + System.out.println(">>> " + t.toString(tuc)); + */ + TypingContext context = new TypingContext(errorLog, environment); + //System.out.println(expression); + expression = expression.checkType(context, type); + //System.out.println(expression); + expression.getType().addPolarity(Polarity.POSITIVE); + context.solveSubsumptions(expression.getLocation()); + 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(), + "Constraint <"+c.constraint+"> is not given and cannot be derived."); + } + if(errorLog.isEmpty()) { // To prevent exceptions + expression = ExpressionAugmentation.augmentSolved( + red.solvedConstraints, + expression); + expression = ExpressionAugmentation.augmentUnsolved( + red.givenConstraints, + expression); + } + } + else { + if(errorLog.isEmpty()) // To prevent exceptions + expression = expression.decomposeMatching(); + } + expression = expression.closure(vars.toArray(new TVar[vars.size()])); + value.setExpression(expression); + } + } + } + + public void typeCheckRules() { + TypingContext context = new TypingContext(errorLog, environment); + for(TransformationRule rule : module.getRules()) { + context.pushEffectUpperBound(rule.location, Types.metaVar(Kinds.EFFECT)); + rule.checkType(context); + rule.setEffect(Types.canonical(context.popEffectUpperBound())); + } + context.solveSubsumptions(Locations.NO_LOCATION); + + ArrayList demands = context.getConstraintDemand(); + if(!demands.isEmpty()) { + ReducedConstraints red = + ConstraintSolver.solve(ce, new ArrayList(), demands, true); + for(Constraint c : red.unsolvedConstraints) { + errorLog.log(c.getDemandLocation(), + "Constraint <"+c.constraint+"> is not given and cannot be derived."); + } + } + + 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."); + break; + } + + /*for(Rule rule : module.getRules()) { + System.out.println(rule.name); + for(Variable variable : rule.variables) + System.out.println(" " + variable.getName() + " :: " + variable.getType()); + }*/ + } +}