package org.simantics.scl.compiler.internal.codegen.utils; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.constants.Constant; import org.simantics.scl.compiler.constants.SCLConstant; import org.simantics.scl.compiler.internal.codegen.continuations.Cont; import org.simantics.scl.compiler.internal.codegen.continuations.ContRef; import org.simantics.scl.compiler.internal.codegen.references.BoundVar; import org.simantics.scl.compiler.internal.codegen.references.Val; import org.simantics.scl.compiler.internal.codegen.references.ValRef; 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.util.TypeUnparsingContext; import gnu.trove.map.hash.TObjectIntHashMap; import gnu.trove.procedure.TObjectIntProcedure; import gnu.trove.set.hash.THashSet; public class SSAValidationContext { public THashSet validBoundVariables = new THashSet(); public THashSet validContinuations = new THashSet(); public THashSet validTypeVariables = new THashSet(); public TObjectIntHashMap refCount = new TObjectIntHashMap(); public Object errorMarker = null; public void assertEquals(Object loc, Type a, Type b) { if(!Types.equals(a, b)) { TypeUnparsingContext tuc = new TypeUnparsingContext(); System.err.println(a.toString(tuc) + " != " + b.toString(tuc)); setErrorMarker(loc); throw new InternalCompilerError(); } } public void assertSubsumes(Object loc, Type a, Type b) { if(!Types.subsumes(a, b)) { TypeUnparsingContext tuc = new TypeUnparsingContext(); /*System.err.println(a.toString(tuc) + " () { @Override public boolean execute(Val val, int count) { if(val instanceof Constant) { if(!(val instanceof SCLConstant)) return true; if(!((SCLConstant)val).getName().module.equals("Composition")) return true; } int realCount = val.occurrenceCount(); if(realCount != count) { System.out.println(val + ": " + realCount + " != " + count); invalidReferenceCounts = true; } return true; } }); if(invalidReferenceCounts) throw new InternalCompilerError(); } public void validate(ValRef ref) { refCount.adjustOrPutValue(ref.getBinding(), 1, 1); Val val = ref.getBinding(); if(val == null) throw new InternalCompilerError(); if(val instanceof Constant) return; if(!validBoundVariables.contains(val)) throw new InternalCompilerError(); if(ref.getParent() == null) throw new InternalCompilerError(); } public void validateType(Type type) { // PROBLEM: code involving existential data types do not pass this test /*for(TVar var : Types.freeVars(type)) if(!validTypeVariables.contains(var)) throw new InternalCompilerError();*/ } public void setErrorMarker(Object errorMarker) { this.errorMarker = errorMarker; } }