]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.runtime/generation/org/simantics/scl/runtime/generation/GenerateFunctions.java
adf2dee305c3693064d1d2a5893888d589ab8087
[simantics/platform.git] / bundles / org.simantics.scl.runtime / generation / org / simantics / scl / runtime / generation / GenerateFunctions.java
1 package org.simantics.scl.runtime.generation;
2
3 import java.io.File;
4 import java.io.FileOutputStream;
5 import java.io.PrintStream;
6 import java.net.URL;
7
8 public class GenerateFunctions {
9     
10     public static final String PACKAGE = "org.simantics.scl.runtime.function";
11     public static final int MAX_ARITY = 8;
12     
13     public static final String HEADER =
14             "/**\n"
15           + " * This code is generated in " + GenerateFunctions.class.getName() + ".\n"
16           + " * Do not edit manually!\n"
17           + " */" 
18             ;
19     
20     public static void generateFunctionN(PrintStream p, int n) {
21         p.println(HEADER);
22         p.println("package " + PACKAGE + ";");
23         p.println();        
24         p.print("public interface Function"+n+"<");
25         for(int i=0;i<n;++i)
26             p.print("P" + i + ",");
27         p.println("R> {");
28         p.print("    R apply(");
29         for(int i=0;i<n;++i) {
30             if(i>0)
31                 p.print(", ");
32             p.print("P"+i+" p" + i);
33         }
34         p.println(");");
35         p.println("}");
36     }
37     
38     public static void generateFunctionN(PrintStream p) {
39         p.println(HEADER);
40         p.println("package " + PACKAGE + ";");
41         p.println();
42         p.println("public interface FunctionN {");
43         p.println("    Object applyArray(Object ... ps);");
44         p.println("}");
45     }
46     
47     public static void generateFunction(PrintStream p) {
48         p.println(HEADER);
49         p.println("package " + PACKAGE + ";");
50         p.println();
51         //p.println("@SuppressWarnings(\"all\")");
52         p.print("public interface Function<");
53         for(int k=0;k<MAX_ARITY;++k) {
54             p.print("P"+k+",");
55         }
56         for(int k=1;k<=MAX_ARITY;++k) {
57             p.print("R"+k);
58             if(k < MAX_ARITY)
59                 p.print(",");
60         }
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) {
65                 p.print("P"+i+",");
66             }
67             p.println("R"+k+">,");
68         }
69         p.println("    FunctionN {");
70         p.println("}");
71     }
72     
73     public static void generateFunctionImplN(PrintStream p, int n) {
74         p.println(HEADER);
75         p.println("package " + PACKAGE + ";");
76         p.println();
77         p.println("import java.util.Arrays;");
78         p.println();
79         p.println("@SuppressWarnings(\"all\")");
80         p.print("public abstract class FunctionImpl" + n + "<");
81         for(int i=0;i<n;++i)
82             p.print("P" + i + ",");
83         p.print("R> implements Function<");
84         for(int i=0;i<n;++i)
85             p.print("P" + i + ",");
86         for(int i=n;i<MAX_ARITY;++i)
87             p.print("Object,");
88         for(int i=1;i<=MAX_ARITY;++i) {
89             if(i == n)
90                 p.print("R");
91             else 
92                 p.print("Object");
93             if(i < MAX_ARITY)
94                 p.print(",");
95         }
96         p.println("> {");
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) {
101                 if(i>0)
102                     p.print(", ");
103                 p.print("Object p" + i);
104             }
105             p.println(") {");
106             p.print("        return new UnsaturatedFunction" + k + "(this");
107             for(int i=0;i<k;++i)
108                 p.print(", p" + i);
109             p.println(");");
110             p.println("    }");
111             p.println();
112         }
113         {
114             if(n <= MAX_ARITY)
115                 p.println("    @Override");
116             p.print("    public abstract R apply(");
117             for(int i=0;i<n;++i) {
118                 if(i>0)
119                     p.print(", ");
120                 p.print("P"+i+" p" + i);
121             }
122             p.println(");");
123             p.println();
124         }
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) {
129                 if(i>0)
130                     p.print(", ");
131                 p.print("Object p" + i);
132             }
133             p.println(") {");
134             p.println("        try {");
135             p.print("            return ((Function)apply(");
136             for(int i=0;i<n;++i) {
137                 if(i>0)
138                     p.print(", ");
139                 p.print("(P"+i+")p" + i);
140             }
141             p.print(")).apply(");
142             for(int i=n;i<k;++i) {
143                 if(i>n)
144                     p.print(", ");
145                 p.print("p" + i);
146             }
147             p.println(");");
148             p.println("        } catch(ClassCastException e) {");
149             p.println("            throw new CalledWithTooManyParameters();");
150             p.println("        }");
151             p.println("    }");
152             p.println();
153         }
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 + ":");
159             if(k==0)
160                 p.println("            return this;");
161             else if(k < n) {
162                 p.print("            return new UnsaturatedFunction" + k + "(this");
163                 for(int i=0;i<k;++i)
164                     p.print(", ps[" + i + "]");
165                 p.println(");");
166             }
167             else if(k == n) {
168                 p.print("            return apply(");
169                 for(int i=0;i<k;++i) {
170                     if(i > 0)
171                         p.print(", ");
172                     p.print("(P"+i+")ps[" + i + "]");
173                 }
174                 p.println(");");
175             }
176             else if(k <= n + MAX_ARITY) {
177                 p.println("            try {");
178                 p.print("                return ((Function)apply(");
179                 for(int i=0;i<n;++i) {
180                     if(i>0)
181                         p.print(", ");
182                     p.print("(P"+i+")ps[" + i + "]");
183                 }
184                 p.print(")).apply(");
185                 for(int i=n;i<k;++i) {
186                     if(i>n)
187                         p.print(", ");
188                     p.print("ps[" + i + "]");
189                 }
190                 p.println(");");
191                 p.println("            } catch(ClassCastException e) {");
192                 p.println("                throw new CalledWithTooManyParameters();");
193                 p.println("            }");
194             }
195         }
196         {
197             p.println("        default:");
198             p.println("            try {");
199             p.print("                return ((Function)apply(");
200             for(int i=0;i<n;++i) {
201                 if(i>0)
202                     p.print(", ");
203                 p.print("(P"+i+")ps[" + i + "]");
204             }
205             p.println(")).apply(Arrays.copyOfRange(ps, "+n+", ps.length));");
206             p.println("            } catch(ClassCastException e) {");
207             p.println("                throw new CalledWithTooManyParameters();");
208             p.println("            }");
209         }
210         p.println("        }");
211         p.println("    }");
212         p.println("}");
213     }
214     
215     public static void generateFunctionImplN(PrintStream p) {
216         p.println(HEADER);
217         p.println("package " + PACKAGE + ";");
218         p.println();
219         p.println("import java.util.Arrays;");
220         p.println();
221         p.println("@SuppressWarnings(\"all\")");
222         p.println("public abstract class FunctionImplN implements Function {");
223         p.println("    int arity;");
224         p.println();
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;");
229         p.println("    }");
230         p.println();
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) {
235                 if(i>0)
236                     p.print(", ");
237                 p.print("Object p" + i);
238             }
239             p.println(") {");
240             p.println("        try {");
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) {
245                     if(j>0)
246                         p.print(", ");
247                     p.print("p" + j);
248                 }
249                 p.print(")).apply(");
250                 for(int j=i;j<k;++j) {
251                     if(j>i)
252                         p.print(", ");
253                     p.print("p" + j);
254                 }
255                 p.println(");");
256             }
257             p.print("            case " + k + ": return doApply(");
258             for(int i=0;i<k;++i) {
259                 if(i>0)
260                     p.print(", ");
261                 p.print("p" + i);
262             }
263             p.println(");");
264             p.print("            default: return new UnsaturatedFunction" + k + "(this");
265             for(int i=0;i<k;++i)
266                 p.print(", p" + i);
267             p.println(");");
268             p.println("            }");
269             p.println("        } catch(ClassCastException e) {");
270             p.println("            throw new CalledWithTooManyParameters();");
271             p.println("        }");
272             p.println("    }");
273             p.println();
274         }
275         p.println("    public abstract Object doApply(Object ... ps);");
276         p.println();
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 */ {");
284         p.println("            try {");
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();");
288         p.println("            }");
289         p.println("        }");
290         p.println("    }");
291         p.println("}");
292     }
293     
294     public static void generateUnsaturatedFunctionN(PrintStream p, int n) {
295         p.println(HEADER);
296         p.println("package " + PACKAGE + ";");
297         p.println();
298         p.println("@SuppressWarnings(\"all\")");
299         p.println("public class UnsaturatedFunction" + n + " implements Function {");
300         p.println("    private final Function f;");
301         for(int i=0;i<n;++i)
302             p.println("    private final Object p" + i + ";");
303         p.println();
304         p.print("    public UnsaturatedFunction" + n + "(Function f");
305         for(int i=0;i<n;++i)
306             p.print(", Object p" + i);
307         p.println(") {");
308         p.println("        this.f = f;");
309         for(int i=0;i<n;++i)
310             p.println("        this.p" + i + " = p" + i + ";");
311         p.println("    }");
312         p.println();
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) {
317                 if(i>0)
318                     p.print(", ");
319                 p.print("Object p" + (i + n));
320             }
321             p.println(") {");
322             if(n + k <= MAX_ARITY)
323                 p.print("        return f.apply(");
324             else
325                 p.print("        return f.applyArray(");
326             for(int i=0;i<k+n;++i) {
327                 if(i>0)
328                     p.print(", ");
329                 p.print("p" + i);
330             }
331             p.println(");");
332             p.println("    }");
333             p.println();
334         }
335         {
336             p.println("    @Override");
337             p.println("    public Object applyArray(Object ... ps) {");         
338             p.println("        Object[] nps = new Object[ps.length + " + n + "];");
339             for(int i=0;i<n;++i)
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);");
344             p.println("    }");
345         }
346         {
347             p.println("    @Override");
348             p.println("    public String toString() {");
349             p.println("        StringBuilder sb = new StringBuilder();");
350             p.println("        sb.append(\"(\").append(f);");
351             for(int i=0;i<n;++i)
352                 p.println("        sb.append(\" \").append(p"+i+");");
353             p.println("        sb.append(\")\");");
354             p.println("        return sb.toString();");
355             p.println("    }");
356         }
357         p.println("}");
358     }
359     
360     public static void generateUnsaturatedFunctionN(PrintStream p) {
361         p.println(HEADER);
362         p.println("package " + PACKAGE + ";");
363         p.println();
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;");
368         p.println();
369         p.println("    public UnsaturatedFunctionN(Function f, Object ... ps) {");
370         p.println("        this.f = f;");
371         p.println("        this.ps = ps;");
372         p.println("    }");
373         p.println();
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) {
378                 if(i>1)
379                     p.print(", ");
380                 p.print("Object p" + i);
381             }
382             p.println(") {");
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);");
388             p.println("    }");
389             p.println();
390         }
391         {
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);");
398             p.println("    }");
399         }
400         {
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();");
409             p.println("    }");
410         }
411         p.println("}");
412     }
413     
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('.', '/'));
421         dir.mkdirs();
422         
423         for(int n=1;n<=MAX_ARITY;++n) {
424             PrintStream ps = 
425                 new PrintStream(new FileOutputStream(new File(dir, "Function"+n+".java")));
426             generateFunctionN(ps, n);
427         }
428         {
429             PrintStream ps = 
430                 new PrintStream(new FileOutputStream(new File(dir, "FunctionN.java")));
431             generateFunctionN(ps);
432         }
433         {
434             PrintStream ps = 
435                 new PrintStream(new FileOutputStream(new File(dir, "Function.java")));
436             generateFunction(ps);
437         }
438         
439         for(int n=1;n<=MAX_ARITY;++n) {
440             PrintStream ps = 
441                 new PrintStream(new FileOutputStream(new File(dir, "FunctionImpl"+n+".java")));
442             generateFunctionImplN(ps, n);
443         }
444         {
445             PrintStream ps = 
446                 new PrintStream(new FileOutputStream(new File(dir, "FunctionImplN.java")));
447             generateFunctionImplN(ps);
448         }
449         for(int n=1;n<=MAX_ARITY;++n) {
450             PrintStream ps = 
451                 new PrintStream(new FileOutputStream(new File(dir, "UnsaturatedFunction"+n+".java")));
452             generateUnsaturatedFunctionN(ps, n);
453         }
454         {
455             PrintStream ps = 
456                 new PrintStream(new FileOutputStream(new File(dir, "UnsaturatedFunctionN.java")));
457             generateUnsaturatedFunctionN(ps);
458         }
459     }    
460 }