1 package org.simantics.scl.compiler.internal.codegen.utils;
3 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
4 import org.simantics.scl.compiler.constants.Constant;
5 import org.simantics.scl.compiler.constants.SCLConstant;
6 import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
7 import org.simantics.scl.compiler.internal.codegen.continuations.ContRef;
8 import org.simantics.scl.compiler.internal.codegen.references.BoundVar;
9 import org.simantics.scl.compiler.internal.codegen.references.Val;
10 import org.simantics.scl.compiler.internal.codegen.references.ValRef;
11 import org.simantics.scl.compiler.types.TVar;
12 import org.simantics.scl.compiler.types.Type;
13 import org.simantics.scl.compiler.types.Types;
14 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
16 import gnu.trove.map.hash.TObjectIntHashMap;
17 import gnu.trove.procedure.TObjectIntProcedure;
18 import gnu.trove.set.hash.THashSet;
20 public class SSAValidationContext {
22 public THashSet<BoundVar> validBoundVariables = new THashSet<BoundVar>();
23 public THashSet<Cont> validContinuations = new THashSet<Cont>();
24 public THashSet<TVar> validTypeVariables = new THashSet<TVar>();
25 public TObjectIntHashMap<Val> refCount = new TObjectIntHashMap<Val>();
26 public Object errorMarker = null;
28 public void assertEquals(Object loc, Type a, Type b) {
29 if(!Types.equals(a, b)) {
30 TypeUnparsingContext tuc = new TypeUnparsingContext();
31 System.err.println(a.toString(tuc) + " != " + b.toString(tuc));
33 throw new InternalCompilerError();
37 public void assertSubsumes(Object loc, Type a, Type b) {
38 if(!Types.subsumes(a, b)) {
39 TypeUnparsingContext tuc = new TypeUnparsingContext();
40 /*System.err.println(a.toString(tuc) + " <! " + b.toString(tuc));*/
42 throw new InternalCompilerError(a.toString(tuc) + " <! " + b.toString(tuc));
46 public void assertEqualsEffect(Object loc, Type a, Type b) {
47 if(!Types.equalsEffect(a, b)) {
48 TypeUnparsingContext tuc = new TypeUnparsingContext();
49 System.err.println(a.toString(tuc) + " != " + b.toString(tuc));
51 throw new InternalCompilerError();
55 public void assertEquals(int a, int b) {
57 throw new InternalCompilerError();
61 validContinuations.clear();
62 validTypeVariables.clear();
65 public void validate(Cont cont) {
66 for(int i=0;i<cont.getArity();++i)
67 validateType(cont.getParameterType(i));
70 public void validate(Val val) {
71 validateType(val.getType());
74 private static boolean hasOccurrence(Cont cont, ContRef occ) {
75 for(ContRef ref = cont.getOccurrence();
83 public void validate(ContRef ref) {
84 if(!validContinuations.contains(ref.getBinding()))
85 throw new InternalCompilerError();
86 if(!hasOccurrence(ref.getBinding(), ref))
87 throw new InternalCompilerError();
88 if(ref.getParent() == null)
89 throw new InternalCompilerError();
92 boolean invalidReferenceCounts;
94 public void checkReferences() {
95 invalidReferenceCounts = false;
96 refCount.forEachEntry(new TObjectIntProcedure<Val>() {
98 public boolean execute(Val val, int count) {
99 if(val instanceof Constant) {
100 if(!(val instanceof SCLConstant))
102 if(!((SCLConstant)val).getName().module.equals("Composition"))
106 int realCount = val.occurrenceCount();
107 if(realCount != count) {
108 System.out.println(val + ": " + realCount + " != " + count);
109 invalidReferenceCounts = true;
114 if(invalidReferenceCounts)
115 throw new InternalCompilerError();
118 public void validate(ValRef ref) {
119 refCount.adjustOrPutValue(ref.getBinding(), 1, 1);
121 Val val = ref.getBinding();
123 throw new InternalCompilerError();
124 if(val instanceof Constant)
126 if(!validBoundVariables.contains(val))
127 throw new InternalCompilerError();
129 if(ref.getParent() == null)
130 throw new InternalCompilerError();
133 public void validateType(Type type) {
134 // PROBLEM: code involving existential data types do not pass this test
135 /*for(TVar var : Types.freeVars(type))
136 if(!validTypeVariables.contains(var))
137 throw new InternalCompilerError();*/
140 public void setErrorMarker(Object errorMarker) {
141 this.errorMarker = errorMarker;