import org.simantics.scl.compiler.environment.Environment;
import org.simantics.scl.compiler.errors.Locations;
import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
+import org.simantics.scl.compiler.types.TPred;
import org.simantics.scl.compiler.types.TVar;
import org.simantics.scl.compiler.types.Type;
import org.simantics.scl.compiler.types.Types;
Type[] parameterTypes;
private static final Type RESOURCE = Types.con("Simantics/DB", "Resource");
-
+
public GraphPropertyRelation(Resource propertyRelation, Type valueType) {
this.propertyRelation = propertyRelation;
this.valueType = valueType;
public TVar[] getTypeVariables() {
return TVar.EMPTY_ARRAY;
}
-
+
+ @Override
+ public TPred[] getTypeConstraints() {
+ return new TPred[] {Types.pred(Types.SERIALIZABLE, valueType)};
+ }
+
@Override
public Type[] getParameterTypes() {
return parameterTypes;
default: throw new IllegalArgumentException();
}
}
-
+
@Override
public int getRequiredVariablesMask() {
return BF;
}
-
+
private static final Name POSSIBLE_RELATED_VALUE = Name.create("Simantics/DB", "possibleRelatedValue");
-
+
@Override
public void generate(long location, QueryCompilationContext context,
Type[] typeParameters, Variable[] parameters, int boundVariables) {
context.condition(new EApply(
context.getCompilationContext().getConstant(Names.Builtin_equals, valueType),
new Expression[] {
- new EVariable(temp),
- new EVariable(parameters[1])
+ new EVariable(temp),
+ new EVariable(parameters[1])
}
));
context.iterateMaybe(temp, possibleValue);
}
private static final Name CLAIM_RELATED_VALUE = Name.create("Simantics/DB", "claimRelatedValue");
-
+
@Override
public Expression generateEnforce(long location, EnforcingContext context,
Type[] typeParameters, Variable[] parameters) {
public int getPhase() {
return 0;
}
-
+
@Override
- public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters) {
- throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support enforce.");
+ public void generateIterate(PlanContext context, CodeWriter w, long location, int boundMask, Variable[] variables,
+ Expression[] expressions, Expression[] typeConstraintEvidenceParameters) {
+ Environment env = context.context.environment;
+ switch(boundMask) {
+ case BF:
+ context.iterateMaybe(location, w, variables[1],
+ w.apply(location,
+ env.getValue(POSSIBLE_RELATED_VALUE).getValue().createSpecialization(valueType),
+ typeConstraintEvidenceParameters[0].toVal(env, w),
+ expressions[0].toVal(env, w),
+ w.getModuleWriter().getExternalConstant(propertyRelation, Types.RESOURCE)));
+ break;
+ case BB:
+ context.checkEqualsJust(location, w, expressions[1].toVal(env, w),
+ w.apply(location,
+ env.getValue(POSSIBLE_RELATED_VALUE).getValue().createSpecialization(valueType),
+ typeConstraintEvidenceParameters[0].toVal(env, w),
+ expressions[0].toVal(env, w),
+ w.getModuleWriter().getExternalConstant(propertyRelation, Types.RESOURCE)));
+ break;
+ default: throw new IllegalArgumentException();
+ }
}
-
+
@Override
- public void generateIterate(PlanContext context, CodeWriter w, long location, int boundMask, Variable[] variables,
- Expression[] expressions) {
- throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support iterate.");
+ public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters, Expression[] typeConstraintEvidenceParameters) {
+ Environment env = context.context.environment;
+ w.apply(location,
+ env.getValue(CLAIM_RELATED_VALUE).getValue().createSpecialization(valueType),
+ typeConstraintEvidenceParameters[0].toVal(env, w),
+ parameters[0].toVal(env, w),
+ w.getModuleWriter().getExternalConstant(propertyRelation, Types.RESOURCE),
+ parameters[1].toVal(env, w));
}
}
@Override
public void generateIterate(PlanContext context, CodeWriter w, long location, int boundMask, Variable[] variables,
- Expression[] expressions) {
+ Expression[] expressions, Expression[] typeConstraintEvidenceParameters) {
Environment env = context.context.environment;
switch(boundMask) {
case BF:
}
@Override
- public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters) {
+ public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters,
+ Expression[] typeConstraintEvidenceParameters) {
Environment env = context.context.environment;
w.apply(location,
env.getValue(CLAIM).getValue(),
import org.simantics.scl.compiler.elaboration.modules.TypeClassInstance;
import org.simantics.scl.compiler.elaboration.modules.TypeClassMethod;
import org.simantics.scl.compiler.errors.ErrorLog;
+import org.simantics.scl.compiler.errors.Locations;
import org.simantics.scl.compiler.internal.codegen.references.IVal;
import org.simantics.scl.compiler.internal.codegen.references.Val;
import org.simantics.scl.compiler.internal.codegen.ssa.SSAModule;
decomposed.parameters[i].setVal(parameterVals[i]);
w.return_(decomposed.body.toVal(compilationContext.environment, w));
} catch(RuntimeException e) {
- errorLog.setExceptionPosition(value.getExpression().location);
+ long location = value.getExpression().location;
+ if(location == Locations.NO_LOCATION)
+ location = value.definitionLocation;
+ errorLog.setExceptionPosition(location);
throw e;
}
}
public CHRRelation relation;
public Type[] typeParameters;
public Expression[] parameters;
+ public Expression[] typeConstraintEvidenceParameters;
public boolean killAfterMatch;
public boolean negated;
public boolean passive = true;
public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
for(Expression parameter : parameters)
parameter.collectRefs(allRefs, refs);
+ if(typeConstraintEvidenceParameters != null)
+ for(Expression parameter : typeConstraintEvidenceParameters)
+ parameter.collectRefs(allRefs, refs);
}
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 {
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);
+ if(typeConstraintEvidenceParameters != null)
+ for(Expression parameter : typeConstraintEvidenceParameters)
+ parameter.collectVars(allVars, vars);
}
public void forVariables(VariableProcedure procedure) {
for(Expression parameter : parameters)
parameter.forVariables(procedure);
+ if(typeConstraintEvidenceParameters != null)
+ for(Expression parameter : typeConstraintEvidenceParameters)
+ parameter.forVariables(procedure);
}
public void collectFreeVariables(THashSet<Variable> vars) {
for(Expression parameter : parameters)
parameter.collectFreeVariables(vars);
+ if(typeConstraintEvidenceParameters != null)
+ for(Expression parameter : typeConstraintEvidenceParameters)
+ parameter.collectFreeVariables(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() {
package org.simantics.scl.compiler.elaboration.chr;
+import org.simantics.scl.compiler.types.TPred;
import org.simantics.scl.compiler.types.TVar;
import org.simantics.scl.compiler.types.Type;
import org.simantics.scl.compiler.types.Types;
TVar[] getTypeVariables();
Type[] getParameterTypes();
+ TPred[] getTypeConstraints();
}
import org.simantics.scl.compiler.constants.generic.MethodRef.FieldRef;
import org.simantics.scl.compiler.constants.generic.MethodRef.SetFieldRef;
import org.simantics.scl.compiler.elaboration.chr.analysis.UsageAnalysis;
-import org.simantics.scl.compiler.elaboration.chr.plan.PlanOp;
import org.simantics.scl.compiler.elaboration.chr.plan.PlanRealizer;
import org.simantics.scl.compiler.elaboration.chr.plan.PrioritizedPlan;
import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
public SCLRelation relation;
public Variable[] variables;
public Expression[] expressions;
+ public Expression[] typeConstraintEvidenceParameters;
public int boundMask;
public IterateRelationOp(long location, SCLRelation relation, Variable[] variables, Expression[] expressions,
- int boundMask) {
+ Expression[] typeConstraintEvidenceParameters, int boundMask) {
super(location);
this.relation = relation;
this.variables = variables;
this.expressions = expressions;
+ this.typeConstraintEvidenceParameters = typeConstraintEvidenceParameters;
this.boundMask = boundMask;
}
@Override
public void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w) {
- relation.generateIterate(planContext, w, location, boundMask, variables, expressions);
+ relation.generateIterate(planContext, w, location, boundMask, variables, expressions, typeConstraintEvidenceParameters);
}
}
import java.util.ArrayList;
+import javax.crypto.CipherInputStream;
+
import org.simantics.scl.compiler.compilation.CompilationContext;
import org.simantics.scl.compiler.constants.IntegerConstant;
import org.simantics.scl.compiler.constants.JavaComparisonOperation;
import org.simantics.scl.compiler.constants.singletons.IncreaseByOne;
+import org.simantics.scl.compiler.constants.singletons.JustConstant;
import org.simantics.scl.compiler.constants.singletons.ListElement;
import org.simantics.scl.compiler.constants.singletons.ListLength;
import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;
import org.simantics.scl.compiler.elaboration.expressions.Variable;
+import org.simantics.scl.compiler.elaboration.java.EqualsFunction;
+import org.simantics.scl.compiler.internal.codegen.continuations.Branch;
import org.simantics.scl.compiler.internal.codegen.continuations.ICont;
import org.simantics.scl.compiler.internal.codegen.references.IVal;
import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
w.continueAs(end);
}
+
+ public void iterateMaybe(long location, CodeWriter w, Variable variable, IVal maybeValue) {
+ Type componentType = variable.getType();
+
+ CodeWriter end = w.createBlock();
+ CodeWriter body = w.createBlock(componentType);
+ w.switch_(maybeValue, new Branch[] {
+ new Branch(JustConstant.INSTANCE, body.getContinuation()),
+ new Branch(null, end.getContinuation())
+ });
+
+ variable.setVal(body.getParameters()[0]);
+ nextOp(body);
+ if(body.isUnfinished())
+ body.jump(end.getContinuation());
+
+ w.continueAs(end);
+ }
public void check(long location, CodeWriter w, IVal booleanValue) {
CodeWriter end = w.createBlock();
w.jump(end.getContinuation());
w.continueAs(end);
}
+
+ public void checkEquals(long location, CodeWriter w, IVal a, IVal b) {
+ check(location, w, w.apply(location,
+ EqualsFunction.INSTANCE.createSpecialization(a.getType()),
+ a, b));
+ }
+
+ public void checkEqualsJust(long location, CodeWriter w, IVal value, IVal maybeValue) {
+ Type componentType = value.getType();
+
+ CodeWriter end = w.createBlock();
+ CodeWriter body = w.createBlock(componentType);
+ w.switch_(maybeValue, new Branch[] {
+ new Branch(JustConstant.INSTANCE, body.getContinuation()),
+ new Branch(null, end.getContinuation())
+ });
+ body.branchAwayUnless(body.apply(location,
+ EqualsFunction.INSTANCE.createSpecialization(componentType),
+ value, body.getParameters()[0]), end.getContinuation());
+ nextOp(body);
+ if(body.isUnfinished())
+ body.jump(end.getContinuation());
+
+ w.continueAs(end);
+ }
}
killAfterMatch(), literal.passive));
else if(relation instanceof ExternalCHRRelation)
context.addPlanOp(new IterateRelationOp(location, ((ExternalCHRRelation)relation).relation,
- freeVariables, boundExpressions, boundMask));
+ freeVariables, boundExpressions, literal.typeConstraintEvidenceParameters, boundMask));
else
throw new InternalCompilerError();
if(freeVariableCount > 1) {
import org.simantics.scl.compiler.internal.codegen.types.StandardTypeConstructor;
import org.simantics.scl.compiler.internal.parsing.Symbol;
import org.simantics.scl.compiler.types.TCon;
+import org.simantics.scl.compiler.types.TPred;
import org.simantics.scl.compiler.types.TVar;
import org.simantics.scl.compiler.types.Type;
import org.simantics.scl.compiler.types.Types;
public boolean isPassive() {
return plans.isEmpty();
}
+
+ public TPred[] getTypeConstraints() {
+ return TPred.EMPTY_ARRAY;
+ }
+
}
import org.simantics.scl.compiler.elaboration.chr.CHRRelation;
import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
+import org.simantics.scl.compiler.types.TPred;
import org.simantics.scl.compiler.types.TVar;
import org.simantics.scl.compiler.types.Type;
public Type[] getParameterTypes() {
return relation.getParameterTypes();
}
+
+ @Override
+ public TPred[] getTypeConstraints() {
+ return relation.getTypeConstraints();
+ }
@Override
public String toString() {
package org.simantics.scl.compiler.elaboration.chr.relations;
import org.simantics.scl.compiler.elaboration.chr.CHRRelation;
+import org.simantics.scl.compiler.types.TPred;
import org.simantics.scl.compiler.types.TVar;
import org.simantics.scl.compiler.types.Type;
import org.simantics.scl.compiler.types.Types;
public Type[] getParameterTypes() {
return parameterTypes;
}
+
+ public TPred[] getTypeConstraints() {
+ return TPred.EMPTY_ARRAY;
+ }
}
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
import org.simantics.scl.compiler.elaboration.chr.CHRRelation;
import org.simantics.scl.compiler.internal.parsing.Symbol;
+import org.simantics.scl.compiler.types.TPred;
import org.simantics.scl.compiler.types.TVar;
import org.simantics.scl.compiler.types.Type;
public TVar[] getTypeVariables() {
throw new InternalCompilerError("Encountered unresolved CHRRelation during type checking.");
}
+
+ public TPred[] getTypeConstraints() {
+ throw new InternalCompilerError("Encountered unresolved CHRRelation during type checking.");
+ }
}
}
@Override
- public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters) {
+ public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters,
+ Expression[] typeConstraintEvidenceParameters) {
throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support enforce.");
}
@Override
public void generateIterate(PlanContext context, CodeWriter w, long location, int boundMask, Variable[] variables,
- Expression[] expressions) {
+ Expression[] expressions, Expression[] typeConstraintEvidenceParameters) {
throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support iterate.");
}
}
}
@Override
- public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters) {
+ public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters,
+ Expression[] typeConstraintEvidenceParameters) {
throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support enforce.");
}
@Override
public void generateIterate(PlanContext context, CodeWriter w, long location, int boundMask, Variable[] variables,
- Expression[] expressions) {
+ Expression[] expressions, Expression[] typeConstraintEvidenceParameters) {
throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support iterate.");
}
}
import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext;
import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;
import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
+import org.simantics.scl.compiler.types.TPred;
import org.simantics.scl.compiler.types.TVar;
import org.simantics.scl.compiler.types.Type;
TVar[] getTypeVariables();
Type[] getParameterTypes();
+ default TPred[] getTypeConstraints() {
+ return TPred.EMPTY_ARRAY;
+ }
int getPhase();
double getSelectivity(int boundVariables);
long location,
int boundMask,
Variable[] variables,
- Expression[] expressions);
+ Expression[] expressions,
+ Expression[] typeConstraintEvidenceParameters);
void generateEnforce(
PlanContext context,
CodeWriter w,
long location,
- Expression[] parameters);
+ Expression[] parameters,
+ Expression[] typeConstraintEvidenceParameters);
}
public class ErrorLog {
ArrayList<CompilationError> errors = new ArrayList<CompilationError>();
- long exceptionPosition;
+ long exceptionPosition = Locations.NO_LOCATION;
public void log(String message) {
errors.add(new CompilationError(message));
}
public void log(Exception e) {
+ long location = Locations.NO_LOCATION;
if(e instanceof InternalCompilerError)
- log(((InternalCompilerError)e).location, e);
- else
- log(new CompilationError(e));
+ location = ((InternalCompilerError)e).location;
+ if(location == Locations.NO_LOCATION)
+ location = exceptionPosition;
+ log(new CompilationError(location, e));
}
public void log(long location, Exception e) {
if(this.exceptionPosition == Locations.NO_LOCATION)
this.exceptionPosition = exceptionPosition;
}
-
- public long getExceptionPosition() {
- return exceptionPosition;
- }
public String getErrorsAsString() {
StringBuilder b = new StringBuilder();
return result;
}
+ public static TPred[] replace(TPred[] types, TVar[] from, Type[] to) {
+ if(types.length == 0)
+ return TPred.EMPTY_ARRAY;
+ TPred[] result = new TPred[types.length];
+ for(int i=0;i<types.length;++i)
+ result[i] = (TPred)types[i].replace(from, to);
+ return result;
+ }
+
public static <T extends Type> Type[] replace(Type[] types, THashMap<TVar, T> map) {
if(types.length == 0)
return Type.EMPTY_ARRAY;