]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/interpreted/ILambda.java
(refs #7090) Generated Function objects implement equals and hashCode
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / interpreted / ILambda.java
index aac13af73abe661ddcc275f0e3f83908b6937e4f..0695ebb4da8396bf3be8f680568419aadadd8b36 100644 (file)
@@ -1,5 +1,7 @@
 package org.simantics.scl.compiler.internal.interpreted;
 
+import java.util.Arrays;
+
 import org.simantics.scl.runtime.function.FunctionImpl1;
 import org.simantics.scl.runtime.function.FunctionImpl2;
 import org.simantics.scl.runtime.function.FunctionImpl3;
@@ -7,11 +9,229 @@ import org.simantics.scl.runtime.function.FunctionImpl4;
 import org.simantics.scl.runtime.function.FunctionImplN;
 
 public class ILambda implements IExpression {
+    private final class Arity1Func extends FunctionImpl1 {
+        private final Object[] inheritedVariableBindings;
+
+        private Arity1Func(Object[] inheritedVariableBindings) {
+            this.inheritedVariableBindings = inheritedVariableBindings;
+        }
+
+        @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);
+        }
+
+        @Override
+        public int hashCode() {
+            return ILambda.this.hashCode() + 31*Arrays.hashCode(inheritedVariableBindings);
+        }
+
+        private ILambda getParent() {
+            return ILambda.this;
+        }
+        
+        @Override
+        public boolean equals(Object obj) {
+            if(obj == this)
+                return true;
+            if(obj == null || obj.getClass() != getClass())
+                return false;
+            Arity1Func other = (Arity1Func)obj;
+            return ILambda.this == other.getParent() && Arrays.equals(inheritedVariableBindings, other.inheritedVariableBindings);
+        }
+    }
+
+    private final class Arity2Func extends FunctionImpl2 {
+        private final Object[] inheritedVariableBindings;
+
+        private Arity2Func(Object[] inheritedVariableBindings) {
+            this.inheritedVariableBindings = inheritedVariableBindings;
+        }
+
+        @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);
+        }
+        
+        @Override
+        public int hashCode() {
+            return ILambda.this.hashCode() + 31*Arrays.hashCode(inheritedVariableBindings);
+        }
+
+        private ILambda getParent() {
+            return ILambda.this;
+        }
+        
+        @Override
+        public boolean equals(Object obj) {
+            if(obj == this)
+                return true;
+            if(obj == null || obj.getClass() != getClass())
+                return false;
+            Arity2Func other = (Arity2Func)obj;
+            return ILambda.this == other.getParent() && Arrays.equals(inheritedVariableBindings, other.inheritedVariableBindings);
+        }
+    }
+
+    private final class Arity3Func extends FunctionImpl3 {
+        private final Object[] inheritedVariableBindings;
+
+        private Arity3Func(Object[] inheritedVariableBindings) {
+            this.inheritedVariableBindings = inheritedVariableBindings;
+        }
+
+        @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);
+        }
+        
+        @Override
+        public int hashCode() {
+            return ILambda.this.hashCode() + 31*Arrays.hashCode(inheritedVariableBindings);
+        }
+
+        private ILambda getParent() {
+            return ILambda.this;
+        }
+        
+        @Override
+        public boolean equals(Object obj) {
+            if(obj == this)
+                return true;
+            if(obj == null || obj.getClass() != getClass())
+                return false;
+            Arity3Func other = (Arity3Func)obj;
+            return ILambda.this == other.getParent() && Arrays.equals(inheritedVariableBindings, other.inheritedVariableBindings);
+        }
+    }
+
+    private final class Arity4Func extends FunctionImpl4 {
+        private final Object[] inheritedVariableBindings;
+
+        private Arity4Func(Object[] inheritedVariableBindings) {
+            this.inheritedVariableBindings = inheritedVariableBindings;
+        }
+
+        @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);
+        }
+
+        @Override
+        public int hashCode() {
+            return ILambda.this.hashCode() + 31*Arrays.hashCode(inheritedVariableBindings);
+        }
+
+        private ILambda getParent() {
+            return ILambda.this;
+        }
+        
+        @Override
+        public boolean equals(Object obj) {
+            if(obj == this)
+                return true;
+            if(obj == null || obj.getClass() != getClass())
+                return false;
+            Arity4Func other = (Arity4Func)obj;
+            return ILambda.this == other.getParent() && Arrays.equals(inheritedVariableBindings, other.inheritedVariableBindings);
+        }
+    }
+
+    private final class ArityNFunc extends FunctionImplN {
+        private final Object[] inheritedVariableBindings;
+
+        private ArityNFunc(Object[] inheritedVariableBindings) {
+            super(arity);
+            this.inheritedVariableBindings = inheritedVariableBindings;
+        }
+
+        @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 int hashCode() {
+            return ILambda.this.hashCode() + 31*Arrays.hashCode(inheritedVariableBindings);
+        }
+
+        private ILambda getParent() {
+            return ILambda.this;
+        }
+        
+        @Override
+        public boolean equals(Object obj) {
+            if(obj == this)
+                return true;
+            if(obj == null || obj.getClass() != getClass())
+                return false;
+            ArityNFunc other = (ArityNFunc)obj;
+            return ILambda.this == other.getParent() && Arrays.equals(inheritedVariableBindings, other.inheritedVariableBindings);
+        }
+    }
+
     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;
@@ -20,7 +240,6 @@ public class ILambda implements IExpression {
         this.body = body;
     }
 
-    @SuppressWarnings("rawtypes")
     @Override
     public Object execute(Object[] variableBindings) {
         final Object[] inheritedVariableBindings = new Object[inheritedVariableIds.length];
@@ -28,100 +247,18 @@ public class ILambda implements IExpression {
             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);
-                }
-            };
+            return new Arity1Func(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);
-                }
-            };
+            return new Arity2Func(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);
-                }
-            };
+            return new Arity3Func(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);
-                }
-            };
+            return new Arity4Func(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);
-                }
-            };
+            return new ArityNFunc(inheritedVariableBindings);
         }
     }
-    
+
     @Override
     public String toString() {
         StringBuilder b = new StringBuilder();
@@ -136,22 +273,22 @@ public class ILambda implements IExpression {
         b.append(')');
         return b.toString();
     }
-    
+
     public String toString(Object[] variableBindings) {
-       StringBuilder sb = new StringBuilder();
-       appendVariableBindings(sb, variableBindings);
-       sb.append(this.toString());
-       return sb.toString();
+        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 ");
-       }       
+        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 ");
+        }      
     }
 }