-package org.simantics.scl.runtime.generation;\r
-\r
-import java.io.File;\r
-import java.io.FileOutputStream;\r
-import java.io.PrintStream;\r
-import java.net.URL;\r
-\r
-public class GenerateFunctions {\r
- \r
- public static final String PACKAGE = "org.simantics.scl.runtime.function";\r
- public static final int MAX_ARITY = 8;\r
- \r
- public static final String HEADER =\r
- "/**\n"\r
- + " * This code is generated in " + GenerateFunctions.class.getName() + ".\n"\r
- + " * Do not edit manually!\n"\r
- + " */" \r
- ;\r
- \r
- public static void generateFunctionN(PrintStream p, int n) {\r
- p.println(HEADER);\r
- p.println("package " + PACKAGE + ";");\r
- p.println(); \r
- p.print("public interface Function"+n+"<");\r
- for(int i=0;i<n;++i)\r
- p.print("P" + i + ",");\r
- p.println("R> {");\r
- p.print(" R apply(");\r
- for(int i=0;i<n;++i) {\r
- if(i>0)\r
- p.print(", ");\r
- p.print("P"+i+" p" + i);\r
- }\r
- p.println(");");\r
- p.println("}");\r
- }\r
- \r
- public static void generateFunctionN(PrintStream p) {\r
- p.println(HEADER);\r
- p.println("package " + PACKAGE + ";");\r
- p.println();\r
- p.println("public interface FunctionN {");\r
- p.println(" Object applyArray(Object ... ps);");\r
- p.println("}");\r
- }\r
- \r
- public static void generateFunction(PrintStream p) {\r
- p.println(HEADER);\r
- p.println("package " + PACKAGE + ";");\r
- p.println();\r
- //p.println("@SuppressWarnings(\"all\")");\r
- p.print("public interface Function<");\r
- for(int k=0;k<MAX_ARITY;++k) {\r
- p.print("P"+k+",");\r
- }\r
- for(int k=1;k<=MAX_ARITY;++k) {\r
- p.print("R"+k);\r
- if(k < MAX_ARITY)\r
- p.print(",");\r
- }\r
- p.println("> extends"); \r
- for(int k=1;k<=MAX_ARITY;++k) {\r
- p.print(" Function" + k + "<");\r
- for(int i=0;i<k;++i) {\r
- p.print("P"+i+",");\r
- }\r
- p.println("R"+k+">,");\r
- }\r
- p.println(" FunctionN {");\r
- p.println("}");\r
- }\r
- \r
- public static void generateFunctionImplN(PrintStream p, int n) {\r
- p.println(HEADER);\r
- p.println("package " + PACKAGE + ";");\r
- p.println();\r
- p.println("import java.util.Arrays;");\r
- p.println();\r
- p.println("@SuppressWarnings(\"all\")");\r
- p.print("public abstract class FunctionImpl" + n + "<");\r
- for(int i=0;i<n;++i)\r
- p.print("P" + i + ",");\r
- p.print("R> implements Function<");\r
- for(int i=0;i<n;++i)\r
- p.print("P" + i + ",");\r
- for(int i=n;i<MAX_ARITY;++i)\r
- p.print("Object,");\r
- for(int i=1;i<=MAX_ARITY;++i) {\r
- if(i == n)\r
- p.print("R");\r
- else \r
- p.print("Object");\r
- if(i < MAX_ARITY)\r
- p.print(",");\r
- }\r
- p.println("> {");\r
- for(int k=1;k<Math.min(n, MAX_ARITY+1);++k) {\r
- p.println(" @Override");\r
- p.print(" public Object apply(");\r
- for(int i=0;i<k;++i) {\r
- if(i>0)\r
- p.print(", ");\r
- p.print("Object p" + i);\r
- }\r
- p.println(") {");\r
- p.print(" return new UnsaturatedFunction" + k + "(this");\r
- for(int i=0;i<k;++i)\r
- p.print(", p" + i);\r
- p.println(");");\r
- p.println(" }");\r
- p.println();\r
- }\r
- {\r
- if(n <= MAX_ARITY)\r
- p.println(" @Override");\r
- p.print(" public abstract R apply(");\r
- for(int i=0;i<n;++i) {\r
- if(i>0)\r
- p.print(", ");\r
- p.print("P"+i+" p" + i);\r
- }\r
- p.println(");");\r
- p.println();\r
- }\r
- for(int k=n+1;k<=MAX_ARITY;++k) {\r
- p.println(" @Override");\r
- p.print(" public Object apply(");\r
- for(int i=0;i<k;++i) {\r
- if(i>0)\r
- p.print(", ");\r
- p.print("Object p" + i);\r
- }\r
- p.println(") {");\r
- p.println(" try {");\r
- p.print(" return ((Function)apply(");\r
- for(int i=0;i<n;++i) {\r
- if(i>0)\r
- p.print(", ");\r
- p.print("(P"+i+")p" + i);\r
- }\r
- p.print(")).apply(");\r
- for(int i=n;i<k;++i) {\r
- if(i>n)\r
- p.print(", ");\r
- p.print("p" + i);\r
- }\r
- p.println(");");\r
- p.println(" } catch(ClassCastException e) {");\r
- p.println(" throw new CalledWithTooManyParameters();");\r
- p.println(" }");\r
- p.println(" }");\r
- p.println();\r
- }\r
- p.println(" @Override");\r
- p.println(" public Object applyArray(Object ... ps) {");\r
- p.println(" switch(ps.length) {");\r
- for(int k=0;k<=MAX_ARITY+n;++k) {\r
- p.println(" case " + k + ":");\r
- if(k==0)\r
- p.println(" return this;");\r
- else if(k < n) {\r
- p.print(" return new UnsaturatedFunction" + k + "(this");\r
- for(int i=0;i<k;++i)\r
- p.print(", ps[" + i + "]");\r
- p.println(");");\r
- }\r
- else if(k == n) {\r
- p.print(" return apply(");\r
- for(int i=0;i<k;++i) {\r
- if(i > 0)\r
- p.print(", ");\r
- p.print("(P"+i+")ps[" + i + "]");\r
- }\r
- p.println(");");\r
- }\r
- else if(k <= n + MAX_ARITY) {\r
- p.println(" try {");\r
- p.print(" return ((Function)apply(");\r
- for(int i=0;i<n;++i) {\r
- if(i>0)\r
- p.print(", ");\r
- p.print("(P"+i+")ps[" + i + "]");\r
- }\r
- p.print(")).apply(");\r
- for(int i=n;i<k;++i) {\r
- if(i>n)\r
- p.print(", ");\r
- p.print("ps[" + i + "]");\r
- }\r
- p.println(");");\r
- p.println(" } catch(ClassCastException e) {");\r
- p.println(" throw new CalledWithTooManyParameters();");\r
- p.println(" }");\r
- }\r
- }\r
- {\r
- p.println(" default:");\r
- p.println(" try {");\r
- p.print(" return ((Function)apply(");\r
- for(int i=0;i<n;++i) {\r
- if(i>0)\r
- p.print(", ");\r
- p.print("(P"+i+")ps[" + i + "]");\r
- }\r
- p.println(")).apply(Arrays.copyOfRange(ps, "+n+", ps.length));");\r
- p.println(" } catch(ClassCastException e) {");\r
- p.println(" throw new CalledWithTooManyParameters();");\r
- p.println(" }");\r
- }\r
- p.println(" }");\r
- p.println(" }");\r
- p.println("}");\r
- }\r
- \r
- public static void generateFunctionImplN(PrintStream p) {\r
- p.println(HEADER);\r
- p.println("package " + PACKAGE + ";");\r
- p.println();\r
- p.println("import java.util.Arrays;");\r
- p.println();\r
- p.println("@SuppressWarnings(\"all\")");\r
- p.println("public abstract class FunctionImplN implements Function {");\r
- p.println(" int arity;");\r
- p.println();\r
- p.println(" public FunctionImplN(int arity) {");\r
- p.println(" if(arity < 1)");\r
- p.println(" throw new IllegalArgumentException();");\r
- p.println(" this.arity = arity;");\r
- p.println(" }");\r
- p.println();\r
- for(int k=1;k<=MAX_ARITY;++k) {\r
- p.println(" @Override");\r
- p.print(" public Object apply(");\r
- for(int i=0;i<k;++i) {\r
- if(i>0)\r
- p.print(", ");\r
- p.print("Object p" + i);\r
- }\r
- p.println(") {");\r
- p.println(" try {");\r
- p.println(" switch(arity) {");\r
- for(int i=1;i<k;++i) {\r
- p.print(" case " + i + ": return ((Function)doApply(");\r
- for(int j=0;j<i;++j) {\r
- if(j>0)\r
- p.print(", ");\r
- p.print("p" + j);\r
- }\r
- p.print(")).apply(");\r
- for(int j=i;j<k;++j) {\r
- if(j>i)\r
- p.print(", ");\r
- p.print("p" + j);\r
- }\r
- p.println(");");\r
- }\r
- p.print(" case " + k + ": return doApply(");\r
- for(int i=0;i<k;++i) {\r
- if(i>0)\r
- p.print(", ");\r
- p.print("p" + i);\r
- }\r
- p.println(");");\r
- p.print(" default: return new UnsaturatedFunction" + k + "(this");\r
- for(int i=0;i<k;++i)\r
- p.print(", p" + i);\r
- p.println(");");\r
- p.println(" }");\r
- p.println(" } catch(ClassCastException e) {");\r
- p.println(" throw new CalledWithTooManyParameters();");\r
- p.println(" }");\r
- p.println(" }");\r
- p.println();\r
- }\r
- p.println(" public abstract Object doApply(Object ... ps);");\r
- p.println();\r
- p.println(" @Override");\r
- p.println(" public Object applyArray(Object ... ps) {");\r
- p.println(" if(ps.length == arity)");\r
- p.println(" return doApply(ps);");\r
- p.println(" else if(ps.length < arity)");\r
- p.println(" return new UnsaturatedFunctionN(this, ps);");\r
- p.println(" else /* ps.length > arity */ {");\r
- p.println(" try {");\r
- p.println(" return ((Function)doApply(Arrays.copyOf(ps, arity))).applyArray(Arrays.copyOfRange(ps, arity, ps.length));");\r
- p.println(" } catch(ClassCastException e) {");\r
- p.println(" throw new CalledWithTooManyParameters();");\r
- p.println(" }");\r
- p.println(" }");\r
- p.println(" }");\r
- p.println("}");\r
- }\r
- \r
- public static void generateUnsaturatedFunctionN(PrintStream p, int n) {\r
- p.println(HEADER);\r
- p.println("package " + PACKAGE + ";");\r
- p.println();\r
- p.println("@SuppressWarnings(\"all\")");\r
- p.println("public class UnsaturatedFunction" + n + " implements Function {");\r
- p.println(" private final Function f;");\r
- for(int i=0;i<n;++i)\r
- p.println(" private final Object p" + i + ";");\r
- p.println();\r
- p.print(" public UnsaturatedFunction" + n + "(Function f");\r
- for(int i=0;i<n;++i)\r
- p.print(", Object p" + i);\r
- p.println(") {");\r
- p.println(" this.f = f;");\r
- for(int i=0;i<n;++i)\r
- p.println(" this.p" + i + " = p" + i + ";");\r
- p.println(" }");\r
- p.println();\r
- for(int k=1;k<=MAX_ARITY;++k) {\r
- p.println(" @Override");\r
- p.print(" public Object apply(");\r
- for(int i=0;i<k;++i) {\r
- if(i>0)\r
- p.print(", ");\r
- p.print("Object p" + (i + n));\r
- }\r
- p.println(") {");\r
- if(n + k <= MAX_ARITY)\r
- p.print(" return f.apply(");\r
- else\r
- p.print(" return f.applyArray(");\r
- for(int i=0;i<k+n;++i) {\r
- if(i>0)\r
- p.print(", ");\r
- p.print("p" + i);\r
- }\r
- p.println(");");\r
- p.println(" }");\r
- p.println();\r
- }\r
- {\r
- p.println(" @Override");\r
- p.println(" public Object applyArray(Object ... ps) {"); \r
- p.println(" Object[] nps = new Object[ps.length + " + n + "];");\r
- for(int i=0;i<n;++i)\r
- p.println(" nps[" + i + "] = p" + i + ";");\r
- p.println(" for(int i=0;i<ps.length;++i)");\r
- p.println(" nps[i + " + n + "] = ps[i];");\r
- p.println(" return f.applyArray(nps);");\r
- p.println(" }");\r
- }\r
- {\r
- p.println(" @Override");\r
- p.println(" public String toString() {");\r
- p.println(" StringBuilder sb = new StringBuilder();");\r
- p.println(" sb.append(\"(\").append(f);");\r
- for(int i=0;i<n;++i)\r
- p.println(" sb.append(\" \").append(p"+i+");");\r
- p.println(" sb.append(\")\");");\r
- p.println(" return sb.toString();");\r
- p.println(" }");\r
- }\r
- p.println("}");\r
- }\r
- \r
- public static void generateUnsaturatedFunctionN(PrintStream p) {\r
- p.println(HEADER);\r
- p.println("package " + PACKAGE + ";");\r
- p.println();\r
- p.println("@SuppressWarnings(\"all\")");\r
- p.println("public class UnsaturatedFunctionN implements Function {");\r
- p.println(" private final Function f;");\r
- p.println(" private final Object[] ps;");\r
- p.println();\r
- p.println(" public UnsaturatedFunctionN(Function f, Object ... ps) {");\r
- p.println(" this.f = f;");\r
- p.println(" this.ps = ps;");\r
- p.println(" }");\r
- p.println();\r
- for(int k=1;k<=MAX_ARITY;++k) {\r
- p.println(" @Override");\r
- p.print(" public Object apply(");\r
- for(int i=1;i<=k;++i) {\r
- if(i>1)\r
- p.print(", ");\r
- p.print("Object p" + i);\r
- }\r
- p.println(") {");\r
- p.println(" Object[] nps = new Object[ps.length + " + k + "];");\r
- p.println(" System.arraycopy(ps, 0, nps, 0, ps.length);");\r
- for(int i=1;i<=k;++i)\r
- p.println(" nps[ps.length+" + (i-1) + "] = p" + i+ ";");\r
- p.println(" return f.applyArray(nps);");\r
- p.println(" }");\r
- p.println();\r
- }\r
- {\r
- p.println(" @Override");\r
- p.println(" public Object applyArray(Object ... ops) {");\r
- p.println(" Object[] nps = new Object[ps.length + ops.length];");\r
- p.println(" System.arraycopy(ps, 0, nps, 0, ps.length);");\r
- p.println(" System.arraycopy(ops, 0, nps, ps.length, ops.length);");\r
- p.println(" return f.applyArray(nps);");\r
- p.println(" }");\r
- }\r
- {\r
- p.println(" @Override");\r
- p.println(" public String toString() {");\r
- p.println(" StringBuilder sb = new StringBuilder();");\r
- p.println(" sb.append(\"(\").append(f);");\r
- p.println(" for (Object p : ps)");\r
- p.println(" sb.append(\" \").append(p);");\r
- p.println(" sb.append(\")\");");\r
- p.println(" return sb.toString();");\r
- p.println(" }");\r
- }\r
- p.println("}");\r
- }\r
- \r
- public static void main(String[] args) throws Exception {\r
- URL url = GenerateFunctions.class.getResource(".");\r
- File dir = new File(url.getPath());\r
- while(!new File(dir, "src").exists())\r
- dir = dir.getParentFile(); \r
- dir = new File(dir, "src");\r
- dir = new File(dir, PACKAGE.replace('.', '/'));\r
- dir.mkdirs();\r
- \r
- for(int n=1;n<=MAX_ARITY;++n) {\r
- PrintStream ps = \r
- new PrintStream(new FileOutputStream(new File(dir, "Function"+n+".java")));\r
- generateFunctionN(ps, n);\r
- }\r
- {\r
- PrintStream ps = \r
- new PrintStream(new FileOutputStream(new File(dir, "FunctionN.java")));\r
- generateFunctionN(ps);\r
- }\r
- {\r
- PrintStream ps = \r
- new PrintStream(new FileOutputStream(new File(dir, "Function.java")));\r
- generateFunction(ps);\r
- }\r
- \r
- for(int n=1;n<=MAX_ARITY;++n) {\r
- PrintStream ps = \r
- new PrintStream(new FileOutputStream(new File(dir, "FunctionImpl"+n+".java")));\r
- generateFunctionImplN(ps, n);\r
- }\r
- {\r
- PrintStream ps = \r
- new PrintStream(new FileOutputStream(new File(dir, "FunctionImplN.java")));\r
- generateFunctionImplN(ps);\r
- }\r
- for(int n=1;n<=MAX_ARITY;++n) {\r
- PrintStream ps = \r
- new PrintStream(new FileOutputStream(new File(dir, "UnsaturatedFunction"+n+".java")));\r
- generateUnsaturatedFunctionN(ps, n);\r
- }\r
- {\r
- PrintStream ps = \r
- new PrintStream(new FileOutputStream(new File(dir, "UnsaturatedFunctionN.java")));\r
- generateUnsaturatedFunctionN(ps);\r
- }\r
- } \r
-}\r
+package org.simantics.scl.runtime.generation;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.net.URL;
+
+public class GenerateFunctions {
+
+ public static final String PACKAGE = "org.simantics.scl.runtime.function";
+ public static final int MAX_ARITY = 8;
+
+ public static final String HEADER =
+ "/**\r\n"
+ + " * This code is generated in " + GenerateFunctions.class.getName() + ".\r\n"
+ + " * Do not edit manually!\r\n"
+ + " */"
+ ;
+
+ public static void generateFunctionN(PrintStream p, int n) {
+ p.println(HEADER);
+ p.println("package " + PACKAGE + ";");
+ p.println();
+ p.print("public interface Function"+n+"<");
+ for(int i=0;i<n;++i)
+ p.print("P" + i + ",");
+ p.println("R> {");
+ p.print(" R apply(");
+ for(int i=0;i<n;++i) {
+ if(i>0)
+ p.print(", ");
+ p.print("P"+i+" p" + i);
+ }
+ p.println(");");
+ p.println("}");
+ }
+
+ public static void generateFunctionN(PrintStream p) {
+ p.println(HEADER);
+ p.println("package " + PACKAGE + ";");
+ p.println();
+ p.println("public interface FunctionN {");
+ p.println(" Object applyArray(Object ... ps);");
+ p.println("}");
+ }
+
+ public static void generateFunction(PrintStream p) {
+ p.println(HEADER);
+ p.println("package " + PACKAGE + ";");
+ p.println();
+ //p.println("@SuppressWarnings(\"all\")");
+ p.print("public interface Function<");
+ for(int k=0;k<MAX_ARITY;++k) {
+ p.print("P"+k+",");
+ }
+ for(int k=1;k<=MAX_ARITY;++k) {
+ p.print("R"+k);
+ if(k < MAX_ARITY)
+ p.print(",");
+ }
+ p.println("> extends");
+ for(int k=1;k<=MAX_ARITY;++k) {
+ p.print(" Function" + k + "<");
+ for(int i=0;i<k;++i) {
+ p.print("P"+i+",");
+ }
+ p.println("R"+k+">,");
+ }
+ p.println(" FunctionN {");
+ p.println("}");
+ }
+
+ public static void generateFunctionImplN(PrintStream p, int n) {
+ p.println(HEADER);
+ p.println("package " + PACKAGE + ";");
+ p.println();
+ p.println("import java.util.Arrays;");
+ p.println();
+ p.println("@SuppressWarnings(\"all\")");
+ p.print("public abstract class FunctionImpl" + n + "<");
+ for(int i=0;i<n;++i)
+ p.print("P" + i + ",");
+ p.print("R> implements Function<");
+ for(int i=0;i<n;++i)
+ p.print("P" + i + ",");
+ for(int i=n;i<MAX_ARITY;++i)
+ p.print("Object,");
+ for(int i=1;i<=MAX_ARITY;++i) {
+ if(i == n)
+ p.print("R");
+ else
+ p.print("Object");
+ if(i < MAX_ARITY)
+ p.print(",");
+ }
+ p.println("> {");
+ for(int k=1;k<Math.min(n, MAX_ARITY+1);++k) {
+ p.println(" @Override");
+ p.print(" public Object apply(");
+ for(int i=0;i<k;++i) {
+ if(i>0)
+ p.print(", ");
+ p.print("Object p" + i);
+ }
+ p.println(") {");
+ p.print(" return new UnsaturatedFunction" + k + "(this");
+ for(int i=0;i<k;++i)
+ p.print(", p" + i);
+ p.println(");");
+ p.println(" }");
+ p.println();
+ }
+ {
+ if(n <= MAX_ARITY)
+ p.println(" @Override");
+ p.print(" public abstract R apply(");
+ for(int i=0;i<n;++i) {
+ if(i>0)
+ p.print(", ");
+ p.print("P"+i+" p" + i);
+ }
+ p.println(");");
+ p.println();
+ }
+ for(int k=n+1;k<=MAX_ARITY;++k) {
+ p.println(" @Override");
+ p.print(" public Object apply(");
+ for(int i=0;i<k;++i) {
+ if(i>0)
+ p.print(", ");
+ p.print("Object p" + i);
+ }
+ p.println(") {");
+ p.println(" try {");
+ p.print(" return ((Function)apply(");
+ for(int i=0;i<n;++i) {
+ if(i>0)
+ p.print(", ");
+ p.print("(P"+i+")p" + i);
+ }
+ p.print(")).apply(");
+ for(int i=n;i<k;++i) {
+ if(i>n)
+ p.print(", ");
+ p.print("p" + i);
+ }
+ p.println(");");
+ p.println(" } catch(ClassCastException e) {");
+ p.println(" throw new CalledWithTooManyParameters();");
+ p.println(" }");
+ p.println(" }");
+ p.println();
+ }
+ p.println(" @Override");
+ p.println(" public Object applyArray(Object ... ps) {");
+ p.println(" switch(ps.length) {");
+ for(int k=0;k<=MAX_ARITY+n;++k) {
+ p.println(" case " + k + ":");
+ if(k==0)
+ p.println(" return this;");
+ else if(k < n) {
+ p.print(" return new UnsaturatedFunction" + k + "(this");
+ for(int i=0;i<k;++i)
+ p.print(", ps[" + i + "]");
+ p.println(");");
+ }
+ else if(k == n) {
+ p.print(" return apply(");
+ for(int i=0;i<k;++i) {
+ if(i > 0)
+ p.print(", ");
+ p.print("(P"+i+")ps[" + i + "]");
+ }
+ p.println(");");
+ }
+ else if(k <= n + MAX_ARITY) {
+ p.println(" try {");
+ p.print(" return ((Function)apply(");
+ for(int i=0;i<n;++i) {
+ if(i>0)
+ p.print(", ");
+ p.print("(P"+i+")ps[" + i + "]");
+ }
+ p.print(")).apply(");
+ for(int i=n;i<k;++i) {
+ if(i>n)
+ p.print(", ");
+ p.print("ps[" + i + "]");
+ }
+ p.println(");");
+ p.println(" } catch(ClassCastException e) {");
+ p.println(" throw new CalledWithTooManyParameters();");
+ p.println(" }");
+ }
+ }
+ {
+ p.println(" default:");
+ p.println(" try {");
+ p.print(" return ((Function)apply(");
+ for(int i=0;i<n;++i) {
+ if(i>0)
+ p.print(", ");
+ p.print("(P"+i+")ps[" + i + "]");
+ }
+ p.println(")).apply(Arrays.copyOfRange(ps, "+n+", ps.length));");
+ p.println(" } catch(ClassCastException e) {");
+ p.println(" throw new CalledWithTooManyParameters();");
+ p.println(" }");
+ }
+ p.println(" }");
+ p.println(" }");
+ p.println("}");
+ }
+
+ public static void generateFunctionImplN(PrintStream p) {
+ p.println(HEADER);
+ p.println("package " + PACKAGE + ";");
+ p.println();
+ p.println("import java.util.Arrays;");
+ p.println();
+ p.println("@SuppressWarnings(\"all\")");
+ p.println("public abstract class FunctionImplN implements Function {");
+ p.println(" int arity;");
+ p.println();
+ p.println(" public FunctionImplN(int arity) {");
+ p.println(" if(arity < 1)");
+ p.println(" throw new IllegalArgumentException();");
+ p.println(" this.arity = arity;");
+ p.println(" }");
+ p.println();
+ for(int k=1;k<=MAX_ARITY;++k) {
+ p.println(" @Override");
+ p.print(" public Object apply(");
+ for(int i=0;i<k;++i) {
+ if(i>0)
+ p.print(", ");
+ p.print("Object p" + i);
+ }
+ p.println(") {");
+ p.println(" try {");
+ p.println(" switch(arity) {");
+ for(int i=1;i<k;++i) {
+ p.print(" case " + i + ": return ((Function)doApply(");
+ for(int j=0;j<i;++j) {
+ if(j>0)
+ p.print(", ");
+ p.print("p" + j);
+ }
+ p.print(")).apply(");
+ for(int j=i;j<k;++j) {
+ if(j>i)
+ p.print(", ");
+ p.print("p" + j);
+ }
+ p.println(");");
+ }
+ p.print(" case " + k + ": return doApply(");
+ for(int i=0;i<k;++i) {
+ if(i>0)
+ p.print(", ");
+ p.print("p" + i);
+ }
+ p.println(");");
+ p.print(" default: return new UnsaturatedFunction" + k + "(this");
+ for(int i=0;i<k;++i)
+ p.print(", p" + i);
+ p.println(");");
+ p.println(" }");
+ p.println(" } catch(ClassCastException e) {");
+ p.println(" throw new CalledWithTooManyParameters();");
+ p.println(" }");
+ p.println(" }");
+ p.println();
+ }
+ p.println(" public abstract Object doApply(Object ... ps);");
+ p.println();
+ p.println(" @Override");
+ p.println(" public Object applyArray(Object ... ps) {");
+ p.println(" if(ps.length == arity)");
+ p.println(" return doApply(ps);");
+ p.println(" else if(ps.length < arity)");
+ p.println(" return new UnsaturatedFunctionN(this, ps);");
+ p.println(" else /* ps.length > arity */ {");
+ p.println(" try {");
+ p.println(" return ((Function)doApply(Arrays.copyOf(ps, arity))).applyArray(Arrays.copyOfRange(ps, arity, ps.length));");
+ p.println(" } catch(ClassCastException e) {");
+ p.println(" throw new CalledWithTooManyParameters();");
+ p.println(" }");
+ p.println(" }");
+ p.println(" }");
+ p.println("}");
+ }
+
+ public static void generateUnsaturatedFunctionN(PrintStream p, int n) {
+ p.println(HEADER);
+ p.println("package " + PACKAGE + ";");
+ p.println();
+ p.println("@SuppressWarnings(\"all\")");
+ p.println("public class UnsaturatedFunction" + n + " implements Function {");
+ p.println(" private final Function f;");
+ for(int i=0;i<n;++i)
+ p.println(" private final Object p" + i + ";");
+ p.println();
+ p.print(" public UnsaturatedFunction" + n + "(Function f");
+ for(int i=0;i<n;++i)
+ p.print(", Object p" + i);
+ p.println(") {");
+ p.println(" this.f = f;");
+ for(int i=0;i<n;++i)
+ p.println(" this.p" + i + " = p" + i + ";");
+ p.println(" }");
+ p.println();
+ for(int k=1;k<=MAX_ARITY;++k) {
+ p.println(" @Override");
+ p.print(" public Object apply(");
+ for(int i=0;i<k;++i) {
+ if(i>0)
+ p.print(", ");
+ p.print("Object p" + (i + n));
+ }
+ p.println(") {");
+ if(n + k <= MAX_ARITY)
+ p.print(" return f.apply(");
+ else
+ p.print(" return f.applyArray(");
+ for(int i=0;i<k+n;++i) {
+ if(i>0)
+ p.print(", ");
+ p.print("p" + i);
+ }
+ p.println(");");
+ p.println(" }");
+ p.println();
+ }
+ {
+ p.println(" @Override");
+ p.println(" public Object applyArray(Object ... ps) {");
+ p.println(" Object[] nps = new Object[ps.length + " + n + "];");
+ for(int i=0;i<n;++i)
+ p.println(" nps[" + i + "] = p" + i + ";");
+ p.println(" for(int i=0;i<ps.length;++i)");
+ p.println(" nps[i + " + n + "] = ps[i];");
+ p.println(" return f.applyArray(nps);");
+ p.println(" }");
+ p.println();
+ }
+ {
+ p.println(" @Override");
+ p.println(" public String toString() {");
+ p.println(" StringBuilder sb = new StringBuilder();");
+ p.println(" sb.append(\"(\").append(f);");
+ for(int i=0;i<n;++i)
+ p.println(" sb.append(\" \").append(p"+i+");");
+ 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("}");
+ }
+
+ public static void generateUnsaturatedFunctionN(PrintStream p) {
+ 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(" private final Object[] ps;");
+ p.println();
+ p.println(" public UnsaturatedFunctionN(Function f, Object ... ps) {");
+ p.println(" this.f = f;");
+ p.println(" this.ps = ps;");
+ p.println(" }");
+ p.println();
+ for(int k=1;k<=MAX_ARITY;++k) {
+ p.println(" @Override");
+ p.print(" public Object apply(");
+ for(int i=1;i<=k;++i) {
+ if(i>1)
+ p.print(", ");
+ p.print("Object p" + i);
+ }
+ p.println(") {");
+ p.println(" Object[] nps = new Object[ps.length + " + k + "];");
+ p.println(" System.arraycopy(ps, 0, nps, 0, ps.length);");
+ for(int i=1;i<=k;++i)
+ p.println(" nps[ps.length+" + (i-1) + "] = p" + i+ ";");
+ p.println(" return f.applyArray(nps);");
+ p.println(" }");
+ p.println();
+ }
+ {
+ p.println(" @Override");
+ p.println(" public Object applyArray(Object ... ops) {");
+ p.println(" Object[] nps = new Object[ps.length + ops.length];");
+ p.println(" System.arraycopy(ps, 0, nps, 0, ps.length);");
+ 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(" public String toString() {");
+ p.println(" StringBuilder sb = new StringBuilder();");
+ p.println(" sb.append(\"(\").append(f);");
+ p.println(" for (Object p : ps)");
+ p.println(" sb.append(\" \").append(p);");
+ 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 void main(String[] args) throws Exception {
+ URL url = GenerateFunctions.class.getResource(".");
+ File dir = new File(url.getPath());
+ while(!new File(dir, "src").exists())
+ dir = dir.getParentFile();
+ dir = new File(dir, "src");
+ dir = new File(dir, PACKAGE.replace('.', '/'));
+ dir.mkdirs();
+
+ for(int n=1;n<=MAX_ARITY;++n) {
+ PrintStream ps =
+ new PrintStream(new FileOutputStream(new File(dir, "Function"+n+".java")));
+ generateFunctionN(ps, n);
+ }
+ {
+ PrintStream ps =
+ new PrintStream(new FileOutputStream(new File(dir, "FunctionN.java")));
+ generateFunctionN(ps);
+ }
+ {
+ PrintStream ps =
+ new PrintStream(new FileOutputStream(new File(dir, "Function.java")));
+ generateFunction(ps);
+ }
+
+ for(int n=1;n<=MAX_ARITY;++n) {
+ PrintStream ps =
+ new PrintStream(new FileOutputStream(new File(dir, "FunctionImpl"+n+".java")));
+ generateFunctionImplN(ps, n);
+ }
+ {
+ PrintStream ps =
+ new PrintStream(new FileOutputStream(new File(dir, "FunctionImplN.java")));
+ generateFunctionImplN(ps);
+ }
+ for(int n=1;n<=MAX_ARITY;++n) {
+ PrintStream ps =
+ new PrintStream(new FileOutputStream(new File(dir, "UnsaturatedFunction"+n+".java")));
+ generateUnsaturatedFunctionN(ps, n);
+ }
+ {
+ PrintStream ps =
+ new PrintStream(new FileOutputStream(new File(dir, "UnsaturatedFunctionN.java")));
+ generateUnsaturatedFunctionN(ps);
+ }
+ }
+}