tsmb.finish();
}
- if(generateEqualsAndHashCode) {
- // Create equals
- {
- TypeDesc CLASS = TypeDesc.forClass(Class.class);
+ if(generateEqualsAndHashCode)
+ implementHashCodeAndEquals(classBuilder, recordName, fieldNamePrefix, types);
+ }
- MethodBuilderBase tsmb = classBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[1]);
- LocalVariable parameter = tsmb.getParameter(0);
- Label success = tsmb.createLabel();
- Label failure = tsmb.createLabel();
+ public static void implementHashCodeAndEquals(ClassBuilder classBuilder, String recordName, String fieldNamePrefix, TypeDesc[] types) {
+ // Create equals
+ {
+ TypeDesc CLASS = TypeDesc.forClass(Class.class);
- // Check type
- tsmb.loadThis();
- tsmb.loadLocal(parameter);
- tsmb.ifComparisonBranch(success, "==", TypeDesc.OBJECT);
- tsmb.loadLocal(parameter);
- tsmb.ifNullBranch(failure, true);
- tsmb.loadLocal(parameter);
- tsmb.invokeVirtual("java/lang/Object", "getClass", CLASS, Constants.EMPTY_TYPEDESC_ARRAY);
- tsmb.loadThis();
- tsmb.invokeVirtual("java/lang/Object", "getClass", CLASS, Constants.EMPTY_TYPEDESC_ARRAY);
- tsmb.ifComparisonBranch(failure, "!=", CLASS);
- tsmb.loadLocal(parameter);
- tsmb.checkCast(classBuilder.getType());
- LocalVariable other = tsmb.createLocalVariable("other", classBuilder.getType());
- tsmb.storeLocal(other);
+ MethodBuilderBase tsmb = classBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[1]);
+ LocalVariable parameter = tsmb.getParameter(0);
+ Label success = tsmb.createLabel();
+ Label failure = tsmb.createLabel();
- // Compare fields
- for(int i=0;i<types.length;++i) {
- TypeDesc type = types[i];
- if(type.equals(TypeDesc.VOID))
- continue;
- tsmb.loadThis();
- tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
- tsmb.loadLocal(other);
- tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
- equals(tsmb, type, failure);
- }
+ // Check type
+ tsmb.loadThis();
+ tsmb.loadLocal(parameter);
+ tsmb.ifComparisonBranch(success, "==", TypeDesc.OBJECT);
+ tsmb.loadLocal(parameter);
+ tsmb.ifNullBranch(failure, true);
+ tsmb.loadLocal(parameter);
+ tsmb.invokeVirtual("java/lang/Object", "getClass", CLASS, Constants.EMPTY_TYPEDESC_ARRAY);
+ tsmb.loadThis();
+ tsmb.invokeVirtual("java/lang/Object", "getClass", CLASS, Constants.EMPTY_TYPEDESC_ARRAY);
+ tsmb.ifComparisonBranch(failure, "!=", CLASS);
+ tsmb.loadLocal(parameter);
+ tsmb.checkCast(classBuilder.getType());
+ LocalVariable other = tsmb.createLocalVariable("other", classBuilder.getType());
+ tsmb.storeLocal(other);
- // Return
- tsmb.setLocation(success);
- tsmb.loadConstant(true);
- tsmb.returnValue(TypeDesc.BOOLEAN);
- tsmb.setLocation(failure);
- tsmb.loadConstant(false);
- tsmb.returnValue(TypeDesc.BOOLEAN);
- tsmb.finish();
+ // Compare fields
+ for(int i=0;i<types.length;++i) {
+ TypeDesc type = types[i];
+ if(type.equals(TypeDesc.VOID))
+ continue;
+ tsmb.loadThis();
+ tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
+ tsmb.loadLocal(other);
+ tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
+ equals(tsmb, type, failure);
}
- // Create hashCode
- {
- MethodBuilderBase tsmb = classBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "hashCode", TypeDesc.INT, Constants.EMPTY_TYPEDESC_ARRAY);
- tsmb.loadConstant(recordName.hashCode());
- for(int i=0;i<types.length;++i) {
- TypeDesc type = types[i];
- if(type.equals(TypeDesc.VOID))
- continue;
- tsmb.loadConstant(31);
- tsmb.math(Opcodes.IMUL);
- tsmb.loadThis();
- tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
- hashCode(tsmb, type);
- tsmb.math(Opcodes.IADD);
- }
- tsmb.returnValue(TypeDesc.INT);
- tsmb.finish();
+ // Return
+ tsmb.setLocation(success);
+ tsmb.loadConstant(true);
+ tsmb.returnValue(TypeDesc.BOOLEAN);
+ tsmb.setLocation(failure);
+ tsmb.loadConstant(false);
+ tsmb.returnValue(TypeDesc.BOOLEAN);
+ tsmb.finish();
+ }
+
+ // Create hashCode
+ {
+ MethodBuilderBase tsmb = classBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "hashCode", TypeDesc.INT, Constants.EMPTY_TYPEDESC_ARRAY);
+ tsmb.loadConstant(recordName.hashCode());
+ for(int i=0;i<types.length;++i) {
+ TypeDesc type = types[i];
+ if(type.equals(TypeDesc.VOID))
+ continue;
+ tsmb.loadConstant(31);
+ tsmb.math(Opcodes.IMUL);
+ tsmb.loadThis();
+ tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
+ hashCode(tsmb, type);
+ tsmb.math(Opcodes.IADD);
}
+ tsmb.returnValue(TypeDesc.INT);
+ tsmb.finish();
}
}
// Create fields
CodeBuilderUtils.makeRecord(classBuilder, functionValue.toString(), Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, "p",
Arrays.copyOf(parameterTypes, knownParametersCount),
- false);
+ true);
// Create apply
{
for(int i=0;i<knownParametersCount;++i) {
mb.loadThis();
mb.loadLocal(mb.getParameter(i));
- mb.storeField(className, "p"+i, parameterTypes[i]);
+ mb.storeField(className, "p"+i, parameterTypes[i]);
}
mb.returnVoid();
mb.finish();
functionValue.applyExact(mb, parameters);
mb.box(functionValue.getReturnType());
mb.returnValue(TypeDesc.OBJECT);
- }
+ }
+
+ CodeBuilderUtils.implementHashCodeAndEquals(classBuilder, functionValue.toString(), "p", parameterTypes);
}
// Finish
public class ValueFromMethod {
+ private static final class Arity1Func extends FunctionImpl1<Object, Object> {
+ private final Method method;
+ private final boolean returnsVoid;
+
+ private Arity1Func(Method method, boolean returnsVoid) {
+ this.method = method;
+ this.returnsVoid = returnsVoid;
+ }
+
+ @Override
+ public Object apply(Object p0) {
+ try {
+ Object ret = method.invoke(null, p0);
+ return returnsVoid ? Tuple0.INSTANCE : ret;
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return method == null ? 0 : method.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Arity1Func other = (Arity1Func) obj;
+ return method.equals(other.method);
+ }
+ }
+
+ private static final class Arity2Func extends FunctionImpl2<Object, Object, Object> {
+ private final Method method;
+ private final boolean returnsVoid;
+
+ private Arity2Func(Method method, boolean returnsVoid) {
+ this.method = method;
+ this.returnsVoid = returnsVoid;
+ }
+
+ @Override
+ public Object apply(Object p0, Object p1) {
+ try {
+ Object ret = method.invoke(null, p0, p1);
+ return returnsVoid ? Tuple0.INSTANCE : ret;
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return method == null ? 0 : method.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Arity2Func other = (Arity2Func) obj;
+ return method.equals(other.method);
+ }
+ }
+
+ private static final class Arity3Func extends FunctionImpl3<Object, Object, Object, Object> {
+ private final Method method;
+ private final boolean returnsVoid;
+
+ private Arity3Func(Method method, boolean returnsVoid) {
+ this.method = method;
+ this.returnsVoid = returnsVoid;
+ }
+
+ @Override
+ public Object apply(Object p0, Object p1, Object p2) {
+ try {
+ Object ret = method.invoke(null, p0, p1, p2);
+ return returnsVoid ? Tuple0.INSTANCE : ret;
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return method == null ? 0 : method.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Arity3Func other = (Arity3Func) obj;
+ return method.equals(other.method);
+ }
+ }
+
+ private static final class Arity4Func extends FunctionImpl4<Object, Object, Object, Object, Object> {
+ private final Method method;
+ private final boolean returnsVoid;
+
+ private Arity4Func(Method method, boolean returnsVoid) {
+ this.method = method;
+ this.returnsVoid = returnsVoid;
+ }
+
+ @Override
+ public Object apply(Object p0, Object p1, Object p2, Object p3) {
+ try {
+ Object ret = method.invoke(null, p0, p1, p2, p3);
+ return returnsVoid ? Tuple0.INSTANCE : ret;
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return method == null ? 0 : method.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Arity4Func other = (Arity4Func) obj;
+ return method.equals(other.method);
+ }
+ }
+
+ private static final class ArityNFunc extends FunctionImplN {
+ private final Method method;
+ private final boolean returnsVoid;
+
+ private ArityNFunc(int arity, Method method, boolean returnsVoid) {
+ super(arity);
+ this.method = method;
+ this.returnsVoid = returnsVoid;
+ }
+
+ @Override
+ public Object doApply(Object... ps) {
+ try {
+ Object ret = method.invoke(null, ps);
+ return returnsVoid ? Tuple0.INSTANCE : ret;
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return method == null ? 0 : method.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ArityNFunc other = (ArityNFunc) obj;
+ return method.equals(other.method);
+ }
+ }
+
public static Object getValueFromStaticMethod(final Method method) throws ReflectiveOperationException {
int arity = method.getParameterTypes().length;
final boolean returnsVoid = method.getReturnType().equals(void.class);
return returnsVoid ? Tuple0.INSTANCE : ret;
}
case 1:
- return new FunctionImpl1<Object,Object>() {
- @Override
- public Object apply(Object p0) {
- try {
- Object ret = method.invoke(null, p0);
- return returnsVoid ? Tuple0.INSTANCE : ret;
- } catch (ReflectiveOperationException e) {
- throw new RuntimeException(e);
- }
- }
- };
+ return new Arity1Func(method, returnsVoid);
case 2:
- return new FunctionImpl2<Object,Object,Object>() {
- @Override
- public Object apply(Object p0, Object p1) {
- try {
- Object ret = method.invoke(null, p0, p1);
- return returnsVoid ? Tuple0.INSTANCE : ret;
- } catch (ReflectiveOperationException e) {
- throw new RuntimeException(e);
- }
- }
- };
+ return new Arity2Func(method, returnsVoid);
case 3:
- return new FunctionImpl3<Object,Object,Object,Object>() {
- @Override
- public Object apply(Object p0, Object p1, Object p2) {
- try {
- Object ret = method.invoke(null, p0, p1, p2);
- return returnsVoid ? Tuple0.INSTANCE : ret;
- } catch (ReflectiveOperationException e) {
- throw new RuntimeException(e);
- }
- }
- };
+ return new Arity3Func(method, returnsVoid);
case 4:
- return new FunctionImpl4<Object,Object,Object,Object,Object>() {
- @Override
- public Object apply(Object p0, Object p1, Object p2, Object p3) {
- try {
- Object ret = method.invoke(null, p0, p1, p2, p3);
- return returnsVoid ? Tuple0.INSTANCE : ret;
- } catch (ReflectiveOperationException e) {
- throw new RuntimeException(e);
- }
- }
- };
+ return new Arity4Func(method, returnsVoid);
default:
- return new FunctionImplN(arity) {
- @Override
- public Object doApply(Object... ps) {
- try {
- Object ret = method.invoke(null, ps);
- return returnsVoid ? Tuple0.INSTANCE : ret;
- } catch (ReflectiveOperationException e) {
- throw new RuntimeException(e);
- }
- }
- };
+ return new ArityNFunc(arity, method, returnsVoid);
}
}
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;
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;
this.body = body;
}
- @SuppressWarnings("rawtypes")
@Override
public Object execute(Object[] variableBindings) {
final Object[] inheritedVariableBindings = new Object[inheritedVariableIds.length];
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();
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 ");
+ }
}
}
public static final int MAX_ARITY = 8;
public static final String HEADER =
- "/**\n"
- + " * This code is generated in " + GenerateFunctions.class.getName() + ".\n"
- + " * Do not edit manually!\n"
+ "/**\r\n"
+ + " * This code is generated in " + GenerateFunctions.class.getName() + ".\r\n"
+ + " * Do not edit manually!\r\n"
+ " */"
;
p.println(" nps[i + " + n + "] = ps[i];");
p.println(" return f.applyArray(nps);");
p.println(" }");
+ p.println();
}
{
p.println(" @Override");
p.println(" sb.append(\")\");");
p.println(" return sb.toString();");
p.println(" }");
+ p.println();
+ }
+ {
+ p.println(" @Override");
+ p.println(" public int hashCode() {");
+ p.println(" int result = f.hashCode();");
+ for(int i=0;i<n;++i)
+ p.println(" result = 31 * result + (p"+i+" == null ? 0 : p"+i+".hashCode());");
+ p.println(" return result;");
+ p.println(" }");
+ p.println();
+ }
+ {
+ p.println(" @Override");
+ p.println(" public boolean equals(Object obj) {");
+ p.println(" if (this == obj)");
+ p.println(" return true;");
+ p.println(" if (obj == null)");
+ p.println(" return false;");
+ p.println(" if (getClass() != obj.getClass())");
+ p.println(" return false;");
+ p.println(" UnsaturatedFunction"+n+" other = (UnsaturatedFunction"+n+") obj;");
+ p.println(" if(!f.equals(other.f))");
+ p.println(" return false;");
+ for(int i=0;i<n;++i) {
+ p.println(" if(p"+i+" == null) {");
+ p.println(" if (other.p"+i+" != null)");
+ p.println(" return false;");
+ p.println(" } else if (!p"+i+".equals(other.p"+i+"))");
+ p.println(" return false;");
+ }
+ p.println(" return true;");
+ p.println(" }");
+ p.println();
}
p.println("}");
}
p.println(HEADER);
p.println("package " + PACKAGE + ";");
p.println();
+ p.println("import java.util.Arrays;");
+ p.println();
p.println("@SuppressWarnings(\"all\")");
p.println("public class UnsaturatedFunctionN implements Function {");
p.println(" private final Function f;");
p.println(" System.arraycopy(ops, 0, nps, ps.length, ops.length);");
p.println(" return f.applyArray(nps);");
p.println(" }");
+ p.println();
}
{
p.println(" @Override");
p.println(" sb.append(\")\");");
p.println(" return sb.toString();");
p.println(" }");
+ p.println();
+ }
+ {
+ p.println(" @Override");
+ p.println(" public int hashCode() {");
+ p.println(" return f.hashCode() + 31 * Arrays.hashCode(ps);");
+ p.println(" }");
+ p.println();
+ }
+ {
+ p.println(" @Override");
+ p.println(" public boolean equals(Object obj) {");
+ p.println(" if (this == obj)");
+ p.println(" return true;");
+ p.println(" if (obj == null)");
+ p.println(" return false;");
+ p.println(" if (getClass() != obj.getClass())");
+ p.println(" return false;");
+ p.println(" UnsaturatedFunctionN other = (UnsaturatedFunctionN) obj;");
+ p.println(" return f.equals(other.f) && Arrays.equals(ps, other.ps);");
+ p.println(" }");
+ p.println();
}
p.println("}");
}
public static Object get(List l, double i) {
return l.get((int)i);
}
+
+ private static final FunctionImpl2 BUILD_FUNC = new FunctionImpl2() {
+ @Override
+ public Object apply(Object p0, Object p1) {
+ ((ArrayList)p0).add(p1);
+ return p0;
+ }
+ };
public static List build(Function f) {
- return (List)f.apply(new ArrayList(),
- new FunctionImpl2() {
- @Override
- public Object apply(Object p0, Object p1) {
- ((List)p0).add(p1);
- return p0;
- }
- });
+ return (List)f.apply(new ArrayList(), BUILD_FUNC);
}
public static List range(int from, int to) {
nps[i + 1] = ps[i];
return f.applyArray(nps);
}
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(")");
return sb.toString();
}
+
+ @Override
+ public int hashCode() {
+ int result = f.hashCode();
+ result = 31 * result + (p0 == null ? 0 : p0.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ UnsaturatedFunction1 other = (UnsaturatedFunction1) obj;
+ if(!f.equals(other.f))
+ return false;
+ if(p0 == null) {
+ if (other.p0 != null)
+ return false;
+ } else if (!p0.equals(other.p0))
+ return false;
+ return true;
+ }
+
}
nps[i + 2] = ps[i];
return f.applyArray(nps);
}
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(")");
return sb.toString();
}
+
+ @Override
+ public int hashCode() {
+ int result = f.hashCode();
+ result = 31 * result + (p0 == null ? 0 : p0.hashCode());
+ result = 31 * result + (p1 == null ? 0 : p1.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ UnsaturatedFunction2 other = (UnsaturatedFunction2) obj;
+ if(!f.equals(other.f))
+ return false;
+ if(p0 == null) {
+ if (other.p0 != null)
+ return false;
+ } else if (!p0.equals(other.p0))
+ return false;
+ if(p1 == null) {
+ if (other.p1 != null)
+ return false;
+ } else if (!p1.equals(other.p1))
+ return false;
+ return true;
+ }
+
}
nps[i + 3] = ps[i];
return f.applyArray(nps);
}
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(")");
return sb.toString();
}
+
+ @Override
+ public int hashCode() {
+ int result = f.hashCode();
+ result = 31 * result + (p0 == null ? 0 : p0.hashCode());
+ result = 31 * result + (p1 == null ? 0 : p1.hashCode());
+ result = 31 * result + (p2 == null ? 0 : p2.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ UnsaturatedFunction3 other = (UnsaturatedFunction3) obj;
+ if(!f.equals(other.f))
+ return false;
+ if(p0 == null) {
+ if (other.p0 != null)
+ return false;
+ } else if (!p0.equals(other.p0))
+ return false;
+ if(p1 == null) {
+ if (other.p1 != null)
+ return false;
+ } else if (!p1.equals(other.p1))
+ return false;
+ if(p2 == null) {
+ if (other.p2 != null)
+ return false;
+ } else if (!p2.equals(other.p2))
+ return false;
+ return true;
+ }
+
}
nps[i + 4] = ps[i];
return f.applyArray(nps);
}
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(")");
return sb.toString();
}
+
+ @Override
+ public int hashCode() {
+ int result = f.hashCode();
+ result = 31 * result + (p0 == null ? 0 : p0.hashCode());
+ result = 31 * result + (p1 == null ? 0 : p1.hashCode());
+ result = 31 * result + (p2 == null ? 0 : p2.hashCode());
+ result = 31 * result + (p3 == null ? 0 : p3.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ UnsaturatedFunction4 other = (UnsaturatedFunction4) obj;
+ if(!f.equals(other.f))
+ return false;
+ if(p0 == null) {
+ if (other.p0 != null)
+ return false;
+ } else if (!p0.equals(other.p0))
+ return false;
+ if(p1 == null) {
+ if (other.p1 != null)
+ return false;
+ } else if (!p1.equals(other.p1))
+ return false;
+ if(p2 == null) {
+ if (other.p2 != null)
+ return false;
+ } else if (!p2.equals(other.p2))
+ return false;
+ if(p3 == null) {
+ if (other.p3 != null)
+ return false;
+ } else if (!p3.equals(other.p3))
+ return false;
+ return true;
+ }
+
}
nps[i + 5] = ps[i];
return f.applyArray(nps);
}
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(")");
return sb.toString();
}
+
+ @Override
+ public int hashCode() {
+ int result = f.hashCode();
+ result = 31 * result + (p0 == null ? 0 : p0.hashCode());
+ result = 31 * result + (p1 == null ? 0 : p1.hashCode());
+ result = 31 * result + (p2 == null ? 0 : p2.hashCode());
+ result = 31 * result + (p3 == null ? 0 : p3.hashCode());
+ result = 31 * result + (p4 == null ? 0 : p4.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ UnsaturatedFunction5 other = (UnsaturatedFunction5) obj;
+ if(!f.equals(other.f))
+ return false;
+ if(p0 == null) {
+ if (other.p0 != null)
+ return false;
+ } else if (!p0.equals(other.p0))
+ return false;
+ if(p1 == null) {
+ if (other.p1 != null)
+ return false;
+ } else if (!p1.equals(other.p1))
+ return false;
+ if(p2 == null) {
+ if (other.p2 != null)
+ return false;
+ } else if (!p2.equals(other.p2))
+ return false;
+ if(p3 == null) {
+ if (other.p3 != null)
+ return false;
+ } else if (!p3.equals(other.p3))
+ return false;
+ if(p4 == null) {
+ if (other.p4 != null)
+ return false;
+ } else if (!p4.equals(other.p4))
+ return false;
+ return true;
+ }
+
}
nps[i + 6] = ps[i];
return f.applyArray(nps);
}
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(")");
return sb.toString();
}
+
+ @Override
+ public int hashCode() {
+ int result = f.hashCode();
+ result = 31 * result + (p0 == null ? 0 : p0.hashCode());
+ result = 31 * result + (p1 == null ? 0 : p1.hashCode());
+ result = 31 * result + (p2 == null ? 0 : p2.hashCode());
+ result = 31 * result + (p3 == null ? 0 : p3.hashCode());
+ result = 31 * result + (p4 == null ? 0 : p4.hashCode());
+ result = 31 * result + (p5 == null ? 0 : p5.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ UnsaturatedFunction6 other = (UnsaturatedFunction6) obj;
+ if(!f.equals(other.f))
+ return false;
+ if(p0 == null) {
+ if (other.p0 != null)
+ return false;
+ } else if (!p0.equals(other.p0))
+ return false;
+ if(p1 == null) {
+ if (other.p1 != null)
+ return false;
+ } else if (!p1.equals(other.p1))
+ return false;
+ if(p2 == null) {
+ if (other.p2 != null)
+ return false;
+ } else if (!p2.equals(other.p2))
+ return false;
+ if(p3 == null) {
+ if (other.p3 != null)
+ return false;
+ } else if (!p3.equals(other.p3))
+ return false;
+ if(p4 == null) {
+ if (other.p4 != null)
+ return false;
+ } else if (!p4.equals(other.p4))
+ return false;
+ if(p5 == null) {
+ if (other.p5 != null)
+ return false;
+ } else if (!p5.equals(other.p5))
+ return false;
+ return true;
+ }
+
}
nps[i + 7] = ps[i];
return f.applyArray(nps);
}
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(")");
return sb.toString();
}
+
+ @Override
+ public int hashCode() {
+ int result = f.hashCode();
+ result = 31 * result + (p0 == null ? 0 : p0.hashCode());
+ result = 31 * result + (p1 == null ? 0 : p1.hashCode());
+ result = 31 * result + (p2 == null ? 0 : p2.hashCode());
+ result = 31 * result + (p3 == null ? 0 : p3.hashCode());
+ result = 31 * result + (p4 == null ? 0 : p4.hashCode());
+ result = 31 * result + (p5 == null ? 0 : p5.hashCode());
+ result = 31 * result + (p6 == null ? 0 : p6.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ UnsaturatedFunction7 other = (UnsaturatedFunction7) obj;
+ if(!f.equals(other.f))
+ return false;
+ if(p0 == null) {
+ if (other.p0 != null)
+ return false;
+ } else if (!p0.equals(other.p0))
+ return false;
+ if(p1 == null) {
+ if (other.p1 != null)
+ return false;
+ } else if (!p1.equals(other.p1))
+ return false;
+ if(p2 == null) {
+ if (other.p2 != null)
+ return false;
+ } else if (!p2.equals(other.p2))
+ return false;
+ if(p3 == null) {
+ if (other.p3 != null)
+ return false;
+ } else if (!p3.equals(other.p3))
+ return false;
+ if(p4 == null) {
+ if (other.p4 != null)
+ return false;
+ } else if (!p4.equals(other.p4))
+ return false;
+ if(p5 == null) {
+ if (other.p5 != null)
+ return false;
+ } else if (!p5.equals(other.p5))
+ return false;
+ if(p6 == null) {
+ if (other.p6 != null)
+ return false;
+ } else if (!p6.equals(other.p6))
+ return false;
+ return true;
+ }
+
}
nps[i + 8] = ps[i];
return f.applyArray(nps);
}
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(")");
return sb.toString();
}
+
+ @Override
+ public int hashCode() {
+ int result = f.hashCode();
+ result = 31 * result + (p0 == null ? 0 : p0.hashCode());
+ result = 31 * result + (p1 == null ? 0 : p1.hashCode());
+ result = 31 * result + (p2 == null ? 0 : p2.hashCode());
+ result = 31 * result + (p3 == null ? 0 : p3.hashCode());
+ result = 31 * result + (p4 == null ? 0 : p4.hashCode());
+ result = 31 * result + (p5 == null ? 0 : p5.hashCode());
+ result = 31 * result + (p6 == null ? 0 : p6.hashCode());
+ result = 31 * result + (p7 == null ? 0 : p7.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ UnsaturatedFunction8 other = (UnsaturatedFunction8) obj;
+ if(!f.equals(other.f))
+ return false;
+ if(p0 == null) {
+ if (other.p0 != null)
+ return false;
+ } else if (!p0.equals(other.p0))
+ return false;
+ if(p1 == null) {
+ if (other.p1 != null)
+ return false;
+ } else if (!p1.equals(other.p1))
+ return false;
+ if(p2 == null) {
+ if (other.p2 != null)
+ return false;
+ } else if (!p2.equals(other.p2))
+ return false;
+ if(p3 == null) {
+ if (other.p3 != null)
+ return false;
+ } else if (!p3.equals(other.p3))
+ return false;
+ if(p4 == null) {
+ if (other.p4 != null)
+ return false;
+ } else if (!p4.equals(other.p4))
+ return false;
+ if(p5 == null) {
+ if (other.p5 != null)
+ return false;
+ } else if (!p5.equals(other.p5))
+ return false;
+ if(p6 == null) {
+ if (other.p6 != null)
+ return false;
+ } else if (!p6.equals(other.p6))
+ return false;
+ if(p7 == null) {
+ if (other.p7 != null)
+ return false;
+ } else if (!p7.equals(other.p7))
+ return false;
+ return true;
+ }
+
}
*/
package org.simantics.scl.runtime.function;
+import java.util.Arrays;
+
@SuppressWarnings("all")
public class UnsaturatedFunctionN implements Function {
private final Function f;
System.arraycopy(ops, 0, nps, ps.length, ops.length);
return f.applyArray(nps);
}
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(")");
return sb.toString();
}
+
+ @Override
+ public int hashCode() {
+ return f.hashCode() + 31 * Arrays.hashCode(ps);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ UnsaturatedFunctionN other = (UnsaturatedFunctionN) obj;
+ return f.equals(other.f) && Arrays.equals(ps, other.ps);
+ }
+
}
@Test public void FromDynamic4() { test(); }
@Test public void FromDynamic5() { test(); }
@Test public void FunctionFunctor() { test(); }
+ @Test public void FunctionIdentity() { test(); }
@Test public void Functor() { test(); }
@Test public void FunctorM1() { test(); }
@Test public void Generalization() { test(); }
--- /dev/null
+import "Prelude"
+
+f n = do
+ a = n+1
+ \x -> a + x
+
+main = [atan2 1==atan2 1, atan2 1==atan2 2, f 1==f 1, f 1==f 2]
+--
+[true, false, true, false]
\ No newline at end of file