1 package org.simantics.scl.compiler.elaboration.expressions;
3 import org.simantics.scl.compiler.compilation.CompilationContext;
4 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
5 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
6 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
7 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
8 import org.simantics.scl.compiler.errors.Locations;
9 import org.simantics.scl.compiler.internal.codegen.references.IVal;
10 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
11 import org.simantics.scl.compiler.internal.interpreted.IConstant;
12 import org.simantics.scl.compiler.internal.interpreted.IExpression;
13 import org.simantics.scl.compiler.internal.interpreted.IIf;
14 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
15 import org.simantics.scl.compiler.types.Type;
16 import org.simantics.scl.compiler.types.Types;
17 import org.simantics.scl.compiler.types.exceptions.MatchException;
18 import org.simantics.scl.runtime.tuple.Tuple0;
20 public class EIf extends Expression {
21 public Expression condition;
22 public Expression then_;
23 public Expression else_; // may be null
25 public EIf(Expression condition, Expression then_, Expression else_) {
26 this.condition = condition;
31 public EIf(long loc, Expression condition, Expression then_, Expression else_) {
33 this.condition = condition;
39 protected void updateType() throws MatchException {
40 setType(then_.getType());
44 public IVal toVal(CompilationContext context, CodeWriter w) {
45 IVal conditionVal = condition.toVal(context, w);
46 CodeWriter joinPoint = w.createBlock(getType());
47 CodeWriter thenBlock = w.createBlock();
49 CodeWriter elseBlock = w.createBlock();
50 w.if_(conditionVal, thenBlock.getContinuation(), elseBlock.getContinuation());
52 IVal elseVal = else_.toVal(context, elseBlock);
53 elseBlock.jump(joinPoint.getContinuation(), elseVal);
56 w.if_(conditionVal, thenBlock.getContinuation(), joinPoint.getContinuation());
58 IVal thenVal = then_.toVal(context, thenBlock);
59 thenBlock.jump(joinPoint.getContinuation(), thenVal);
60 w.continueAs(joinPoint);
62 return w.getParameters()[0];
66 public Expression simplify(SimplificationContext context) {
67 condition = condition.simplify(context);
68 then_ = then_.simplify(context);
70 else_ = else_.simplify(context);
75 public Expression resolve(TranslationContext context) {
76 condition = condition.resolve(context);
77 then_ = then_.resolve(context);
79 else_ = else_.resolve(context);
84 public Expression replace(ReplaceContext context) {
85 return new EIf(condition.replace(context),
86 then_.replace(context),
87 else_ == null ? null : else_.replace(context));
91 public Expression checkBasicType(TypingContext context, Type requiredType) {
92 condition = condition.checkType(context, Types.BOOLEAN);
93 then_ = then_.checkType(context, requiredType);
95 else_ = else_.checkType(context, requiredType);
97 context.getErrorLog().log(location, "Else branch is required because the return value of the if expression is used.");
102 public Expression checkIgnoredType(TypingContext context) {
103 condition = condition.checkType(context, Types.BOOLEAN);
104 then_ = then_.checkIgnoredType(context);
106 else_ = else_.checkIgnoredType(context);
111 public boolean isEffectful() {
112 return condition.isEffectful() || then_.isEffectful() || (else_ != null && else_.isEffectful());
116 public void setLocationDeep(long loc) {
117 if(location == Locations.NO_LOCATION) {
119 condition.setLocationDeep(loc);
120 then_.setLocationDeep(loc);
122 else_.setLocationDeep(loc);
127 public void accept(ExpressionVisitor visitor) {
132 public IExpression toIExpression(ExpressionInterpretationContext target) {
133 return new IIf(condition.toIExpression(target), then_.toIExpression(target),
134 else_ != null ? else_.toIExpression(target) : new IConstant(Tuple0.INSTANCE));
138 public Expression accept(ExpressionTransformer transformer) {
139 return transformer.transform(this);
143 public int getSyntacticFunctionArity() {
144 return Math.max(then_.getSyntacticFunctionArity(), else_.getSyntacticFunctionArity());