import org.simantics.scl.compiler.elaboration.chr.relations.ExternalCHRRelation;
import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation;
import org.simantics.scl.compiler.elaboration.chr.relations.UnresolvedCHRRelation;
+import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext.ExistentialFrame;
import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
+import org.simantics.scl.compiler.elaboration.expressions.ERecord;
import org.simantics.scl.compiler.elaboration.expressions.Expression;
import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment;
import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
import org.simantics.scl.compiler.errors.Locations;
import org.simantics.scl.compiler.internal.parsing.Symbol;
import org.simantics.scl.compiler.types.kinds.Kinds;
import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
import gnu.trove.set.hash.TIntHashSet;
public class CHRLiteral extends Symbol {
public CHRRelation relation;
public Type[] typeParameters;
public Expression[] parameters;
+ public FieldAssignment[] fields; // optional
+ public Expression[] typeConstraintEvidenceParameters;
public boolean killAfterMatch;
public boolean negated;
public boolean passive = true;
- public CHRLiteral(long location, CHRRelation relation, Expression[] parameters, boolean remove, boolean negated) {
+ public CHRLiteral(long location, CHRRelation relation, Expression[] parameters, boolean killAfterMatch, boolean negated) {
this.location = location;
this.relation = relation;
this.parameters = parameters;
- this.killAfterMatch = remove;
+ this.killAfterMatch = killAfterMatch;
this.negated = negated;
}
public void resolve(TranslationContext context) {
+ if(relation == SpecialCHRRelation.ASSIGN) {
+ parameters[1] = parameters[1].resolve(context);
+ parameters[0] = parameters[0].resolveAsPattern(context);
+ return;
+ }
+ if(parameters != null) {
+ for(int i=0;i<parameters.length;++i)
+ parameters[i] = parameters[i].resolve(context);
+ }
if(relation instanceof UnresolvedCHRRelation) {
UnresolvedCHRRelation unresolved = (UnresolvedCHRRelation)relation;
CHRConstraint constraint = context.resolveCHRConstraint(unresolved.name);
if(sclRelation != null)
relation = new ExternalCHRRelation(sclRelation);
else {
+ if(unresolved.name.contains(".")) {
+ context.getErrorLog().log(unresolved.location, "Couldn't resolve relation " + unresolved.name + ".");
+ return;
+ }
+ if(parameters == null) {
+ context.getErrorLog().log(location, "Relation must be declared if record syntax is used.");
+ return;
+ }
Type[] parameterTypes = new Type[parameters.length];
for(int i=0;i<parameterTypes.length;++i)
parameterTypes[i] = Types.metaVar(Kinds.STAR);
}
}
}
- for(int i=0;i<parameters.length;++i)
- parameters[i] = parameters[i].resolve(context);
- }
-
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- for(Expression parameter : parameters)
- parameter.collectRefs(allRefs, refs);
+ if(parameters == null && fields != null) {
+ String[] fieldNames = relation.getFieldNames();
+ if(fieldNames == null) {
+ context.getErrorLog().log(location, "Relation " + relation + " does not define field names.");
+ return;
+ }
+ parameters = ERecord.translateFieldsToFunctionParameters(context, fields, fieldNames, true);
+ if(parameters == null)
+ return;
+ for(int i=0;i<parameters.length;++i) {
+ Expression parameter = parameters[i];
+ if(parameter == null) {
+ ExistentialFrame frame = context.getCurrentExistentialFrame();
+ if(frame == null || frame.disallowNewExistentials)
+ context.getErrorLog().log(location, "Field " + fieldNames[i] + " not defined.");
+ else
+ parameters[i] = frame.createBlank(location);
+ }
+ else
+ parameters[i] = parameters[i].resolve(context);
+ }
+ fields = null;
+ }
}
public void checkType(TypingContext context) {
if(parameters.length != 1)
throw new InternalCompilerError("Wrong number of parameters for EXECUTE constraint.");
parameters[0] = parameters[0].checkIgnoredType(context);
+ typeConstraintEvidenceParameters = Expression.EMPTY_ARRAY;
+ }
+ else if(relation == SpecialCHRRelation.ASSIGN) {
+ parameters[1] = parameters[1].inferType(context);
+ parameters[0] = parameters[0].checkTypeAsPattern(context, parameters[1].getType());
+ typeConstraintEvidenceParameters = Expression.EMPTY_ARRAY;
}
else {
TVar[] typeVariables = relation.getTypeVariables();
else
for(int i=0;i<parameters.length;++i)
parameters[i] = parameters[i].checkType(context, parameterTypes[i]);
+
+ typeConstraintEvidenceParameters = context.addConstraints(Types.replace(relation.getTypeConstraints(), typeVariables, typeParameters));
}
}
public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {
for(Expression parameter : parameters)
parameter.collectVars(allVars, vars);
- }
-
- public void forVariables(VariableProcedure procedure) {
- for(Expression parameter : parameters)
- parameter.forVariables(procedure);
- }
-
- public void collectFreeVariables(THashSet<Variable> vars) {
- for(Expression parameter : parameters)
- parameter.collectFreeVariables(vars);
+ if(typeConstraintEvidenceParameters != null)
+ for(Expression parameter : typeConstraintEvidenceParameters)
+ parameter.collectVars(allVars, vars);
}
public void setLocationDeep(long loc) {
public void simplify(SimplificationContext context) {
for(int i=0;i<parameters.length;++i)
parameters[i] = parameters[i].simplify(context);
+ if(typeConstraintEvidenceParameters != null)
+ for(int i=0;i<typeConstraintEvidenceParameters.length;++i)
+ typeConstraintEvidenceParameters[i] = typeConstraintEvidenceParameters[i].simplify(context);
}
public String toString() {
return b.toString();
}
- public void collectQueryEffects(THashSet<Type> effects) {
- }
-
- public void collectEnforceEffects(THashSet<Type> effects) {
+ public CHRLiteral replace(ReplaceContext context) {
+ CHRLiteral copy = new CHRLiteral(location, relation, context.replace(parameters), killAfterMatch, negated);
+ for(int i=0;i<parameters.length;++i)
+ copy.parameters[i] = copy.parameters[i].replace(context);
+ copy.passive = passive;
+ copy.typeConstraintEvidenceParameters = context.replace(typeConstraintEvidenceParameters);
+ copy.typeParameters = context.replace(typeParameters);
+ copy.fields = context.replace(fields);
+ return copy;
}
}