]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EIf.java
Merge "Re-enabled Acorn transaction cancellation support for testing"
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / EIf.java
1 package org.simantics.scl.compiler.elaboration.expressions;\r
2 \r
3 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
4 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
5 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
6 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
7 import org.simantics.scl.compiler.environment.Environment;\r
8 import org.simantics.scl.compiler.errors.Locations;\r
9 import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
10 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
11 import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
12 import org.simantics.scl.compiler.internal.interpreted.IConstant;\r
13 import org.simantics.scl.compiler.internal.interpreted.IExpression;\r
14 import org.simantics.scl.compiler.internal.interpreted.IIf;\r
15 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;\r
16 import org.simantics.scl.compiler.types.Type;\r
17 import org.simantics.scl.compiler.types.Types;\r
18 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
19 import org.simantics.scl.runtime.tuple.Tuple0;\r
20 \r
21 import gnu.trove.map.hash.TObjectIntHashMap;\r
22 import gnu.trove.set.hash.THashSet;\r
23 import gnu.trove.set.hash.TIntHashSet;\r
24 \r
25 public class EIf extends Expression {\r
26     public Expression condition;\r
27     public Expression then_;\r
28     public Expression else_; // may be null\r
29     \r
30     public EIf(Expression condition, Expression then_, Expression else_) {\r
31         this.condition = condition;\r
32         this.then_ = then_;\r
33         this.else_ = else_;\r
34     }\r
35 \r
36     public EIf(long loc, Expression condition, Expression then_, Expression else_) {\r
37         super(loc);\r
38         this.condition = condition;\r
39         this.then_ = then_;\r
40         this.else_ = else_;\r
41     }\r
42 \r
43         public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
44         condition.collectRefs(allRefs, refs);\r
45         then_.collectRefs(allRefs, refs);\r
46         if(else_ != null)\r
47             else_.collectRefs(allRefs, refs);\r
48     }\r
49 \r
50         @Override\r
51         public void collectVars(TObjectIntHashMap<Variable> allVars,\r
52                 TIntHashSet vars) {\r
53             condition.collectVars(allVars, vars);\r
54         then_.collectVars(allVars, vars);\r
55         if(else_ != null)\r
56             else_.collectVars(allVars, vars);\r
57         }\r
58 \r
59         @Override\r
60         protected void updateType() throws MatchException {\r
61             setType(then_.getType());\r
62         }\r
63         \r
64         @Override\r
65         public IVal toVal(Environment env, CodeWriter w) {\r
66         IVal conditionVal = condition.toVal(env, w); \r
67         CodeWriter joinPoint = w.createBlock(getType());\r
68         CodeWriter thenBlock = w.createBlock();\r
69         if(else_ != null) {\r
70             CodeWriter elseBlock = w.createBlock();        \r
71             w.if_(conditionVal, thenBlock.getContinuation(), elseBlock.getContinuation());\r
72                 \r
73             IVal elseVal = else_.toVal(env, elseBlock);\r
74             elseBlock.jump(joinPoint.getContinuation(), elseVal);\r
75         }\r
76         else {\r
77             w.if_(conditionVal, thenBlock.getContinuation(), joinPoint.getContinuation());\r
78         }\r
79         IVal thenVal = then_.toVal(env, thenBlock);\r
80         thenBlock.jump(joinPoint.getContinuation(), thenVal);\r
81         w.continueAs(joinPoint);\r
82         \r
83         return w.getParameters()[0];\r
84     }\r
85 \r
86     @Override\r
87     public void collectFreeVariables(THashSet<Variable> vars) {\r
88         condition.collectFreeVariables(vars);\r
89         then_.collectFreeVariables(vars);\r
90         if(else_ != null)\r
91             else_.collectFreeVariables(vars);\r
92     }\r
93 \r
94     @Override\r
95     public Expression simplify(SimplificationContext context) {\r
96         condition = condition.simplify(context);\r
97         then_ = then_.simplify(context);\r
98         if(else_ != null)\r
99             else_ = else_.simplify(context);\r
100         return this;\r
101     }\r
102 \r
103     @Override\r
104     public Expression resolve(TranslationContext context) {\r
105         condition = condition.resolve(context);\r
106         then_ = then_.resolve(context);\r
107         if(else_ != null)\r
108             else_ = else_.resolve(context);\r
109         return this;\r
110     }\r
111 \r
112     @Override\r
113     public Expression replace(ReplaceContext context) {\r
114         return new EIf(condition.replace(context), \r
115                 then_.replace(context), \r
116                 else_ == null ? null : else_.replace(context));\r
117     }\r
118     \r
119     @Override\r
120     public Expression checkBasicType(TypingContext context, Type requiredType) {\r
121         condition = condition.checkType(context, Types.BOOLEAN);\r
122         then_ = then_.checkType(context, requiredType);\r
123         if(else_ != null)\r
124             else_ = else_.checkType(context, requiredType);\r
125         else\r
126             context.getErrorLog().log(location, "Else branch is required because the return value of the if expression is used.");\r
127         return this;\r
128     }\r
129     \r
130     @Override\r
131     public Expression checkIgnoredType(TypingContext context) {\r
132         condition = condition.checkType(context, Types.BOOLEAN);\r
133         then_ = then_.checkIgnoredType(context);\r
134         if(else_ != null)\r
135             else_ = else_.checkIgnoredType(context);\r
136         return this;\r
137     }\r
138     \r
139     @Override\r
140     public Expression decorate(ExpressionDecorator decorator) {\r
141         condition = condition.decorate(decorator);\r
142         then_ = then_.decorate(decorator);\r
143         if(else_ != null)\r
144             else_ = else_.decorate(decorator);        \r
145         return decorator.decorate(this);\r
146     }\r
147     \r
148     @Override\r
149     public boolean isEffectful() {\r
150         return condition.isEffectful() || then_.isEffectful() || (else_ != null && else_.isEffectful());\r
151     }\r
152 \r
153     @Override\r
154     public void collectEffects(THashSet<Type> effects) {\r
155         condition.collectEffects(effects);\r
156         then_.collectEffects(effects);\r
157         if(else_ != null)\r
158             else_.collectEffects(effects);\r
159     }\r
160     \r
161     @Override\r
162     public void setLocationDeep(long loc) {\r
163         if(location == Locations.NO_LOCATION) {\r
164             location = loc;\r
165             condition.setLocationDeep(loc);\r
166             then_.setLocationDeep(loc);\r
167             if(else_ != null)\r
168                 else_.setLocationDeep(loc);\r
169         }\r
170     }\r
171     \r
172     @Override\r
173     public void accept(ExpressionVisitor visitor) {\r
174         visitor.visit(this);\r
175     }\r
176     \r
177     @Override\r
178     public IExpression toIExpression(ExpressionInterpretationContext target) {\r
179         return new IIf(condition.toIExpression(target), then_.toIExpression(target), \r
180                 else_ != null ? else_.toIExpression(target) : new IConstant(Tuple0.INSTANCE));\r
181     }\r
182 \r
183     @Override\r
184     public void forVariables(VariableProcedure procedure) {\r
185         condition.forVariables(procedure);\r
186         then_.forVariables(procedure);\r
187         if(else_ != null)\r
188             else_.forVariables(procedure);\r
189     }\r
190     @Override\r
191     public Expression accept(ExpressionTransformer transformer) {\r
192         return transformer.transform(this);\r
193     }\r
194 \r
195 }\r