aea2cbfdcd47b0921222e4ccde6a50fd0c34db1c
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / chr / plan / PlanContext.java
1 package org.simantics.scl.compiler.elaboration.chr.plan;
2
3 import java.util.ArrayList;
4
5 import javax.crypto.CipherInputStream;
6
7 import org.simantics.scl.compiler.compilation.CompilationContext;
8 import org.simantics.scl.compiler.constants.IntegerConstant;
9 import org.simantics.scl.compiler.constants.JavaComparisonOperation;
10 import org.simantics.scl.compiler.constants.singletons.IncreaseByOne;
11 import org.simantics.scl.compiler.constants.singletons.JustConstant;
12 import org.simantics.scl.compiler.constants.singletons.ListElement;
13 import org.simantics.scl.compiler.constants.singletons.ListLength;
14 import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;
15 import org.simantics.scl.compiler.elaboration.expressions.Variable;
16 import org.simantics.scl.compiler.elaboration.java.EqualsFunction;
17 import org.simantics.scl.compiler.internal.codegen.continuations.Branch;
18 import org.simantics.scl.compiler.internal.codegen.continuations.ICont;
19 import org.simantics.scl.compiler.internal.codegen.references.IVal;
20 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
21 import org.simantics.scl.compiler.types.Type;
22 import org.simantics.scl.compiler.types.Types;
23
24 public abstract class PlanContext {
25     public CompilationContext context;
26     public CHRRuleset ruleset;
27     public IVal storeVar;
28     public ArrayList<PartnerFact> partnerFacts = new ArrayList<PartnerFact>();
29     public IVal currentId;
30     
31     public PlanContext(CompilationContext context, CHRRuleset ruleset, IVal storeVar) {
32         this.context = context;
33         this.ruleset = ruleset;
34         this.storeVar = storeVar;
35     }
36
37     public abstract void nextOp(CodeWriter w);
38
39     public IVal generateNewId(long location, CodeWriter w) {
40         if(currentId == null)
41             currentId = w.apply(location, ruleset.readCurrentId, storeVar);
42         IVal result = currentId;
43         currentId = w.apply(location, IncreaseByOne.INSTANCE, currentId);
44         return result;
45     }
46     
47     public void iterateList(long location, CodeWriter w, Variable variable, IVal listValue) {
48         Type componentType = variable.getType();
49         IVal listLength = w.apply(location, ListLength.INSTANCE.createSpecialization(componentType), listValue);
50         
51         CodeWriter body = w.createBlock(Types.INTEGER);
52         ICont bodyContinuation = body.getContinuation();
53         CodeWriter end = w.createBlock();
54                 
55         w.jump(body.getContinuation(), IntegerConstant.ZERO);
56         
57         IVal index = body.getParameters()[0];
58         body.branchAwayIf(body.apply(location, JavaComparisonOperation.IEQUAL, index, listLength),
59                 end.getContinuation());
60         variable.setVal(body.apply(location, ListElement.INSTANCE.createSpecialization(componentType), listValue, index));
61         nextOp(body);
62         if(body.isUnfinished())
63             body.jump(bodyContinuation, body.apply(location, IncreaseByOne.INSTANCE, index));
64         
65         w.continueAs(end);
66     }
67     
68     public void iterateMaybe(long location, CodeWriter w, Variable variable, IVal maybeValue) {
69         Type componentType = variable.getType();
70
71         CodeWriter end = w.createBlock();
72         CodeWriter body = w.createBlock(componentType);
73         w.switch_(maybeValue, new Branch[] {
74                 new Branch(JustConstant.INSTANCE, body.getContinuation()),
75                 new Branch(null, end.getContinuation())
76         });
77         
78         variable.setVal(body.getParameters()[0]);
79         nextOp(body);
80         if(body.isUnfinished())
81             body.jump(end.getContinuation());
82         
83         w.continueAs(end);
84     }
85
86     public void check(long location, CodeWriter w, IVal booleanValue) {
87         CodeWriter end = w.createBlock();
88         w.branchAwayUnless(booleanValue, end.getContinuation());
89         nextOp(w);
90         if(w.isUnfinished())
91             w.jump(end.getContinuation());
92         w.continueAs(end);
93     }
94
95     public void checkEquals(long location, CodeWriter w, IVal a, IVal b) {
96         check(location, w, w.apply(location,
97                 EqualsFunction.INSTANCE.createSpecialization(a.getType()),
98                 a, b));
99     }
100     
101     public void checkEqualsJust(long location, CodeWriter w, IVal value, IVal maybeValue) {
102         Type componentType = value.getType();
103
104         CodeWriter end = w.createBlock();
105         CodeWriter body = w.createBlock(componentType);
106         w.switch_(maybeValue, new Branch[] {
107                 new Branch(JustConstant.INSTANCE, body.getContinuation()),
108                 new Branch(null, end.getContinuation())
109         });
110         body.branchAwayUnless(body.apply(location,
111                 EqualsFunction.INSTANCE.createSpecialization(componentType),
112                 value, body.getParameters()[0]), end.getContinuation());
113         nextOp(body);
114         if(body.isUnfinished())
115             body.jump(end.getContinuation());
116         
117         w.continueAs(end);
118     }
119 }