]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRLiteral.java
e7b3320d77758d87b023904aa880f980a99f8ec5
[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(parameters != null) {
51             for(int i=0;i<parameters.length;++i)
52                 parameters[i] = parameters[i].resolve(context);
53         }
54         if(relation instanceof UnresolvedCHRRelation) {
55             UnresolvedCHRRelation unresolved = (UnresolvedCHRRelation)relation;
56             CHRConstraint constraint = context.resolveCHRConstraint(unresolved.name);
57             if(constraint != null) {
58                 relation = constraint;
59                 passive = false;
60             }
61             else {
62                 SCLRelation sclRelation = context.resolveRelation(unresolved.location, unresolved.name);
63                 if(sclRelation != null)
64                     relation = new ExternalCHRRelation(sclRelation);
65                 else {
66                     if(unresolved.name.contains(".")) {
67                         context.getErrorLog().log(unresolved.location, "Couldn't resolve relation " + unresolved.name + ".");
68                         return;
69                     }   
70                     if(parameters == null) {
71                         context.getErrorLog().log(location, "Relation must be declared if record syntax is used.");
72                         return;
73                     }
74                     Type[] parameterTypes = new Type[parameters.length];
75                     for(int i=0;i<parameterTypes.length;++i)
76                         parameterTypes[i] = Types.metaVar(Kinds.STAR);
77                     constraint = new CHRConstraint(location, unresolved.name, parameterTypes);
78                     constraint.implicitlyDeclared = true;
79                     context.newCHRConstraint(constraint.name, constraint);
80                     relation = constraint;
81                     passive = false;
82                     //context.getErrorLog().log(unresolved.location, "Couldn't resolve constraint " + unresolved.name + ".");
83                 }
84             }
85         }
86         if(parameters == null && fields != null) {
87             String[] fieldNames = relation.getFieldNames();
88             if(fieldNames == null) {
89                 context.getErrorLog().log(location, "Relation " + relation + " does not define field names.");
90                 return;
91             }
92             parameters = ERecord.translateFieldsToFunctionParameters(context, fields, fieldNames);
93             if(parameters == null)
94                 return;
95             for(int i=0;i<parameters.length;++i) {
96                 Expression parameter = parameters[i];
97                 if(parameter == null) {
98                     ExistentialFrame frame = context.getCurrentExistentialFrame();
99                     if(frame == null || frame.disallowNewExistentials)
100                         context.getErrorLog().log(location, "Field " + fieldNames[i] + " not defined.");
101                     else
102                         parameters[i] = frame.createBlank(location);
103                 }
104                 else
105                     parameters[i] = parameters[i].resolve(context);
106             }
107             fields = null;
108         }
109     }
110
111     public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
112         for(Expression parameter : parameters)
113             parameter.collectRefs(allRefs, refs);
114         if(typeConstraintEvidenceParameters != null)
115             for(Expression parameter : typeConstraintEvidenceParameters)
116                 parameter.collectRefs(allRefs, refs);
117     }
118
119     public void checkType(TypingContext context) {
120         if(relation == SpecialCHRRelation.EXECUTE) {
121             if(parameters.length != 1)
122                 throw new InternalCompilerError("Wrong number of parameters for EXECUTE constraint.");
123             parameters[0] = parameters[0].checkIgnoredType(context);
124             typeConstraintEvidenceParameters = Expression.EMPTY_ARRAY;
125         }
126         else {
127             TVar[] typeVariables = relation.getTypeVariables();
128             typeParameters = typeVariables.length == 0 ? Type.EMPTY_ARRAY : new Type[typeVariables.length];
129             for(int i=0;i<typeVariables.length;++i)
130                 typeParameters[i] = Types.metaVar(typeVariables[i].getKind());
131             Type[] parameterTypes = Types.replace(relation.getParameterTypes(), typeVariables, typeParameters);
132             if(parameterTypes.length != parameters.length)
133                 context.getErrorLog().log(location, "Constraint is applied with wrong number of parameters");
134             else
135                 for(int i=0;i<parameters.length;++i)
136                     parameters[i] = parameters[i].checkType(context, parameterTypes[i]);
137             
138             typeConstraintEvidenceParameters = context.addConstraints(Types.replace(relation.getTypeConstraints(), typeVariables, typeParameters));
139         }
140     }
141
142     public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {
143         for(Expression parameter : parameters)
144             parameter.collectVars(allVars, vars);
145         if(typeConstraintEvidenceParameters != null)
146             for(Expression parameter : typeConstraintEvidenceParameters)
147                 parameter.collectVars(allVars, vars);
148     }
149
150     public void forVariables(VariableProcedure procedure) {
151         for(Expression parameter : parameters)
152             parameter.forVariables(procedure);
153         if(typeConstraintEvidenceParameters != null)
154             for(Expression parameter : typeConstraintEvidenceParameters)
155                 parameter.forVariables(procedure);
156     }
157
158     public void collectFreeVariables(THashSet<Variable> vars) {
159         for(Expression parameter : parameters)
160             parameter.collectFreeVariables(vars);
161         if(typeConstraintEvidenceParameters != null)
162             for(Expression parameter : typeConstraintEvidenceParameters)
163                 parameter.collectFreeVariables(vars);
164     }
165
166     public void setLocationDeep(long loc) {
167         if(location == Locations.NO_LOCATION) {
168             this.location = loc;
169             for(Expression parameter : parameters)
170                 parameter.setLocationDeep(loc);
171         }
172     }
173     
174     public void simplify(SimplificationContext context) {
175         for(int i=0;i<parameters.length;++i)
176             parameters[i] = parameters[i].simplify(context);
177         if(typeConstraintEvidenceParameters != null)
178             for(int i=0;i<typeConstraintEvidenceParameters.length;++i)
179                 typeConstraintEvidenceParameters[i] = typeConstraintEvidenceParameters[i].simplify(context);
180     }
181     
182     public String toString() {
183         StringBuilder b = new StringBuilder();
184         ExpressionToStringVisitor visitor = new ExpressionToStringVisitor(b);
185         visitor.visit(this);
186         return b.toString();
187     }
188
189     public void collectQueryEffects(THashSet<Type> effects) {
190         // TODO
191     }
192
193     public void collectEnforceEffects(THashSet<Type> effects) {
194         // TODO
195     }
196 }