1 package org.simantics.scl.runtime.generation;
4 import java.io.FileOutputStream;
5 import java.io.PrintStream;
8 public class GenerateFunctions {
10 public static final String PACKAGE = "org.simantics.scl.runtime.function";
11 public static final int MAX_ARITY = 8;
13 public static final String HEADER =
15 + " * This code is generated in " + GenerateFunctions.class.getName() + ".\n"
16 + " * Do not edit manually!\n"
20 public static void generateFunctionN(PrintStream p, int n) {
22 p.println("package " + PACKAGE + ";");
24 p.print("public interface Function"+n+"<");
26 p.print("P" + i + ",");
29 for(int i=0;i<n;++i) {
32 p.print("P"+i+" p" + i);
38 public static void generateFunctionN(PrintStream p) {
40 p.println("package " + PACKAGE + ";");
42 p.println("public interface FunctionN {");
43 p.println(" Object applyArray(Object ... ps);");
47 public static void generateFunction(PrintStream p) {
49 p.println("package " + PACKAGE + ";");
51 //p.println("@SuppressWarnings(\"all\")");
52 p.print("public interface Function<");
53 for(int k=0;k<MAX_ARITY;++k) {
56 for(int k=1;k<=MAX_ARITY;++k) {
61 p.println("> extends");
62 for(int k=1;k<=MAX_ARITY;++k) {
63 p.print(" Function" + k + "<");
64 for(int i=0;i<k;++i) {
67 p.println("R"+k+">,");
69 p.println(" FunctionN {");
73 public static void generateFunctionImplN(PrintStream p, int n) {
75 p.println("package " + PACKAGE + ";");
77 p.println("import java.util.Arrays;");
79 p.println("@SuppressWarnings(\"all\")");
80 p.print("public abstract class FunctionImpl" + n + "<");
82 p.print("P" + i + ",");
83 p.print("R> implements Function<");
85 p.print("P" + i + ",");
86 for(int i=n;i<MAX_ARITY;++i)
88 for(int i=1;i<=MAX_ARITY;++i) {
97 for(int k=1;k<Math.min(n, MAX_ARITY+1);++k) {
98 p.println(" @Override");
99 p.print(" public Object apply(");
100 for(int i=0;i<k;++i) {
103 p.print("Object p" + i);
106 p.print(" return new UnsaturatedFunction" + k + "(this");
115 p.println(" @Override");
116 p.print(" public abstract R apply(");
117 for(int i=0;i<n;++i) {
120 p.print("P"+i+" p" + i);
125 for(int k=n+1;k<=MAX_ARITY;++k) {
126 p.println(" @Override");
127 p.print(" public Object apply(");
128 for(int i=0;i<k;++i) {
131 p.print("Object p" + i);
135 p.print(" return ((Function)apply(");
136 for(int i=0;i<n;++i) {
139 p.print("(P"+i+")p" + i);
141 p.print(")).apply(");
142 for(int i=n;i<k;++i) {
148 p.println(" } catch(ClassCastException e) {");
149 p.println(" throw new CalledWithTooManyParameters();");
154 p.println(" @Override");
155 p.println(" public Object applyArray(Object ... ps) {");
156 p.println(" switch(ps.length) {");
157 for(int k=0;k<=MAX_ARITY+n;++k) {
158 p.println(" case " + k + ":");
160 p.println(" return this;");
162 p.print(" return new UnsaturatedFunction" + k + "(this");
164 p.print(", ps[" + i + "]");
168 p.print(" return apply(");
169 for(int i=0;i<k;++i) {
172 p.print("(P"+i+")ps[" + i + "]");
176 else if(k <= n + MAX_ARITY) {
178 p.print(" return ((Function)apply(");
179 for(int i=0;i<n;++i) {
182 p.print("(P"+i+")ps[" + i + "]");
184 p.print(")).apply(");
185 for(int i=n;i<k;++i) {
188 p.print("ps[" + i + "]");
191 p.println(" } catch(ClassCastException e) {");
192 p.println(" throw new CalledWithTooManyParameters();");
197 p.println(" default:");
199 p.print(" return ((Function)apply(");
200 for(int i=0;i<n;++i) {
203 p.print("(P"+i+")ps[" + i + "]");
205 p.println(")).apply(Arrays.copyOfRange(ps, "+n+", ps.length));");
206 p.println(" } catch(ClassCastException e) {");
207 p.println(" throw new CalledWithTooManyParameters();");
215 public static void generateFunctionImplN(PrintStream p) {
217 p.println("package " + PACKAGE + ";");
219 p.println("import java.util.Arrays;");
221 p.println("@SuppressWarnings(\"all\")");
222 p.println("public abstract class FunctionImplN implements Function {");
223 p.println(" int arity;");
225 p.println(" public FunctionImplN(int arity) {");
226 p.println(" if(arity < 1)");
227 p.println(" throw new IllegalArgumentException();");
228 p.println(" this.arity = arity;");
231 for(int k=1;k<=MAX_ARITY;++k) {
232 p.println(" @Override");
233 p.print(" public Object apply(");
234 for(int i=0;i<k;++i) {
237 p.print("Object p" + i);
241 p.println(" switch(arity) {");
242 for(int i=1;i<k;++i) {
243 p.print(" case " + i + ": return ((Function)doApply(");
244 for(int j=0;j<i;++j) {
249 p.print(")).apply(");
250 for(int j=i;j<k;++j) {
257 p.print(" case " + k + ": return doApply(");
258 for(int i=0;i<k;++i) {
264 p.print(" default: return new UnsaturatedFunction" + k + "(this");
269 p.println(" } catch(ClassCastException e) {");
270 p.println(" throw new CalledWithTooManyParameters();");
275 p.println(" public abstract Object doApply(Object ... ps);");
277 p.println(" @Override");
278 p.println(" public Object applyArray(Object ... ps) {");
279 p.println(" if(ps.length == arity)");
280 p.println(" return doApply(ps);");
281 p.println(" else if(ps.length < arity)");
282 p.println(" return new UnsaturatedFunctionN(this, ps);");
283 p.println(" else /* ps.length > arity */ {");
285 p.println(" return ((Function)doApply(Arrays.copyOf(ps, arity))).applyArray(Arrays.copyOfRange(ps, arity, ps.length));");
286 p.println(" } catch(ClassCastException e) {");
287 p.println(" throw new CalledWithTooManyParameters();");
294 public static void generateUnsaturatedFunctionN(PrintStream p, int n) {
296 p.println("package " + PACKAGE + ";");
298 p.println("@SuppressWarnings(\"all\")");
299 p.println("public class UnsaturatedFunction" + n + " implements Function {");
300 p.println(" private final Function f;");
302 p.println(" private final Object p" + i + ";");
304 p.print(" public UnsaturatedFunction" + n + "(Function f");
306 p.print(", Object p" + i);
308 p.println(" this.f = f;");
310 p.println(" this.p" + i + " = p" + i + ";");
313 for(int k=1;k<=MAX_ARITY;++k) {
314 p.println(" @Override");
315 p.print(" public Object apply(");
316 for(int i=0;i<k;++i) {
319 p.print("Object p" + (i + n));
322 if(n + k <= MAX_ARITY)
323 p.print(" return f.apply(");
325 p.print(" return f.applyArray(");
326 for(int i=0;i<k+n;++i) {
336 p.println(" @Override");
337 p.println(" public Object applyArray(Object ... ps) {");
338 p.println(" Object[] nps = new Object[ps.length + " + n + "];");
340 p.println(" nps[" + i + "] = p" + i + ";");
341 p.println(" for(int i=0;i<ps.length;++i)");
342 p.println(" nps[i + " + n + "] = ps[i];");
343 p.println(" return f.applyArray(nps);");
347 p.println(" @Override");
348 p.println(" public String toString() {");
349 p.println(" StringBuilder sb = new StringBuilder();");
350 p.println(" sb.append(\"(\").append(f);");
352 p.println(" sb.append(\" \").append(p"+i+");");
353 p.println(" sb.append(\")\");");
354 p.println(" return sb.toString();");
360 public static void generateUnsaturatedFunctionN(PrintStream p) {
362 p.println("package " + PACKAGE + ";");
364 p.println("@SuppressWarnings(\"all\")");
365 p.println("public class UnsaturatedFunctionN implements Function {");
366 p.println(" private final Function f;");
367 p.println(" private final Object[] ps;");
369 p.println(" public UnsaturatedFunctionN(Function f, Object ... ps) {");
370 p.println(" this.f = f;");
371 p.println(" this.ps = ps;");
374 for(int k=1;k<=MAX_ARITY;++k) {
375 p.println(" @Override");
376 p.print(" public Object apply(");
377 for(int i=1;i<=k;++i) {
380 p.print("Object p" + i);
383 p.println(" Object[] nps = new Object[ps.length + " + k + "];");
384 p.println(" System.arraycopy(ps, 0, nps, 0, ps.length);");
385 for(int i=1;i<=k;++i)
386 p.println(" nps[ps.length+" + (i-1) + "] = p" + i+ ";");
387 p.println(" return f.applyArray(nps);");
392 p.println(" @Override");
393 p.println(" public Object applyArray(Object ... ops) {");
394 p.println(" Object[] nps = new Object[ps.length + ops.length];");
395 p.println(" System.arraycopy(ps, 0, nps, 0, ps.length);");
396 p.println(" System.arraycopy(ops, 0, nps, ps.length, ops.length);");
397 p.println(" return f.applyArray(nps);");
401 p.println(" @Override");
402 p.println(" public String toString() {");
403 p.println(" StringBuilder sb = new StringBuilder();");
404 p.println(" sb.append(\"(\").append(f);");
405 p.println(" for (Object p : ps)");
406 p.println(" sb.append(\" \").append(p);");
407 p.println(" sb.append(\")\");");
408 p.println(" return sb.toString();");
414 public static void main(String[] args) throws Exception {
415 URL url = GenerateFunctions.class.getResource(".");
416 File dir = new File(url.getPath());
417 while(!new File(dir, "src").exists())
418 dir = dir.getParentFile();
419 dir = new File(dir, "src");
420 dir = new File(dir, PACKAGE.replace('.', '/'));
423 for(int n=1;n<=MAX_ARITY;++n) {
425 new PrintStream(new FileOutputStream(new File(dir, "Function"+n+".java")));
426 generateFunctionN(ps, n);
430 new PrintStream(new FileOutputStream(new File(dir, "FunctionN.java")));
431 generateFunctionN(ps);
435 new PrintStream(new FileOutputStream(new File(dir, "Function.java")));
436 generateFunction(ps);
439 for(int n=1;n<=MAX_ARITY;++n) {
441 new PrintStream(new FileOutputStream(new File(dir, "FunctionImpl"+n+".java")));
442 generateFunctionImplN(ps, n);
446 new PrintStream(new FileOutputStream(new File(dir, "FunctionImplN.java")));
447 generateFunctionImplN(ps);
449 for(int n=1;n<=MAX_ARITY;++n) {
451 new PrintStream(new FileOutputStream(new File(dir, "UnsaturatedFunction"+n+".java")));
452 generateUnsaturatedFunctionN(ps, n);
456 new PrintStream(new FileOutputStream(new File(dir, "UnsaturatedFunctionN.java")));
457 generateUnsaturatedFunctionN(ps);