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 = "/**\n" + " * This code is generated in " + GenerateFunctions.class.getName() + ".\n" + " * Do not edit manually!\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 {"); p.print(" R apply("); for(int i=0;i0) 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 extends"); for(int k=1;k<=MAX_ARITY;++k) { p.print(" Function" + k + "<"); for(int i=0;i,"); } 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 implements Function<"); for(int i=0;i {"); for(int k=1;k0) p.print(", "); p.print("Object p" + i); } p.println(") {"); p.print(" return new UnsaturatedFunction" + k + "(this"); for(int i=0;i0) 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;i0) p.print(", "); p.print("Object p" + i); } p.println(") {"); p.println(" try {"); p.print(" return ((Function)apply("); for(int i=0;i0) p.print(", "); p.print("(P"+i+")p" + i); } p.print(")).apply("); for(int i=n;in) 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 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;i0) p.print(", "); p.print("(P"+i+")ps[" + i + "]"); } p.print(")).apply("); for(int i=n;in) 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;i0) 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;i0) p.print(", "); p.print("Object p" + i); } p.println(") {"); p.println(" try {"); p.println(" switch(arity) {"); for(int i=1;i0) p.print(", "); p.print("p" + j); } p.print(")).apply("); for(int j=i;ji) p.print(", "); p.print("p" + j); } p.println(");"); } p.print(" case " + k + ": return doApply("); for(int i=0;i0) p.print(", "); p.print("p" + i); } p.println(");"); p.print(" default: return new UnsaturatedFunction" + k + "(this"); for(int i=0;i 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;i0) 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;i0) 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;i1) 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(" @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("}"); } 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); } } }