]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRLiteral.java
Merge "Resolve some dependency problems with SDK features"
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / chr / CHRLiteral.java
1 package org.simantics.scl.compiler.elaboration.chr;
2
3 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
4 import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
5 import org.simantics.scl.compiler.elaboration.chr.relations.ExternalCHRRelation;
6 import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation;
7 import org.simantics.scl.compiler.elaboration.chr.relations.UnresolvedCHRRelation;
8 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
9 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
10 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext.ExistentialFrame;
11 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
12 import org.simantics.scl.compiler.elaboration.expressions.ERecord;
13 import org.simantics.scl.compiler.elaboration.expressions.Expression;
14 import org.simantics.scl.compiler.elaboration.expressions.Variable;
15 import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
16 import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;
17 import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment;
18 import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
19 import org.simantics.scl.compiler.errors.Locations;
20 import org.simantics.scl.compiler.internal.parsing.Symbol;
21 import org.simantics.scl.compiler.types.TVar;
22 import org.simantics.scl.compiler.types.Type;
23 import org.simantics.scl.compiler.types.Types;
24 import org.simantics.scl.compiler.types.kinds.Kinds;
25
26 import gnu.trove.map.hash.TObjectIntHashMap;
27 import gnu.trove.set.hash.THashSet;
28 import gnu.trove.set.hash.TIntHashSet;
29
30 public class CHRLiteral extends Symbol {
31     
32     public CHRRelation relation;
33     public Type[] typeParameters;
34     public Expression[] parameters;
35     public FieldAssignment[] fields; // optional
36     public Expression[] typeConstraintEvidenceParameters;
37     public boolean killAfterMatch;
38     public boolean negated;
39     public boolean passive = true;
40     
41     public CHRLiteral(long location, CHRRelation relation, Expression[] parameters, boolean remove, boolean negated) {
42         this.location = location;
43         this.relation = relation;
44         this.parameters = parameters;
45         this.killAfterMatch = remove;
46         this.negated = negated;
47     }
48
49     public void resolve(TranslationContext context) {
50         if(relation instanceof UnresolvedCHRRelation) {
51             UnresolvedCHRRelation unresolved = (UnresolvedCHRRelation)relation;
52             CHRConstraint constraint = context.resolveCHRConstraint(unresolved.name);
53             if(constraint != null) {
54                 relation = constraint;
55                 passive = false;
56             }
57             else {
58                 SCLRelation sclRelation = context.resolveRelation(unresolved.location, unresolved.name);
59                 if(sclRelation != null)
60                     relation = new ExternalCHRRelation(sclRelation);
61                 else {
62                     if(parameters == null) {
63                         context.getErrorLog().log(location, "Relation must be declared if record syntax is used.");
64                         return;
65                     }
66                     Type[] parameterTypes = new Type[parameters.length];
67                     for(int i=0;i<parameterTypes.length;++i)
68                         parameterTypes[i] = Types.metaVar(Kinds.STAR);
69                     constraint = new CHRConstraint(location, unresolved.name, parameterTypes);
70                     constraint.implicitlyDeclared = true;
71                     context.newCHRConstraint(constraint.name, constraint);
72                     relation = constraint;
73                     passive = false;
74                     //context.getErrorLog().log(unresolved.location, "Couldn't resolve constraint " + unresolved.name + ".");
75                 }
76             }
77         }
78         if(parameters == null && fields != null) {
79             String[] fieldNames = relation.getFieldNames();
80             if(fieldNames == null) {
81                 context.getErrorLog().log(location, "Relation " + relation + " does not define field names.");
82                 return;
83             }
84             parameters = ERecord.translateFieldsToFunctionParameters(context, fields, fieldNames);
85             if(parameters == null)
86                 return;
87             for(int i=0;i<parameters.length;++i) {
88                 Expression parameter = parameters[i];
89                 if(parameter == null) {
90                     ExistentialFrame frame = context.getCurrentExistentialFrame();
91                     if(frame == null || frame.disallowNewExistentials)
92                         context.getErrorLog().log(location, "Field " + fieldNames[i] + " not defined.");
93                     else
94                         parameters[i] = frame.createBlank(location);
95                 }
96                 else
97                     parameters[i] = parameters[i].resolve(context);
98             }
99             fields = null;
100         }
101         else {
102             for(int i=0;i<parameters.length;++i)
103                 parameters[i] = parameters[i].resolve(context);
104         }
105     }
106
107     public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
108         for(Expression parameter : parameters)
109             parameter.collectRefs(allRefs, refs);
110         if(typeConstraintEvidenceParameters != null)
111             for(Expression parameter : typeConstraintEvidenceParameters)
112                 parameter.collectRefs(allRefs, refs);
113     }
114
115     public void checkType(TypingContext context) {
116         if(relation == SpecialCHRRelation.EXECUTE) {
117             if(parameters.length != 1)
118                 throw new InternalCompilerError("Wrong number of parameters for EXECUTE constraint.");
119             parameters[0] = parameters[0].checkIgnoredType(context);
120             typeConstraintEvidenceParameters = Expression.EMPTY_ARRAY;
121         }
122         else {
123             TVar[] typeVariables = relation.getTypeVariables();
124             typeParameters = typeVariables.length == 0 ? Type.EMPTY_ARRAY : new Type[typeVariables.length];
125             for(int i=0;i<typeVariables.length;++i)
126                 typeParameters[i] = Types.metaVar(typeVariables[i].getKind());
127             Type[] parameterTypes = Types.replace(relation.getParameterTypes(), typeVariables, typeParameters);
128             if(parameterTypes.length != parameters.length)
129                 context.getErrorLog().log(location, "Constraint is applied with wrong number of parameters");
130             else
131                 for(int i=0;i<parameters.length;++i)
132                     parameters[i] = parameters[i].checkType(context, parameterTypes[i]);
133             
134             typeConstraintEvidenceParameters = context.addConstraints(Types.replace(relation.getTypeConstraints(), typeVariables, typeParameters));
135         }
136     }
137
138     public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {
139         for(Expression parameter : parameters)
140             parameter.collectVars(allVars, vars);
141         if(typeConstraintEvidenceParameters != null)
142             for(Expression parameter : typeConstraintEvidenceParameters)
143                 parameter.collectVars(allVars, vars);
144     }
145
146     public void forVariables(VariableProcedure procedure) {
147         for(Expression parameter : parameters)
148             parameter.forVariables(procedure);
149         if(typeConstraintEvidenceParameters != null)
150             for(Expression parameter : typeConstraintEvidenceParameters)
151                 parameter.forVariables(procedure);
152     }
153
154     public void collectFreeVariables(THashSet<Variable> vars) {
155         for(Expression parameter : parameters)
156             parameter.collectFreeVariables(vars);
157         if(typeConstraintEvidenceParameters != null)
158             for(Expression parameter : typeConstraintEvidenceParameters)
159                 parameter.collectFreeVariables(vars);
160     }
161
162     public void setLocationDeep(long loc) {
163         if(location == Locations.NO_LOCATION) {
164             this.location = loc;
165             for(Expression parameter : parameters)
166                 parameter.setLocationDeep(loc);
167         }
168     }
169     
170     public void simplify(SimplificationContext context) {
171         for(int i=0;i<parameters.length;++i)
172             parameters[i] = parameters[i].simplify(context);
173         if(typeConstraintEvidenceParameters != null)
174             for(int i=0;i<typeConstraintEvidenceParameters.length;++i)
175                 typeConstraintEvidenceParameters[i] = typeConstraintEvidenceParameters[i].simplify(context);
176     }
177     
178     public String toString() {
179         StringBuilder b = new StringBuilder();
180         ExpressionToStringVisitor visitor = new ExpressionToStringVisitor(b);
181         visitor.visit(this);
182         return b.toString();
183     }
184
185     public void collectQueryEffects(THashSet<Type> effects) {
186     }
187
188     public void collectEnforceEffects(THashSet<Type> effects) {
189     }
190 }