]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EIf.java
Merged changes from feature/scl to master.
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / EIf.java
index e1ccd53ddc3bc2a7bdf99d30fe12eb7ac19e6044..b714d7678aa7e4c88461b5c3ac529a0fc75414bb 100755 (executable)
@@ -9,12 +9,14 @@ import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
 import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
+import org.simantics.scl.compiler.internal.interpreted.IConstant;\r
 import org.simantics.scl.compiler.internal.interpreted.IExpression;\r
 import org.simantics.scl.compiler.internal.interpreted.IIf;\r
 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;\r
 import org.simantics.scl.compiler.types.Type;\r
 import org.simantics.scl.compiler.types.Types;\r
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
+import org.simantics.scl.runtime.tuple.Tuple0;\r
 \r
 import gnu.trove.map.hash.TObjectIntHashMap;\r
 import gnu.trove.set.hash.THashSet;\r
@@ -23,7 +25,7 @@ import gnu.trove.set.hash.TIntHashSet;
 public class EIf extends Expression {\r
     public Expression condition;\r
     public Expression then_;\r
-    public Expression else_;\r
+    public Expression else_; // may be null\r
     \r
     public EIf(Expression condition, Expression then_, Expression else_) {\r
         this.condition = condition;\r
@@ -41,7 +43,8 @@ public class EIf extends Expression {
        public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
         condition.collectRefs(allRefs, refs);\r
         then_.collectRefs(allRefs, refs);\r
-        else_.collectRefs(allRefs, refs);\r
+        if(else_ != null)\r
+            else_.collectRefs(allRefs, refs);\r
     }\r
 \r
        @Override\r
@@ -49,7 +52,8 @@ public class EIf extends Expression {
                TIntHashSet vars) {\r
            condition.collectVars(allVars, vars);\r
         then_.collectVars(allVars, vars);\r
-        else_.collectVars(allVars, vars);\r
+        if(else_ != null)\r
+            else_.collectVars(allVars, vars);\r
        }\r
 \r
        @Override\r
@@ -60,20 +64,20 @@ public class EIf extends Expression {
        @Override\r
        public IVal toVal(Environment env, CodeWriter w) {\r
         IVal conditionVal = condition.toVal(env, w); \r
-        \r
-        CodeWriter thenBlock = w.createBlock();\r
-        CodeWriter elseBlock = w.createBlock();\r
-        \r
         CodeWriter joinPoint = w.createBlock(getType());\r
-        \r
-        w.if_(conditionVal, thenBlock.getContinuation(), elseBlock.getContinuation());\r
-        \r
+        CodeWriter thenBlock = w.createBlock();\r
+        if(else_ != null) {\r
+            CodeWriter elseBlock = w.createBlock();        \r
+            w.if_(conditionVal, thenBlock.getContinuation(), elseBlock.getContinuation());\r
+                \r
+            IVal elseVal = else_.toVal(env, elseBlock);\r
+            elseBlock.jump(joinPoint.getContinuation(), elseVal);\r
+        }\r
+        else {\r
+            w.if_(conditionVal, thenBlock.getContinuation(), joinPoint.getContinuation());\r
+        }\r
         IVal thenVal = then_.toVal(env, thenBlock);\r
         thenBlock.jump(joinPoint.getContinuation(), thenVal);\r
-        \r
-        IVal elseVal = else_.toVal(env, elseBlock);\r
-        elseBlock.jump(joinPoint.getContinuation(), elseVal);\r
-        \r
         w.continueAs(joinPoint);\r
         \r
         return w.getParameters()[0];\r
@@ -83,14 +87,16 @@ public class EIf extends Expression {
     public void collectFreeVariables(THashSet<Variable> vars) {\r
         condition.collectFreeVariables(vars);\r
         then_.collectFreeVariables(vars);\r
-        else_.collectFreeVariables(vars);\r
+        if(else_ != null)\r
+            else_.collectFreeVariables(vars);\r
     }\r
 \r
     @Override\r
     public Expression simplify(SimplificationContext context) {\r
         condition = condition.simplify(context);\r
         then_ = then_.simplify(context);\r
-        else_ = else_.simplify(context);\r
+        if(else_ != null)\r
+            else_ = else_.simplify(context);\r
         return this;\r
     }\r
 \r
@@ -98,7 +104,8 @@ public class EIf extends Expression {
     public Expression resolve(TranslationContext context) {\r
         condition = condition.resolve(context);\r
         then_ = then_.resolve(context);\r
-        else_ = else_.resolve(context);\r
+        if(else_ != null)\r
+            else_ = else_.resolve(context);\r
         return this;\r
     }\r
 \r
@@ -106,14 +113,17 @@ public class EIf extends Expression {
     public Expression replace(ReplaceContext context) {\r
         return new EIf(condition.replace(context), \r
                 then_.replace(context), \r
-                else_.replace(context));\r
+                else_ == null ? null : else_.replace(context));\r
     }\r
     \r
     @Override\r
     public Expression checkBasicType(TypingContext context, Type requiredType) {\r
         condition = condition.checkType(context, Types.BOOLEAN);\r
         then_ = then_.checkType(context, requiredType);\r
-        else_ = else_.checkType(context, requiredType);\r
+        if(else_ != null)\r
+            else_ = else_.checkType(context, requiredType);\r
+        else\r
+            context.getErrorLog().log(location, "Else branch is required because the return value of the if expression is used.");\r
         return this;\r
     }\r
     \r
@@ -121,7 +131,8 @@ public class EIf extends Expression {
     public Expression checkIgnoredType(TypingContext context) {\r
         condition = condition.checkType(context, Types.BOOLEAN);\r
         then_ = then_.checkIgnoredType(context);\r
-        else_ = else_.checkIgnoredType(context);\r
+        if(else_ != null)\r
+            else_ = else_.checkIgnoredType(context);\r
         return this;\r
     }\r
     \r
@@ -129,20 +140,22 @@ public class EIf extends Expression {
     public Expression decorate(ExpressionDecorator decorator) {\r
         condition = condition.decorate(decorator);\r
         then_ = then_.decorate(decorator);\r
-        else_ = else_.decorate(decorator);        \r
+        if(else_ != null)\r
+            else_ = else_.decorate(decorator);        \r
         return decorator.decorate(this);\r
     }\r
     \r
     @Override\r
     public boolean isEffectful() {\r
-       return condition.isEffectful() || then_.isEffectful() || else_.isEffectful();\r
+       return condition.isEffectful() || then_.isEffectful() || (else_ != null && else_.isEffectful());\r
     }\r
 \r
     @Override\r
     public void collectEffects(THashSet<Type> effects) {\r
         condition.collectEffects(effects);\r
         then_.collectEffects(effects);\r
-        else_.collectEffects(effects);\r
+        if(else_ != null)\r
+            else_.collectEffects(effects);\r
     }\r
     \r
     @Override\r
@@ -151,7 +164,8 @@ public class EIf extends Expression {
             location = loc;\r
             condition.setLocationDeep(loc);\r
             then_.setLocationDeep(loc);\r
-            else_.setLocationDeep(loc);\r
+            if(else_ != null)\r
+                else_.setLocationDeep(loc);\r
         }\r
     }\r
     \r
@@ -162,26 +176,16 @@ public class EIf extends Expression {
     \r
     @Override\r
     public IExpression toIExpression(ExpressionInterpretationContext target) {\r
-        return new IIf(condition.toIExpression(target), then_.toIExpression(target), else_.toIExpression(target));\r
-    }\r
-    \r
-    public Expression getCondition() {\r
-        return condition;\r
-    }\r
-    \r
-    public Expression getThen() {\r
-        return then_;\r
-    }\r
-    \r
-    public Expression getElse() {\r
-        return else_;\r
+        return new IIf(condition.toIExpression(target), then_.toIExpression(target), \r
+                else_ != null ? else_.toIExpression(target) : new IConstant(Tuple0.INSTANCE));\r
     }\r
 \r
     @Override\r
     public void forVariables(VariableProcedure procedure) {\r
         condition.forVariables(procedure);\r
         then_.forVariables(procedure);\r
-        else_.forVariables(procedure);\r
+        if(else_ != null)\r
+            else_.forVariables(procedure);\r
     }\r
     @Override\r
     public Expression accept(ExpressionTransformer transformer) {\r