]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/OptionalRelation.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / java / OptionalRelation.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/OptionalRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/OptionalRelation.java
new file mode 100644 (file)
index 0000000..3276e0f
--- /dev/null
@@ -0,0 +1,84 @@
+package org.simantics.scl.compiler.elaboration.java;
+
+import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.elaboration.expressions.EApply;
+import org.simantics.scl.compiler.elaboration.expressions.EVariable;
+import org.simantics.scl.compiler.elaboration.expressions.Expression;
+import org.simantics.scl.compiler.elaboration.expressions.Variable;
+import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;
+import org.simantics.scl.compiler.elaboration.relations.AbstractRelation;
+import org.simantics.scl.compiler.types.TVar;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.kinds.Kinds;
+
+public class OptionalRelation extends AbstractRelation {
+    public static final OptionalRelation INSTANCE = new OptionalRelation();
+    
+    private OptionalRelation() {}
+    
+    private static final TVar A = Types.var(Kinds.STAR);
+    
+    private static final TVar[] TYPE_VARIABLES = new TVar[] {A};
+    
+    @Override
+    public TVar[] getTypeVariables() {
+        return TYPE_VARIABLES;
+    }
+    
+    private static final Type[] PARAMETER_TYPES = new Type[] {A, Types.apply(Types.MAYBE, A)};
+    
+    @Override
+    public Type[] getParameterTypes() {
+        return PARAMETER_TYPES;
+    }
+
+    @Override
+    public int getPhase() {
+        return 0;
+    }
+    
+    @Override
+    public double getSelectivity(int boundVariables) {
+        switch(boundVariables) {
+        case FF: 
+        case BF: return Double.POSITIVE_INFINITY;
+        case FB: return 0.95;
+        case BB: return 0.5;
+        default: throw new IllegalArgumentException();
+        }
+    }
+    
+    @Override
+    public int getRequiredVariablesMask() {
+        return FB;
+    }
+
+    @Override
+    public void generate(long location,
+            QueryCompilationContext context,
+            Type[] typeParameters, Variable[] parameters, int boundVariables) {
+        switch(boundVariables) {
+        case FB:
+            context.iterateMaybe(parameters[0], new EVariable(parameters[1]));
+            break;
+        case BB: 
+            context.condition(
+                    new EApply(
+                            context.getConstant(Name.create("Prelude", "elemMaybe"), typeParameters),
+                            new Expression[] {
+                                context.getEvidence(location, Types.pred(Types.EQ, typeParameters[0])),
+                                new EVariable(parameters[0]),
+                                new EVariable(parameters[1])
+                            }
+                            ));
+            break;
+        default: throw new IllegalArgumentException();
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "Optional";
+    }
+}