]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRuleset.java
Merge "Adding more detailed message to thrown exceptions in SyncElementFactory"
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / chr / CHRRuleset.java
1 package org.simantics.scl.compiler.elaboration.chr;\r
2 \r
3 import java.util.ArrayList;\r
4 \r
5 import org.cojen.classfile.TypeDesc;\r
6 import org.simantics.scl.compiler.compilation.CompilationContext;\r
7 import org.simantics.scl.compiler.constants.BooleanConstant;\r
8 import org.simantics.scl.compiler.constants.Constant;\r
9 import org.simantics.scl.compiler.constants.IntegerConstant;\r
10 import org.simantics.scl.compiler.constants.JavaMethod;\r
11 import org.simantics.scl.compiler.constants.generic.CallJava;\r
12 import org.simantics.scl.compiler.constants.generic.MethodRef.FieldRef;\r
13 import org.simantics.scl.compiler.constants.generic.MethodRef.SetFieldRef;\r
14 import org.simantics.scl.compiler.elaboration.chr.analysis.UsageAnalysis;\r
15 import org.simantics.scl.compiler.elaboration.chr.plan.PlanOp;\r
16 import org.simantics.scl.compiler.elaboration.chr.plan.PlanRealizer;\r
17 import org.simantics.scl.compiler.elaboration.chr.plan.PrioritizedPlan;\r
18 import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;\r
19 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
20 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
21 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
22 import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
23 import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;\r
24 import org.simantics.scl.compiler.errors.Locations;\r
25 import org.simantics.scl.compiler.internal.codegen.chr.CHRCodeGenerator;\r
26 import org.simantics.scl.compiler.internal.codegen.references.BoundVar;\r
27 import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
28 import org.simantics.scl.compiler.internal.codegen.types.StandardTypeConstructor;\r
29 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
30 import org.simantics.scl.compiler.internal.parsing.Symbol;\r
31 import org.simantics.scl.compiler.types.TCon;\r
32 import org.simantics.scl.compiler.types.TVar;\r
33 import org.simantics.scl.compiler.types.Type;\r
34 import org.simantics.scl.compiler.types.Types;\r
35 \r
36 import gnu.trove.map.hash.TObjectIntHashMap;\r
37 import gnu.trove.set.hash.THashSet;\r
38 import gnu.trove.set.hash.TIntHashSet;\r
39 \r
40 public class CHRRuleset extends Symbol {\r
41     \r
42     public static final String INIT_CONSTRAINT = "__INIT__";\r
43     \r
44     public ArrayList<CHRConstraint> constraints = new ArrayList<CHRConstraint>();\r
45     public ArrayList<CHRRule> rules = new ArrayList<CHRRule>();\r
46     \r
47     public CHRConstraint initConstraint;\r
48     public int priorityCount;\r
49     \r
50     public String storeClassName;\r
51     public TCon storeType;\r
52     public BoundVar storeVariable;\r
53     public TypeDesc storeTypeDesc;\r
54     public Constant activateProcedure;\r
55     public Constant readCurrentId;\r
56     public Constant writeCurrentId;\r
57     \r
58     // FIXME remove and change the parameter of Expression.toVal\r
59     private CompilationContext cachedContext;\r
60     \r
61     // For code generation\r
62     public BoundVar this_;\r
63     public BoundVar[] parameters;\r
64     public TypeDesc[] parameterTypeDescs;\r
65     \r
66     public CHRRuleset() {\r
67         initConstraint = new CHRConstraint(Locations.NO_LOCATION, INIT_CONSTRAINT, Type.EMPTY_ARRAY);\r
68         constraints.add(initConstraint);\r
69     }\r
70     \r
71     public void resolve(TranslationContext context) {\r
72         for(CHRConstraint constraint : constraints)\r
73             context.newCHRConstraint(constraint.name, constraint);\r
74         priorityCount = 0;\r
75         for(CHRRule rule : rules) {\r
76             rule.resolve(context);\r
77             rule.priority = priorityCount++;\r
78         }\r
79         /*for(CHRConstraint constraint : constraints) {\r
80             Variable newVariable = context.newVariable("claim" + constraint.factClassName);\r
81         }*/\r
82     }\r
83 \r
84     public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
85         for(CHRRule rule : rules)\r
86             rule.collectRefs(allRefs, refs);\r
87     }\r
88 \r
89     public void checkType(TypingContext context) {\r
90         for(CHRRule rule : rules)\r
91             rule.checkType(context);\r
92     }\r
93 \r
94     public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {\r
95         for(CHRRule rule : rules)\r
96             rule.collectVars(allVars, vars);\r
97     }\r
98 \r
99     public void forVariables(VariableProcedure procedure) {\r
100         for(CHRRule rule : rules)\r
101             rule.forVariables(procedure);\r
102     }\r
103 \r
104     public void collectFreeVariables(THashSet<Variable> vars) {\r
105         for(CHRRule rule : rules)\r
106             rule.collectFreeVariables(vars);\r
107     }\r
108 \r
109     public void setLocationDeep(long loc) {\r
110         if(location == Locations.NO_LOCATION) {\r
111             this.location = loc;\r
112             for(CHRRule rule : rules)\r
113                 rule.setLocationDeep(loc);\r
114         }\r
115     }\r
116 \r
117     public void compile(SimplificationContext context) {\r
118         initializeCodeGeneration(context.getCompilationContext());\r
119         UsageAnalysis.analyzeUsage(this);\r
120         for(CHRRule rule : rules)\r
121             rule.compile(context.getCompilationContext(), initConstraint);\r
122         // remove init constraint if it is not useful\r
123         if(initConstraint.plans.isEmpty()) {\r
124             constraints.remove(0);\r
125             initConstraint = null;\r
126         }\r
127         for(CHRConstraint constraint : constraints) {\r
128             constraint.plans.sort((PrioritizedPlan a, PrioritizedPlan b) -> {\r
129                 return Integer.compare(a.priority, b.priority);\r
130             });\r
131             /*System.out.println(constraint.name);\r
132             for(PrioritizedPlan plan : constraint.plans) {\r
133                 System.out.println("  priority " + plan.priority);\r
134                 for(PlanOp op : plan.ops)\r
135                     System.out.println("    " + op);\r
136             }*/\r
137         }\r
138     }\r
139 \r
140     public void simplify(SimplificationContext context) {\r
141         for(CHRRule rule : rules)\r
142             rule.simplify(context);\r
143     }\r
144     \r
145     public void initializeCodeGeneration(CompilationContext context) {\r
146         cachedContext = context; // FIXME remove\r
147         \r
148         String suffix = context.namingPolicy.getFreshClosureClassNameSuffix();\r
149         storeType = Types.con(context.namingPolicy.getModuleName(), "CHR" + suffix);\r
150         storeClassName = context.namingPolicy.getModuleClassName() + suffix;\r
151         storeTypeDesc = TypeDesc.forClass(storeClassName);\r
152         storeVariable = new BoundVar(storeType); \r
153         for(CHRConstraint constraint : constraints)\r
154             constraint.initializeCodeGeneration(context, this);\r
155         activateProcedure = new JavaMethod(true, storeClassName, "activate", Types.PROC, Types.UNIT, storeType, Types.INTEGER);\r
156         readCurrentId = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.INTEGER, new Type[] {storeType},\r
157                 null, new FieldRef(storeClassName, "currentId", CHRCodeGenerator.FACT_ID_TYPE), null);\r
158         writeCurrentId = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {storeType, Types.INTEGER},\r
159                 null, new SetFieldRef(storeClassName, "currentId", CHRCodeGenerator.FACT_ID_TYPE), null);\r
160         if(context.module != null) // for unit testing\r
161             context.module.addTypeDescriptor(storeType.name, new StandardTypeConstructor(storeType, TVar.EMPTY_ARRAY, storeTypeDesc));\r
162     }\r
163     \r
164     public void generateCode(CodeWriter w) {\r
165         CHRRulesetObject object = new CHRRulesetObject(storeVariable, this);\r
166         w.defineObject(object);\r
167         for(CHRConstraint constraint : constraints) {\r
168             //System.out.println(constraint);\r
169             for(PrioritizedPlan plan : constraint.plans) {\r
170                 /*System.out.println("    plan " + plan.priority);\r
171                 for(PlanOp planOp : plan.ops)\r
172                     System.out.println("        " + planOp);*/\r
173                 PlanRealizer realizer = new PlanRealizer(cachedContext, this, storeVariable, plan.ops);\r
174                 CodeWriter methodWriter = object.createMethod(w.getModuleWriter(), TVar.EMPTY_ARRAY, Types.PROC, Types.BOOLEAN, new Type[] {constraint.factType});\r
175                 plan.implementation = methodWriter.getFunction();\r
176                 plan.activeFact.setVal(methodWriter.getParameters()[0]);\r
177                 realizer.nextOp(methodWriter);\r
178                 if(methodWriter.isUnfinished())\r
179                     methodWriter.return_(BooleanConstant.TRUE);\r
180             }\r
181         }\r
182         if(initConstraint != null) {\r
183             IVal initFact = w.apply(location, initConstraint.constructor, IntegerConstant.ZERO);\r
184             w.apply(location, initConstraint.addProcedure, storeVariable, initFact);\r
185             w.apply(location, activateProcedure, storeVariable, new IntegerConstant(Integer.MAX_VALUE));\r
186         }\r
187     }\r
188 \r
189     public void collectEffects(THashSet<Type> effects) {\r
190         for(CHRRule rule : rules) {\r
191             for(CHRLiteral literal : rule.head.literals)\r
192                 literal.collectQueryEffects(effects);\r
193             for(CHRLiteral literal : rule.head.literals)\r
194                 literal.collectEnforceEffects(effects);\r
195         }\r
196     }\r
197 }\r