]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/interpreted/ILambda.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / interpreted / ILambda.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/interpreted/ILambda.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/interpreted/ILambda.java
new file mode 100644 (file)
index 0000000..aac13af
--- /dev/null
@@ -0,0 +1,157 @@
+package org.simantics.scl.compiler.internal.interpreted;
+
+import org.simantics.scl.runtime.function.FunctionImpl1;
+import org.simantics.scl.runtime.function.FunctionImpl2;
+import org.simantics.scl.runtime.function.FunctionImpl3;
+import org.simantics.scl.runtime.function.FunctionImpl4;
+import org.simantics.scl.runtime.function.FunctionImplN;
+
+public class ILambda implements IExpression {
+    private final int[] inheritedVariableIds;
+    private final int arity;
+    private final int variableBindingsLength;
+    private final IExpression body;
+    
+    public ILambda(int[] inheritedVariableIds, int arity,
+            int variableBindingsLength, IExpression body) {
+        this.inheritedVariableIds = inheritedVariableIds;
+        this.arity = arity;
+        this.variableBindingsLength = variableBindingsLength;
+        this.body = body;
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Override
+    public Object execute(Object[] variableBindings) {
+        final Object[] inheritedVariableBindings = new Object[inheritedVariableIds.length];
+        for(int i=0;i<inheritedVariableIds.length;++i)
+            inheritedVariableBindings[i] = variableBindings[inheritedVariableIds[i]];
+        switch(arity) {
+        case 1:
+            return new FunctionImpl1() {
+                @Override
+                public Object apply(Object param0) {
+                    Object[] newVariableBindings = new Object[variableBindingsLength];
+                    int i = 0;;
+                    for(;i < inheritedVariableBindings.length;++i)
+                        newVariableBindings[i] = inheritedVariableBindings[i];
+                    newVariableBindings[i] = param0;
+                    return body.execute(newVariableBindings);
+                }
+                
+                @Override
+                public String toString() {
+                       return ILambda.this.toString(inheritedVariableBindings);
+                }
+            };
+        case 2:
+            return new FunctionImpl2() {
+                @Override
+                public Object apply(Object param0, Object param1) {
+                    Object[] newVariableBindings = new Object[variableBindingsLength];
+                    int i = 0;;
+                    for(;i < inheritedVariableBindings.length;++i)
+                        newVariableBindings[i] = inheritedVariableBindings[i];
+                    newVariableBindings[i++] = param0;
+                    newVariableBindings[i] = param1;
+                    return body.execute(newVariableBindings);
+                }
+                
+                @Override
+                public String toString() {
+                       return ILambda.this.toString(inheritedVariableBindings);
+                }
+            };
+        case 3:
+            return new FunctionImpl3() {
+                @Override
+                public Object apply(Object param0, Object param1, Object param2) {
+                    Object[] newVariableBindings = new Object[variableBindingsLength];
+                    int i = 0;;
+                    for(;i < inheritedVariableBindings.length;++i)
+                        newVariableBindings[i] = inheritedVariableBindings[i];
+                    newVariableBindings[i++] = param0;
+                    newVariableBindings[i++] = param1;
+                    newVariableBindings[i] = param2;
+                    return body.execute(newVariableBindings);
+                }
+                
+                @Override
+                public String toString() {
+                       return ILambda.this.toString(inheritedVariableBindings);
+                }
+            };
+        case 4:
+            return new FunctionImpl4() {
+                @Override
+                public Object apply(Object param0, Object param1, Object param2, Object param3) {
+                    Object[] newVariableBindings = new Object[variableBindingsLength];
+                    int i = 0;;
+                    for(;i < inheritedVariableBindings.length;++i)
+                        newVariableBindings[i] = inheritedVariableBindings[i];
+                    newVariableBindings[i++] = param0;
+                    newVariableBindings[i++] = param1;
+                    newVariableBindings[i++] = param2;
+                    newVariableBindings[i] = param3;
+                    return body.execute(newVariableBindings);
+                }
+                
+                @Override
+                public String toString() {
+                       return ILambda.this.toString(inheritedVariableBindings);
+                }
+            };
+        default:
+            return new FunctionImplN(arity) {
+                @Override
+                public Object doApply(Object... ps) {
+                    Object[] newVariableBindings = new Object[variableBindingsLength];
+                    int i = 0;;
+                    for(;i < inheritedVariableBindings.length;++i)
+                        newVariableBindings[i] = inheritedVariableBindings[i];
+                    for(Object p : ps)
+                        newVariableBindings[i++] = p;
+                    return body.execute(newVariableBindings);
+                }
+                
+                @Override
+                public String toString() {
+                       return ILambda.this.toString(inheritedVariableBindings);
+                }
+            };
+        }
+    }
+    
+    @Override
+    public String toString() {
+        StringBuilder b = new StringBuilder();
+        b.append("(\\");
+        for(int i=0;i<inheritedVariableIds.length;++i)
+            b.append('v').append(i)
+            .append("(v").append(inheritedVariableIds[i]).append(") ");
+        for(int i=0;i<arity;++i)
+            b.append('v').append(i+inheritedVariableIds.length).append(' ');
+        b.append("-> ");
+        b.append(body);
+        b.append(')');
+        return b.toString();
+    }
+    
+    public String toString(Object[] variableBindings) {
+       StringBuilder sb = new StringBuilder();
+       appendVariableBindings(sb, variableBindings);
+       sb.append(this.toString());
+       return sb.toString();
+    }
+    
+    private static void appendVariableBindings(StringBuilder sb, Object[] variableBindings) {
+       if (variableBindings.length > 0) {
+               sb.append("(let {");
+               for(int i = 0; i < variableBindings.length; i++) {
+                       if (i > 0) sb.append("; ");
+                       sb.append("v").append(i).append("=").append(variableBindings[i].toString());
+               }
+               sb.append("} in ");
+       }       
+    }
+}