import java.util.ArrayList;
import org.cojen.classfile.TypeDesc;
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
import org.simantics.scl.compiler.compilation.CompilationContext;
import org.simantics.scl.compiler.constants.BooleanConstant;
import org.simantics.scl.compiler.constants.Constant;
import org.simantics.scl.compiler.constants.NoRepConstant;
import org.simantics.scl.compiler.constants.generic.CallJava;
import org.simantics.scl.compiler.constants.generic.MethodRef.FieldRef;
+import org.simantics.scl.compiler.constants.generic.MethodRef.ObjectMethodRef;
import org.simantics.scl.compiler.constants.generic.MethodRef.SetFieldRef;
import org.simantics.scl.compiler.elaboration.chr.analysis.CHRConstraintGGInfo;
import org.simantics.scl.compiler.elaboration.chr.analysis.UsageAnalysis;
import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
import org.simantics.scl.compiler.elaboration.expressions.block.IncludeStatement;
import org.simantics.scl.compiler.environment.AmbiguousNameException;
import org.simantics.scl.compiler.errors.Locations;
import org.simantics.scl.compiler.internal.codegen.references.IVal;
import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;
import org.simantics.scl.compiler.internal.codegen.types.StandardTypeConstructor;
+import org.simantics.scl.compiler.internal.codegen.utils.Constants;
import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
import org.simantics.scl.compiler.internal.parsing.Symbol;
import org.simantics.scl.compiler.types.TCon;
import org.simantics.scl.compiler.types.TVar;
import org.simantics.scl.compiler.types.Type;
import org.simantics.scl.compiler.types.Types;
-import org.simantics.scl.runtime.chr.CHRContext;
import gnu.trove.map.hash.THashMap;
import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
import gnu.trove.set.hash.TIntHashSet;
public class CHRRuleset extends Symbol {
public TCon runtimeRulesetType;
public BoundVar runtimeRulesetVariable;
public TypeDesc runtimeRulesetTypeDesc;
- public Constant readCurrentId;
- public Constant writeCurrentId;
+
+ public static final Constant READ_CURRENT_ID = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.INTEGER, new Type[] {Types.CHRContext},
+ null, new FieldRef(CHRCodeGenerationConstants.CHRContext_name, "currentId", CHRRuntimeRulesetCodeGenerator.FACT_ID_TYPE), null);
+ public static final Constant WRITE_CURRENT_ID = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {Types.CHRContext, Types.INTEGER},
+ null, new SetFieldRef(CHRCodeGenerationConstants.CHRContext_name, "currentId", CHRRuntimeRulesetCodeGenerator.FACT_ID_TYPE), null);
+ public static final Constant GENERATE_ID = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.INTEGER, new Type[] {Types.CHRContext},
+ null, new ObjectMethodRef(false, CHRCodeGenerationConstants.CHRContext_name, "generateId", CHRRuntimeRulesetCodeGenerator.FACT_ID_TYPE, Constants.EMPTY_TYPEDESC_ARRAY), null);
// FIXME remove and change the parameter of Expression.toVal
private CompilationContext cachedContext;
public CHRRuleset() {
initConstraint = new CHRConstraint(Locations.NO_LOCATION, INIT_CONSTRAINT, Type.EMPTY_ARRAY);
- constraints.add(initConstraint);
+ addConstraint(initConstraint);
+ }
+
+ public void addConstraint(CHRConstraint constraint) {
+ constraints.add(constraint);
+ constraint.setParent(this);
}
public void resolve(TranslationContext context) {
}*/
}
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- for(IncludeStatement include : includes)
- include.value.collectRefs(allRefs, refs);
- for(CHRRule rule : rules)
- rule.collectRefs(allRefs, refs);
- }
-
public void checkType(TypingContext context) {
for(IncludeStatement include : includes)
include.value = include.value.checkType(context, include.ruleset.runtimeRulesetType);
rule.collectVars(allVars, vars);
}
- public void forVariables(VariableProcedure procedure) {
- for(IncludeStatement include : includes)
- include.value.forVariables(procedure);
- for(CHRRule rule : rules)
- rule.forVariables(procedure);
- }
-
- public void collectFreeVariables(THashSet<Variable> vars) {
- for(IncludeStatement include : includes)
- include.value.collectFreeVariables(vars);
- for(CHRRule rule : rules)
- rule.collectFreeVariables(vars);
- }
-
public void setLocationDeep(long loc) {
if(location == Locations.NO_LOCATION) {
this.location = loc;
}
}
- public void compile(SimplificationContext context) {
- initializeCodeGeneration(context.getCompilationContext());
- if(extensible)
- applyExtensibleDefaults();
- UsageAnalysis.analyzeUsage(this);
- for(CHRRule rule : rules) {
- rule.compile(context.getCompilationContext(), initConstraint);
- for(CHRSearchPlan plan : rule.plans) {
- CHRConstraint constraint = plan.constraint;
- if(!activeConstraintGGInfo.containsKey(constraint)) {
- activeConstraintGGInfo.put(constraint, new CHRConstraintGGInfo(rule.priority));
- IncludeStatement include = constraintSourceMap.get(constraint);
- if(include != null) {
- ArrayList<CHRConstraint> list = inverseActiveConstraintSourceMap.get(include);
- if(list == null) {
- list = new ArrayList<CHRConstraint>(4);
- inverseActiveConstraintSourceMap.put(include, list);
+ private void compile(SimplificationContext context) {
+ try {
+ initializeCodeGeneration(context.getCompilationContext());
+ if(extensible)
+ applyExtensibleDefaults();
+ UsageAnalysis.analyzeUsage(this);
+ for(CHRRule rule : rules) {
+ rule.compile(context.getCompilationContext(), initConstraint);
+ for(CHRSearchPlan plan : rule.plans) {
+ CHRConstraint constraint = plan.constraint;
+ if(!activeConstraintGGInfo.containsKey(constraint)) {
+ activeConstraintGGInfo.put(constraint, new CHRConstraintGGInfo(rule.priority));
+ IncludeStatement include = constraintSourceMap.get(constraint);
+ if(include != null) {
+ ArrayList<CHRConstraint> list = inverseActiveConstraintSourceMap.get(include);
+ if(list == null) {
+ list = new ArrayList<CHRConstraint>(4);
+ inverseActiveConstraintSourceMap.put(include, list);
+ }
+ list.add(constraint);
}
- list.add(constraint);
}
}
}
- }
- // remove init constraint if it is not useful
- if(getMinimumPriority(initConstraint) == Integer.MAX_VALUE) {
- constraints.remove(0);
- initConstraint = null;
+ // remove init constraint if it is not useful
+ if(getMinimumPriority(initConstraint) == Integer.MAX_VALUE) {
+ constraints.remove(0);
+ initConstraint = null;
+ }
+ } catch(Exception e) {
+ throw InternalCompilerError.injectLocation(location, e);
}
}
int max = 1 << constraint.parameterTypes.length;
for(int i=0;i<max;++i)
constraint.getOrCreateIndex(cachedContext, i);
+ constraint.setMayBeRemoved();
/*
constraint.getOrCreateIndex(cachedContext, 0);
if(constraint.parameterTypes.length > 0)
}
}
- public void simplify(SimplificationContext context) {
- for(IncludeStatement include : includes)
+ private void simplify(SimplificationContext context) {
+ for(IncludeStatement include : includes) {
+ //include.ruleset.simplifyAndCompileIfNeeded(context);
include.value = include.value.simplify(context);
+ }
for(CHRRule rule : rules)
rule.simplify(context);
}
+ public void simplifyAndCompileIfNeeded(SimplificationContext context) {
+ if(runtimeRulesetTypeDesc == null) {
+ simplify(context);
+ compile(context);
+ }
+ }
+
public void setRulesetType(TCon type, String className) {
this.runtimeRulesetType = type;
this.runtimeRulesetClassName = className;
runtimeRulesetVariable = new BoundVar(runtimeRulesetType);
for(CHRConstraint constraint : constraints)
constraint.initializeCodeGeneration(context, this);
- readCurrentId = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.INTEGER, new Type[] {Types.CHRContext},
- null, new FieldRef(CHRCodeGenerationConstants.CHRContext_name, "currentId", CHRRuntimeRulesetCodeGenerator.FACT_ID_TYPE), null);
- writeCurrentId = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {Types.CHRContext, Types.INTEGER},
- null, new SetFieldRef(CHRCodeGenerationConstants.CHRContext_name, "currentId", CHRRuntimeRulesetCodeGenerator.FACT_ID_TYPE), null);
if(createTypeDesc && context.module != null) // for unit testing
context.module.addTypeDescriptor(runtimeRulesetType.name, new StandardTypeConstructor(runtimeRulesetType, TVar.EMPTY_ARRAY, runtimeRulesetTypeDesc));
}
public IVal generateCode(CodeWriter w) {
for(IncludeStatement include : includes) {
- include.storeVar = include.value.toVal(cachedContext.environment, w);
+ include.storeVar = include.value.toVal(cachedContext, w);
initialPriorityNumber = Math.max(initialPriorityNumber, include.ruleset.initialPriorityNumber + include.ruleset.priorityCount);
}
CHRRulesetObject object = new CHRRulesetObject(runtimeRulesetVariable, this);
PlanRealizer realizer = new PlanRealizer(cachedContext, this, runtimeRulesetVariable, implementationParameters[0], plan.ops);
realizer.nextOp(methodWriter);
if(methodWriter.isUnfinished())
- methodWriter.return_(BooleanConstant.TRUE);
+ methodWriter.return_(rule.location, BooleanConstant.TRUE);
}
}
- if(!includes.isEmpty()) {
+ if(!includes.isEmpty() || extensible) {
{
CodeWriter methodWriter = object.createMethod(w.getModuleWriter(), TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {Types.CHRContext});
initializer = methodWriter.getFunction();
new JavaMethod(true, runtimeRulesetClassName, "register", Types.PROC, Types.UNIT, new Type[] {runtimeRulesetType, Types.CHRContext, include.ruleset.runtimeRulesetType}),
object.getTarget(), methodWriter.getParameters()[0], include.storeVar);
}
- methodWriter.return_(NoRepConstant.UNIT);
+ if(extensible)
+ methodWriter.apply(Locations.NO_LOCATION,
+ new JavaMethod(true, runtimeRulesetClassName, "register", Types.PROC, Types.UNIT, new Type[] {runtimeRulesetType, Types.CHRContext}),
+ object.getTarget(), methodWriter.getParameters()[0]);
+ methodWriter.return_(location, NoRepConstant.UNIT);
}
{
CodeWriter methodWriter = object.createMethod(w.getModuleWriter(), TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {Types.CHRContext});
new JavaMethod(true, runtimeRulesetClassName, "unregister", Types.PROC, Types.UNIT, new Type[] {runtimeRulesetType, Types.CHRContext, include.ruleset.runtimeRulesetType}),
object.getTarget(), methodWriter.getParameters()[0], include.storeVar);
}
- methodWriter.return_(NoRepConstant.UNIT);
+ if(extensible)
+ methodWriter.apply(Locations.NO_LOCATION,
+ new JavaMethod(true, runtimeRulesetClassName, "unregister", Types.PROC, Types.UNIT, new Type[] {runtimeRulesetType, Types.CHRContext}),
+ object.getTarget(), methodWriter.getParameters()[0]);
+ methodWriter.return_(location, NoRepConstant.UNIT);
}
}
if(initConstraint != null) {
new JavaMethod(true, runtimeRulesetClassName, "initialize", Types.PROC, Types.UNIT, new Type[] {runtimeRulesetType, Types.CHRContext}),
object.getTarget(), chrContext);
}
- IVal initFact = w.apply(location, initConstraint.constructor, IntegerConstant.ZERO);
+ IVal initFact = w.apply(location, initConstraint.constructor, w.apply(location, GENERATE_ID, chrContext));
w.apply(location, initConstraint.addProcedure, runtimeRulesetVariable, chrContext, initFact);
w.apply(location, ACTIVATE, chrContext, new IntegerConstant(Integer.MAX_VALUE));
if(deinitializer != null) {
return runtimeRulesetVariable;
}
- public void collectEffects(THashSet<Type> effects) {
- for(CHRRule rule : rules) {
- for(CHRLiteral literal : rule.head.literals)
- literal.collectQueryEffects(effects);
- for(CHRLiteral literal : rule.head.literals)
- literal.collectEnforceEffects(effects);
- }
+ public void addRule(CHRRule rule) {
+ rules.add(rule);
+ rule.parentRuleset = this;
}
}