]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/SSAValidationContext.java
Replace System.err and System.out with SLF4J Logging
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / codegen / utils / SSAValidationContext.java
1 package org.simantics.scl.compiler.internal.codegen.utils;
2
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;
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
17
18 import gnu.trove.map.hash.TObjectIntHashMap;
19 import gnu.trove.procedure.TObjectIntProcedure;
20 import gnu.trove.set.hash.THashSet;
21
22 public class SSAValidationContext {
23
24     private static final Logger LOGGER = LoggerFactory.getLogger(SSAValidationContext.class);
25
26     public THashSet<BoundVar> validBoundVariables = new THashSet<BoundVar>();
27     public THashSet<Cont> validContinuations = new THashSet<Cont>();
28     public THashSet<TVar> validTypeVariables = new THashSet<TVar>();
29     public TObjectIntHashMap<Val> refCount = new TObjectIntHashMap<Val>(); 
30     public Object errorMarker = null;
31     
32     public void assertEquals(Object loc, Type a, Type b) {
33         if(!Types.equals(a, b)) {
34             TypeUnparsingContext tuc = new TypeUnparsingContext();
35             String message = a.toString(tuc) + " != " + b.toString(tuc);
36             LOGGER.error(message);
37             setErrorMarker(loc);
38             throw new InternalCompilerError(message);
39         }
40     }
41     
42     public void assertSubsumes(Object loc, Type a, Type b) {
43         if(!Types.subsumes(a, b)) {
44             TypeUnparsingContext tuc = new TypeUnparsingContext();
45             /*System.err.println(a.toString(tuc) + " <! " + b.toString(tuc));*/
46             setErrorMarker(loc);
47             throw new InternalCompilerError(a.toString(tuc) + " <! " + b.toString(tuc));
48         }
49     }
50
51     public void assertEqualsEffect(Object loc, Type a, Type b) {
52         if(!Types.equalsEffect(a, b)) {
53             TypeUnparsingContext tuc = new TypeUnparsingContext();
54             String message = a.toString(tuc) + " != " + b.toString(tuc);
55             LOGGER.error(message);
56             setErrorMarker(loc);
57             throw new InternalCompilerError(message);
58         }
59     }
60     
61     public void assertEquals(int a, int b) {
62         if(a != b)
63             throw new InternalCompilerError();
64     }
65
66     public void reset() {
67         validContinuations.clear();
68         validTypeVariables.clear();
69     }
70
71     public void validate(Cont cont) {
72         for(int i=0;i<cont.getArity();++i)
73             validateType(cont.getParameterType(i));
74     }
75     
76     public void validate(Val val) {
77         validateType(val.getType());
78     }
79     
80     private static boolean hasOccurrence(Cont cont, ContRef occ) {
81         for(ContRef ref = cont.getOccurrence(); 
82                 ref != null; 
83                 ref = ref.getNext())
84             if(ref == occ)
85                 return true;
86         return false;
87     }
88     
89     public void validate(ContRef ref) {
90         if(!validContinuations.contains(ref.getBinding()))
91             throw new InternalCompilerError();
92         if(!hasOccurrence(ref.getBinding(), ref))
93             throw new InternalCompilerError();
94         if(ref.getParent() == null)
95             throw new InternalCompilerError();
96     }
97     
98     boolean invalidReferenceCounts;
99     
100     public void checkReferences() {
101         invalidReferenceCounts = false;
102         refCount.forEachEntry(new TObjectIntProcedure<Val>() {            
103             @Override
104             public boolean execute(Val val, int count) {
105                 if(val instanceof Constant) {
106                     if(!(val instanceof SCLConstant))
107                         return true;
108                     if(!((SCLConstant)val).getName().module.equals("Composition"))
109                         return true;
110                 }
111                 
112                 int realCount = val.occurrenceCount();
113                 if(realCount != count) {
114                     LOGGER.warn(val + ": " + realCount + " != " + count);
115                     invalidReferenceCounts = true;
116                 }
117                 return true;
118             }
119         });
120         if(invalidReferenceCounts)
121             throw new InternalCompilerError();
122     }
123     
124     public void validate(ValRef ref) {
125         refCount.adjustOrPutValue(ref.getBinding(), 1, 1);
126         
127         Val val = ref.getBinding();
128         if(val == null)
129             throw new InternalCompilerError();
130         if(val instanceof Constant)
131             return;
132         if(!validBoundVariables.contains(val))
133             throw new InternalCompilerError();
134         
135         if(ref.getParent() == null)
136             throw new InternalCompilerError();
137     }
138
139     public void validateType(Type type) {
140         // PROBLEM: code involving existential data types do not pass this test
141         /*for(TVar var : Types.freeVars(type))
142             if(!validTypeVariables.contains(var))
143                 throw new InternalCompilerError();*/
144     }
145     
146     public void setErrorMarker(Object errorMarker) {
147         this.errorMarker = errorMarker;
148     }
149     
150 }