Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

1376
LINES

< > BotCompany Repo | #1006723 // Higher-Level-Transpiled #759 Spike [old]

JavaX translator [tags: use-pretranspiled]

Libraryless. Click here for Pure Java version (7724L/58K/154K).

1  
!1006722
2  
3  
m {
4  
  static bool autoQuine = true;
5  
  
6  
  !include #1001496 // Matches
7  
  !include #1000882 // EGDiff
8  
  !include #1000883 // BlockDiffer
9  
  !include #1001065 // DialoGIO
10  
  !include #1004045 // IndexedList2
11  
  //include #1001296 // MultiMap
12  
  !include #1000988 // MultiSet
13  
  !include #1004543 // DynamicObject
14  
  !include #1005575 // CompilerBot
15  
16  
  !include #1002662 // isTrue
17  
  
18  
  static int varCount;
19  
  static new Map<S, S> snippetCache;
20  
  static bool useIndexedList = true, opt_javaTok = true;
21  
22  
  p {
23  
    if (useIndexedList) findCodeTokens_debug = true;
24  
    javaTok_opt = opt_javaTok;
25  
    findCodeTokens_indexed = findCodeTokens_unindexed = 0;
26  
    findCodeTokens_bails = findCodeTokens_nonbails = 0;
27  
    javaTok_n = javaTok_elements = 0;
28  
    
29  
    print("759 STARTING " + identityHashCode(main.class));
30  
    varCount = 0;
31  
    L<S> tok = jtok(loadMainJava());
32  
    
33  
    L ts = findTranslators(toLines(join(tok)));
34  
    //print("Translators in source at start: " + structure(ts));
35  
    
36  
    // "duplicate" statement
37  
    
38  
    L<S> lines = toLines(join(tok));
39  
    call(getJavaX(), "findTranslators", lines);
40  
    new Matches m;
41  
    if (match("duplicate *", fromLines(lines), m)) {
42  
      // actual copying - unused
43  
      // tok = jtok(loadSnippet(m.get(0)));
44  
      
45  
      // reference by include()
46  
      tok = jtok("m { p { callMain(include(" + quote(m.get(0)) + ")); } }");
47  
    }
48  
    
49  
    // add m { }
50  
    
51  
    if (!hasCodeTokens(tok, "m", "{") && !hasCodeTokens(tok, "main", "{") && !hasCodeTokens(tok, "class", "main"))
52  
      tok = jtok(moveImportsUp("m {\n" + join(tok) + "\n}"));
53  
    
54  
    // standard translate
55  
    
56  
    ts = findTranslators(toLines(join(tok)));
57  
    //print("Translators in source: " + structure(ts));
58  
    tok = jtok(defaultTranslate(join(tok)));
59  
    
60  
    //print("end of default translate");
61  
    //print(join(tok));
62  
63  
    tok_autoCloseBrackets(tok);    
64  
    tok = processIncludes(tok); // before standard functions
65  
    processConceptsDot(tok);
66  
    tok = processIncludes(tok);
67  
    earlyStuff(tok);
68  
    
69  
    int safety = 0;
70  
    boolean same;
71  
    do {
72  
      S before = join(tok);
73  
      tok = standardFunctions(tok);
74  
      tok = stdstuff(tok); // standard functions and all the keywords
75  
      S diff;
76  
      long startTime = now();
77  
      //diff = unidiff(before, join(tok));
78  
      //print("unidiff: " + (now()-startTime) + " ms");
79  
      //same = eq(diff, "");
80  
      same = eq(before, join(tok)); // << could be sped up
81  
      if (!same) {
82  
        print("Not same " + safety + ".");
83  
        //print(indent(2, diff));
84  
      }
85  
      if (safety++ >= 10) {
86  
        //print(unidiff(before, join(tok)));
87  
        print("----");
88  
        print(join(tok));
89  
        print("----");
90  
        fail("safety 10 error!");
91  
      }
92  
    } while (!same);
93  
    
94  
    // POST-PROCESSING after stdstuff loop
95  
    
96  
    quicknew2(tok);
97  
    //tok = jtok(quicknew(join(tok)));
98  
    tok = extendClasses(tok);
99  
    libs(tok);
100  
    sourceCodeLine(tok);
101  
    throwFail(tok);
102  
    innerClassesVar(tok);
103  
    tok = autoImports(tok); // faster to do it at the end
104  
105  
    if (useIndexedList)
106  
      print("Indexed/unindexed lookups: " + findCodeTokens_indexed + "/" + findCodeTokens_unindexed + ", lists made: " + IndexedList2.instances);
107  
    print("findCodeToken bails: " + findCodeTokens_bails + "/" + findCodeTokens_nonbails);
108  
    print("javaToks: " + javaTok_n + "/" + javaTok_elements);
109  
    
110  
    if (tok.contains("package"))
111  
      splitJavaFiles(tok);
112  
    else
113  
      saveMainJava(tok);
114  
  }
115  
  
116  
  static L<S> stdstuff(L<S> tok) {
117  
    //if (++level >= 10) fail("woot? 10");
118  
    
119  
    print("stdstuff!");
120  
    int i;
121  
    
122  
    if (jfind(tok, "!<int>") >= 0) {
123  
      L<S> lines = toLines(join(tok));
124  
      L ts = findTranslators(lines);
125  
      tok = jtok(fromLines(lines));
126  
      print("DROPPING TRANSLATORS: " + structure(ts));
127  
    }
128  
129  
    tok = quickmain(tok);
130  
    tok = processIncludes(tok);
131  
    processConceptsDot(tok);
132  
    tok = processIncludes(tok);
133  
    earlyStuff(tok);
134  
    tok = multilineStrings(tok);
135  
    inStringEvals(tok);
136  
    listComprehensions(tok);
137  
    directSnippetRefs(tok);
138  
    quicknu(tok);
139  
    
140  
    jreplace(tok, "synced <id>", "synchronized $2");
141  
    
142  
    tok = replaceKeywordBlock(tok, "answer",
143  
      "static S answer(S s) {\nfinal new Matches m;\n",
144  
      "\nret null;\n}");
145  
      
146  
    tok = replaceKeywordBlock(tok, "loading",
147  
      "{ JWindow _loading_window = showLoadingAnimation(); try { /* loading try */ ",
148  
      "/* loading try */ } finally { disposeWindow(_loading_window); }\n /* loading end */ } /* after loading */ \n");
149  
150  
    tok = replaceKeywordBlock(tok, "html",
151  
      "static O html(S uri, fMap<S, S> params) ctex " + "{\n", "}");
152  
    
153  
    // "static sync" => static synchronized
154  
    jreplace(tok, "static sync", "static synchronized");
155  
156  
    // "sclass" => static class
157  
    jreplace(tok, "sclass", "static class");
158  
159  
    // "asclass" => abstract static class
160  
    jreplace(tok, "asclass", "abstract static class");
161  
162  
    // "sinterface" => static interface
163  
    jreplace(tok, "sinterface", "static interface");
164  
165  
    // "ssynchronized" => static synchronized
166  
    jreplace(tok, "ssynchronized", "static synchronized");
167  
168  
    jreplace(tok, "ssvoid", "static synchronized void");
169  
    jreplace(tok, "svoid", "static void");
170  
    jreplace(tok, "sbool", "static bool");
171  
    jreplace(tok, "sint", "static int");
172  
    jreplace(tok, "snew", "static new");
173  
    jreplace(tok, "sv <id>", "static void $2");
174  
    jreplace(tok, "pvoid", "public void");
175  
176  
    // "sS" => static S
177  
    jreplace(tok, "sS", "static S");
178  
179  
    // "sO" => static O
180  
    jreplace(tok, "sO", "static O");
181  
182  
    // "sL" => static L
183  
    jreplace(tok, "sL", "static L");
184  
185  
    // "toString {" => "public S toString() {"
186  
    jreplace(tok, "toString {", "public S toString() {");
187  
    
188  
    jreplace(tok, "Int", "Integer");
189  
    jreplace(tok, "Bool", "Boolean");
190  
    jreplace(tok, "Char", "Character");
191  
    
192  
    // I REALLY wanted to avoid this, but eh...
193  
    jreplace(tok, "SS", "Map<S, S>");
194  
195  
    // "catch {" => "catch (Throwable _e) {"
196  
    jreplace(tok, "catch {", "catch (Throwable _e) {");
197  
198  
    // "catch X e {" => "catch (X e) {"
199  
    jreplace(tok, "catch <id> <id> {", "catch ($2 $3) {");
200  
201  
    // "catch e {" => "catch (Throwable e) {" (if e is lowercase)
202  
    jreplace(tok, "catch <id> {", "catch (Throwable $2) {", new O() {
203  
      bool get(L<S> tok, int i) {
204  
        S word = tok.get(i+3);
205  
        ret startsWithLowerCase(word);
206  
      }
207  
    });
208  
    
209  
    jreplace(tok, "+ +", "+", new O() {
210  
      bool get(L<S> tok, int i) {
211  
        //printStructure("++: ", subList(tok, i-1, i+6));
212  
        if (empty(_get(tok, i+2))) ret false; // no space between the pluses
213  
        if (empty(_get(tok, i)) && eq("+", _get(tok, i-1))) ret false;  // an actual "++" at the left
214  
        if (empty(_get(tok, i+4)) && eq("+", _get(tok, i+5))) ret false;  // an actual "++" at the right
215  
        //print("doing it");
216  
        ret true;
217  
      }
218  
    });
219  
220  
    // some crazy fancy syntax
221  
    jreplace(tok, "set <id>;", "$2 = true;");
222  
    
223  
    // [stdEq] -> implementation of equals()
224  
    jreplace(tok, "[stdEq]",
225  
      "public bool equals(O o) { ret stdEq2(this, o); }\n" +
226  
      "public int hashCode() { ret stdHash2(this); }");
227  
    
228  
    // [concepts] "concept.field -> bla" for dereferencing references
229  
    jreplace(tok, "<id> ->", "$1.get().");
230  
    
231  
    // [concepts] "concept.field!" for dereferencing references
232  
    
233  
    jreplace(tok, "<id>!", "$1.get()", new O() { bool get(L<S> tok, int i) {
234  
      if (tok.get(i+2).contains("\n")) ret false; // no line break between <id> and !
235  
      S t = _get(tok, i+5);
236  
      if (t == null) ret false;
237  
      if (isIdentifier(t) || eqOneOf(t, "=", "(")) ret false;
238  
      ret true;
239  
    }});
240  
    
241  
    // [concepts] "field := value" for defining fields e.g. in "uniq"
242  
    while ((i = jfind(tok, "<id> :=")) >= 0) {
243  
      tok.set(i, quote(tok.get(i)));
244  
      tok.set(i+2, ",");
245  
      tok.set(i+4, "");
246  
      reTok(tok, i, i+5);
247  
    }
248  
    
249  
    // "quoted" := value
250  
    while ((i = jfind(tok, "<quoted> :=")) >= 0) {
251  
      tok.set(i, tok.get(i));
252  
      tok.set(i+2, ",");
253  
      tok.set(i+4, "");
254  
      reTok(tok, i, i+5);
255  
    }
256  
    
257  
    // more shortening
258  
259  
    jreplace(tok, "fS", "final S");
260  
    jreplace(tok, "fO", "final O");
261  
    jreplace(tok, "fL", "final L");
262  
    jreplace(tok, "fMap", "final Map");
263  
    jreplace(tok, "fRunnable", "final Runnable");
264  
    jreplace(tok, "f int", "final int");
265  
    
266  
    // "continue unless"
267  
    
268  
    while ((i = jfind(tok, "continue unless")) >= 0) {
269  
      int j = scanOverExpression(tok, getBracketMap(tok), i+4, ";");
270  
      replaceTokens(tok, i, i+4, "{ if (!(");
271  
      tok.set(j, ")) continue; }");
272  
      reTok(tok, i, j+1);
273  
    }
274  
    
275  
    // "continue if"
276  
    
277  
    while ((i = jfind(tok, "continue if")) >= 0) {
278  
      int j = scanOverExpression(tok, getBracketMap(tok), i+4, ";");
279  
      replaceTokens(tok, i, i+4, "{ if (");
280  
      tok.set(j, ") continue; }");
281  
      reTok(tok, i, j+1);
282  
    }
283  
    
284  
    // "return if"
285  
    
286  
    while ((i = jfind(tok, "return if")) >= 0) {
287  
      int j = scanOverExpression(tok, getBracketMap(tok), i+4, ";");
288  
      replaceTokens(tok, i, i+4, "{ if (");
289  
      tok.set(j, ") return; }");
290  
      reTok(tok, i, j+1);
291  
    }
292  
    
293  
    // Replace $1 with m.unq(0) etc. - caveat: this blocks identifiers $1, $2, ...
294  
    for (i = 1; i < l(tok); i += 2) {
295  
      S s = tok.get(i);
296  
      if (s.startsWith("$")) {
297  
        s = substring(s, 1);
298  
        if (isInteger(s)) {
299  
          tok.set(i, "m.unq(" + (parseInt(s)-1) + ")");
300  
          reTok(tok, i);
301  
        }
302  
      }
303  
    }
304  
305  
    // shortened method declarations - hopefully that works
306  
    
307  
    jreplace(tok, "void <id> {", "$1 $2() {");
308  
    jreplace(tok, "String <id> {", "$1 $2() {");
309  
    jreplace(tok, "Object <id> {", "$1 $2() {");
310  
    jreplace(tok, "List <id> {", "$1 $2() {");
311  
    
312  
    // instanceof trickery
313  
    
314  
    jreplace(tok, "is a <id>", "instanceof $3");
315  
    jreplace(tok, "!<id> instanceof <id>.<id>", "!($2 instanceof $4.$6)");
316  
    jreplace(tok, "!<id> instanceof <id>", "!($2 instanceof $4)");
317  
    jreplace(tok, "<id> !instanceof <id>", "!($1 instanceof $4)");
318  
    
319  
    // func keyword for lambdas - now automatically quines toString() if enabled
320  
    
321  
    while ((i = jfind(tok, "func(")) >= 0) {
322  
      int argsFrom = i+4, argsTo = findCodeTokens(tok, i, false, ")");
323  
      int idx = findCodeTokens(tok, argsTo, false, "{");
324  
      int j = findEndOfBracketPart(tok, idx);
325  
      L<S> contents = subList(tok, idx+1, j-1);
326  
      replaceTokens(tok, i, j, "new O { O get(" + join(subList(tok, argsFrom, argsTo-1)) + ") ct" + "ex { " + tok_addReturn(contents) + " }\n" +
327  
      (autoQuine ? "  public S toString() { ret " + quote(trim(join(contents))) + "; }" : "") + "}");
328  
      reTok(tok, i, j);
329  
    }
330  
    
331  
    while ((i = jfind(tok, "voidfunc(")) >= 0) {
332  
      int argsFrom = i+4, argsTo = findCodeTokens(tok, i, false, ")");
333  
      int idx = findCodeTokens(tok, argsTo, false, "{");
334  
      int j = findEndOfBracketPart(tok, idx);
335  
      L<S> contents = subList(tok, idx+1, j-1);
336  
      replaceTokens(tok, i, j, "new O { void get(" + join(subList(tok, argsFrom, argsTo-1)) + ") ct" + "ex { " + tok_addSemicolon(contents) + " }\n" +
337  
      (autoQuine ? "  public S toString() { ret " + quote(trim(join(contents))) + "; }" : "") + "}");
338  
      reTok(tok, i, j);
339  
    }
340  
    
341  
    while ((i = jfind(tok, "func {")) >= 0) {
342  
      int idx = findCodeTokens(tok, i, false, "{");
343  
      int j = findEndOfBracketPart(tok, idx+2);
344  
      L<S> contents = subList(tok, idx+1, j-1);
345  
      replaceTokens(tok, i, j, "new O { O get() ct" + "ex { " + tok_addReturn(contents) + " }\n" +
346  
      (autoQuine ? "  public S toString() { ret " + quote(trim(join(contents))) + "; }" : "") + "}");
347  
      reTok(tok, i, j);
348  
    }
349  
    /*tok = replaceKeywordBlock(tok, "func",
350  
      "new O { O get() { ret",
351  
      ";}}");*/
352  
    
353  
    // shortened subconcept declaration (before star constructors!)
354  
    
355  
    jreplace(tok, "<id> > <id> {", "concept $3 extends $1 {", new O() { O get(L<S> tok, int i) {
356  
      //print("subconcept: " + quote(tok.get(i)));
357  
      ret tok.get(i).contains("\n"); // only at beginning of line
358  
    }});
359  
    
360  
    // concept declarations
361  
    
362  
    for (S kw : ll("concept", "sconcept")) {
363  
      O cond = new O() {
364  
        O get(L<S> tok, int i) {
365  
          addFieldOrder(tok, i+1);
366  
          ret true;
367  
        }
368  
      };
369  
      bool re = false;
370  
      if (jreplace(tok, kw + " <id> {", "static class $2 extends Concept {", cond)) re = true;
371  
      if (jreplace(tok, kw + " <id> implements", "static class $2 extends Concept implements", cond)) re = true;
372  
      if (jreplace(tok, kw + " <id>", "static class $2", cond)) re = true;
373  
      if (re) reTok(tok);
374  
    }
375  
    
376  
    // "case" as a variable name ( => _case)
377  
    
378  
    caseAsVariableName(tok);
379  
    
380  
    // "continue" as a function name ( => _continue)
381  
    continueAsFunctionName(tok);
382  
    
383  
    // * constructors
384  
    if (hasCodeTokens(tok, "\\*", "("))
385  
      tok = expandStarConstructors(tok);
386  
      
387  
    // Do this BEFORE awt replacement! ("p-awt" contains "awt" token)
388  
    tok = replaceKeywordBlock(tok, "p-substance-thread", "p { substance();", "}");
389  
    tok = replaceKeywordBlock(tok, "p-substance", "p-awt { substance();", "}");
390  
    jreplace(tok, "p-type {", "p-typewriter {");
391  
    tok = replaceKeywordBlock(tok, "p-awt", "p { swing {", "}}");
392  
    tok = replaceKeywordBlock(tok, "p-typewriter", "p { typeWriterConsole();", "}");
393  
    tok = replaceKeywordBlock(tok, "p-lowprio", "p { lowPriorityThread(r " + "{", "}); }");
394  
    tok_p_repeatWithSleep(tok);
395  
396  
    tok = replaceKeywordBlock(tok,
397  
      "awt",
398  
      "swingLater(r " + "{", // for #711
399  
      "});");
400  
401  
    tok = replaceKeywordBlock(tok,
402  
      "swing",
403  
      "{ swingAndWait(r " + "{", // for #711
404  
      "}); }");
405  
406  
    // crazy stuff
407  
408  
    jreplace (tok, "for <id> over <id>:", "for (int $2 = 0; $2 < l($4); $2++)");
409  
    jreplace (tok, "for <id> to <id>:", "for (int $2 = 0; $2 < $4; $2++)");
410  
    jreplace (tok, "for <id> to <int>:", "for (int $2 = 0; $2 < $4; $2++)");
411  
    
412  
    // STANDARD CLASSES & INTERFACES
413  
414  
    S sc = cacheGet("#1003674");   
415  
    new L<S> lclasses;
416  
    for (S line : toLinesFullTrim(sc)) {
417  
      line = javaDropComments(line).trim();
418  
      int idx = line.indexOf('/');
419  
      lclasses.addAll(ll(line.substring(0, idx), line.substring(idx+1)));
420  
    }
421  
    
422  
    final Set<S> haveClasses = addLibraryClasses(tok, toStringArray(lclasses));
423  
    haveClasses.add("String");
424  
    
425  
    // Stuff that depends on the list of inner classes (haveClasses)
426  
    expandClassReferences(tok, haveClasses);
427  
    slashCasts(tok, haveClasses);
428  
    
429  
    // "x << X" => "x instanceof X"
430  
    jreplace(tok, "<id> << <id>", "$1 instanceof $4", new O() {
431  
      O get(L<S> tok, int i) {
432  
        ret haveClasses.contains(tok.get(i+7));
433  
      }
434  
    });
435  
436  
    expandVarCopies(tok);
437  
    
438  
    // concept-related stuff
439  
    
440  
    // auto-import concepts
441  
    bool _a = hasCodeTokens(tok, /*"extends",*/ "Concept"), _b = !haveClasses.contains("Concept");
442  
    print("auto-import: " + _a + ", " + _b);
443  
    if (_a && _b) {
444  
      printStruct(haveClasses);
445  
      tok = includeInMainLoaded(tok, "concepts.");
446  
      reTok(tok, l(tok)-1, l(tok));
447  
      //processConceptsDot(tok);
448  
    }
449  
    
450  
    jreplace(tok, "for (<id> <id>)", "for ($3 $4 : list($3))");
451  
452  
    // the infamous missing functions (usually caused by class Matches)
453  
    // maybe not needed anymore?
454  
    if (!hasCodeTokens(tok, "String", "unquote") && containsToken(tok, "unquote")) {
455  
      print("Adding unquote");
456  
      tok = includeInMain(tok, "#1001735");
457  
    }
458  
      
459  
    if (!hasCodeTokens(tok, "String", "formatSnippetID") && containsToken(tok, "formatSnippetID")) {
460  
      print("Adding formatSnippetID");
461  
      tok = includeInMain(tok, "#1000709");
462  
    }
463  
    
464  
    tok = expandShortTypes(tok);
465  
      
466  
    if (containsToken(tok, "cast")) {
467  
      S s = join(tok);
468  
      s = s.replaceAll("(\\w+<[\\w\\s,\\[\\]]+>|\\w+|\\w+\\[\\]|\\w+\\[\\]\\[\\])\\s+(\\w+)\\s*=\\s*cast(\\W[^;]*);", "$1 $2 = ($1) ($3);");
469  
      tok = jtok(s);
470  
    }
471  
    
472  
    tok = replaceKeywordBlock(tok, "r-thread", "runnableThread(r " + "{", "})");
473  
    
474  
    // runnable and r - now also with automatic toString if enabled
475  
    for (S keyword : ll("runnable", "r"))
476  
      while ((i = jfind(tok, keyword + " {")) >= 0) {
477  
        int idx = findCodeTokens(tok, i, false, "{");
478  
        int j = findEndOfBracketPart(tok, idx);
479  
        L<S> contents = subList(tok, idx+1, j-1);
480  
        //print("r contents: " + structure(contents));
481  
        replaceTokens(tok, i, j+1, "new Runnable() { public void run() { try { " + tok_addSemicolon(contents) + 
482  
          "\n} catch (Exception __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); } }" +
483  
      (autoQuine ? "  public S toString() { return " + quote(trim(join(contents))) + "; }" : "") +
484  
          "}");
485  
        reTok(tok, i, j+1);
486  
      }
487  
    
488  
    tok = replaceKeywordBlock(tok,
489  
      "expectException",
490  
      "{ bool __ok = false; try {",
491  
      "} catch { __ok = true; } assertTrue(\"expected exception\", __ok); }");
492  
      
493  
    while ((i = tok.indexOf("tex")) >= 0) {
494  
      tok.set(i, "throws Exception");
495  
      tok = jtok(tok);
496  
    }
497  
    
498  
    // shorter & smarter whiles
499  
    
500  
    jreplace(tok, "while true", "while (true)");
501  
    jreplace(tok, "while licensed", "while (licensed())");
502  
    jreplace(tok, "repeat {", "while (licensed()) {");
503  
    tok_repeatWithSleep(tok);
504  
    
505  
    // null; => return null; etc.
506  
507  
    O cond = new O() {
508  
      bool get(L<S> tok, int i) {
509  
        S t = _get(tok, i-1);
510  
        ret l(t) == 1 && "{};)".contains(t) || eq(t, "else");
511  
      }
512  
    };
513  
    jreplace(tok, "null;", "return null;", cond);
514  
    jreplace(tok, "false;", "return false;", cond);
515  
    jreplace(tok, "true;", "return true;", cond);
516  
    jreplace(tok, "this;", "return this;", cond);
517  
518  
    // "myFunction;" instead of "myFunction();" - quite rough
519  
    cond = new O() {
520  
      bool get(L<S> tok, int i) {
521  
        S word = tok.get(i+3);
522  
        //print("single word: " + word);
523  
        ret !litlist("break", "continue", "return").contains(word);
524  
      }
525  
    };
526  
    for (S pre : litlist("}", ";"))
527  
      jreplace(tok, pre + " <id>;", "$1 $2();", cond);
528  
529  
    // shorter match syntax for answer methods
530  
    
531  
    jreplace(tok, "if <quoted> || <quoted>",
532  
      "if (matchOneOf(s, m, $2, $5))");
533  
    jreplace(tok, "if <quoted>", "if (matchStartX($2, s, m))",
534  
      new O() { bool get(L<S> tok, int i) {
535  
        ret unquote(tok.get(i+3)).endsWith("...");
536  
      }});
537  
    jreplace(tok, "if <quoted>", "if (match($2, s, m))");
538  
    jreplace(tok, "if match <quoted>", "if (match($3, s, m))");
539  
540  
    // extra commas ("litlist(1, 2,)")
541  
    
542  
    jreplace(tok, ",)", ")");
543  
    
544  
    // additional translations (if necessary)
545  
    
546  
    tok = replaceKeywordBlock(tok,
547  
      "pcall",
548  
      "try { /* pcall 1*/ ",
549  
      "/* pcall 2 */ } catch (Throwable __e) { printStackTrace(__e); }");
550  
551  
    tok = dialogHandler(tok);
552  
    
553  
    tok = replaceKeywordBlock(tok, "exceptionToUser",
554  
      "try {",
555  
      "} catch (Throwable __e) { ret exceptionToUser(__e); }"); 
556  
557  
    if (hasCodeTokens(tok, "twice", "{"))
558  
      tok = replaceKeywordBlock(tok, "twice",
559  
        "for (int __twice = 0; __twice < 2; __twice++) {",
560  
        "}"); 
561  
562  
    while ((i = findCodeTokens(tok, "repeat", "*", "{")) >= 0) {
563  
      S v = makeVar("repeat");
564  
      tok.set(i, "for (int " + v + " = 0; " + v + " < " + tok.get(i+2) + "; " + v + "++)");
565  
      tok.set(i+2, "");
566  
      tok = jtok(tok);
567  
    }
568  
569  
    tok = replaceKeywordBlockDyn(tok,
570  
      "time",
571  
      new O() { S[] get() {
572  
        S var = makeVar("startTime");
573  
        ret new S[] {
574  
          "{ long " + var + " = now(); try { ",
575  
          "} finally { " + var + " = now()-" + var + "; saveTiming(" + var + "); } }"};
576  
      }});
577  
    
578  
    if (hasCodeTokens(tok, "assertFail", "{")) {
579  
      S var = makeVar("oops");
580  
      
581  
      tok = replaceKeywordBlock(tok,
582  
        "assertFail",
583  
        "boolean " + var + " = false; try {",
584  
        "\n" + var + " = true; } catch (Exception e) { /* ok */ } assertFalse(" + var + ");"); 
585  
    }
586  
    
587  
    tok = replaceKeywordBlock(tok,
588  
      "yo",
589  
      "try {",
590  
      "} catch (Exception " + makeVar("e") + ") { ret false; }");
591  
592  
    tok = replaceKeywordBlock(tok,
593  
      "awtIfNecessary",
594  
      "swingNowOrLater(r " + "{",
595  
      "});");
596  
      
597  
    if (hasCodeTokens(tok, "ctex"))
598  
      tok = ctex(tok);
599  
      
600  
    tok = replaceKeywordBlock(tok,
601  
      "actionListener",
602  
      "new java.awt.event.ActionListener() { " +
603  
        "public void actionPerformed(java.awt.event.ActionEvent _evt) {",
604  
      "}}");
605  
      
606  
    namedThreads(tok);
607  
    threads(tok);
608  
609  
    // try answer
610  
    while ((i = findCodeTokens(tok, "try", "answer")) >= 0) {
611  
      int j = findEndOfStatement(tok, i);
612  
      S v = makeVar("a");
613  
      tok.set(i, "{ S " + v);
614  
      tok.set(i+2, "=");
615  
      tok.set(j-1, "; if (!empty(" + v + ")) ret " + v + "; }");
616  
      tok = jtok(tok);
617  
    }
618  
619  
    // return optional (return if not null)
620  
    while ((i = jfind(tok, "return optional <id> =")) >= 0) {
621  
      int j = findEndOfStatement(tok, i);
622  
      S v = tok.get(i+4);
623  
      clearTokens(tok, i+2, i+4);
624  
      tok.set(i, "{");
625  
      tok.set(j-1, "; if (" + v + " != null) ret " + v + "; }");
626  
      tok = jtok(tok);
627  
    }
628  
    
629  
    functionReferences(tok);
630  
631  
    // TODO: optimize
632  
    S moved = moveImportsUp2(join(tok));
633  
    if (moved != null)
634  
      tok = jtok(moved);
635  
      
636  
    ret tok;
637  
  } // end of stdStuff!
638  
  
639  
  static L<S> multilineStrings(L<S> tok) {
640  
    for (int i = 1; i < tok.size(); i += 2) {
641  
      S t = tok.get(i);
642  
      if (isQuoted(t))
643  
        if (t.startsWith("[") || t.contains("\r") || t.contains("\n"))
644  
          tok.set(i, quote(unquote(t)));
645  
    }
646  
    ret tok;
647  
  }
648  
  
649  
  static void inStringEvals(L<S> tok) {
650  
    bool change = false;
651  
    for (int i = 1; i < tok.size(); i += 2) {
652  
      S t = tok.get(i);
653  
      if (!isQuoted(t)) continue;
654  
      if (t.contains("\\*") && !t.contains("\\\\")) { // << rough
655  
        tok.set(i, inStringEval(t));
656  
        change = true;
657  
      }
658  
    }
659  
    if (change) reTok(tok);
660  
  }
661  
  
662  
  static S inStringEval(S t) {
663  
    t = dropPrefix("\"", dropSuffix("\"", t));
664  
    new L<S> l;
665  
    int idx;
666  
    while ((idx = t.indexOf("\\*")) >= 0) {
667  
      int j = indexOf(t, idx, "*/");
668  
      if (j < 0) break;
669  
      if (idx > 0)
670  
        l.add("\"" + substring(t, 0, idx) + "\"");
671  
      l.add("(" + trim(substring(t, idx+2, j)) + ")");
672  
      t = substring(t, j+2);
673  
    }
674  
    if (nempty(t))
675  
      l.add("\"" + t + "\"");
676  
    ret "(" + join(" + ", l) + ")";
677  
  }
678  
  
679  
  static L<S> quickmain(L<S> tok) {
680  
    int i = findCodeTokens(tok, "main", "{");
681  
    if (i < 0) i = findCodeTokens(tok, "m", "{");
682  
    if (i >= 0 && !(i-2 > 0 && tok.get(i-2).equals("class")))
683  
      tok.set(i, "public class main");
684  
      
685  
    i = findCodeTokens(tok, "psvm", "{");
686  
    if (i < 0) i = findCodeTokens(tok, "p", "{");
687  
    if (i >= 0)
688  
      tok.set(i, "public static void main(final String[] args) throws Exception");
689  
      
690  
    ret jtok(tok);
691  
  }
692  
  
693  
  static S makeVar(S name) {
694  
    ret "_" + name + "_" + varCount++;
695  
  }
696  
  
697  
  static S makeVar() { ret makeVar(""); }
698  
  
699  
  /*static L<S> standardFunctions(L<S> tok) {
700  
    ret rtq(tok, "#1002474");
701  
  }*/
702  
  
703  
  static L<S> rtq(L<S> tok, S id) {
704  
    ret runTranslatorQuick(tok, id);
705  
  }
706  
  
707  
  static L<S> expandShortTypes(L<S> tok) {
708  
    // replace <int> with <Integer>
709  
    for (int i = 1; i+4 < tok.size(); i += 2)
710  
      if (tok.get(i).equals("<")
711  
        && litlist(">", ",").contains(tok.get(i+4))) {
712  
        String type = tok.get(i+2);
713  
        if (type.equals("int")) type = "Integer";
714  
        else if (type.equals("long")) type = "Long";
715  
        tok.set(i+2, type);
716  
      }
717  
      
718  
    // O = Object, S = String, ret = return
719  
    for (int i = 1; i < tok.size(); i += 2) {
720  
      String t = tok.get(i);
721  
      if (t.equals("O")) t = "Object";
722  
      if (t.equals("S")) t = "String";
723  
      else if (t.equals("L")) t = "List";
724  
      //else if (t.equals("F")) t = "Function";
725  
      else if (t.equals("ret")) t = "return";
726  
      else if (t.equals("bool") && i+2 < tok.size() && neq(tok.get(i+2), "(")) t = "boolean"; // bool -> boolean if it's not a function name
727  
      tok.set(i, t);
728  
    }
729  
    
730  
    ret tok;
731  
  }
732  
  
733  
  static L<S> autoImports(L<S> tok) {
734  
    S s = join(tok);
735  
    List<String> imports = findImports(s);
736  
    new StringBuilder buf;
737  
    for (String c : standardImports)
738  
      if (!(imports.contains(c)))
739  
        buf.append("import " + c + ";\n");
740  
    if (buf.length() == 0) ret tok;
741  
    ret jtok(buf+s);
742  
  }
743  
  
744  
  static String[] standardImports = {
745  
    "java.util.*",
746  
    "java.util.zip.*",
747  
    "java.util.List",
748  
    "java.util.regex.*",
749  
    "java.util.concurrent.*",
750  
    "java.util.concurrent.atomic.*",
751  
    "java.util.concurrent.locks.*",
752  
    "javax.swing.*",
753  
    "javax.swing.event.*",
754  
    "javax.swing.text.*",
755  
    "javax.swing.table.*",
756  
    "java.io.*",
757  
    "java.net.*",
758  
    "java.lang.reflect.*",
759  
    "java.lang.ref.*",
760  
    "java.lang.management.*",
761  
    "java.security.*",
762  
    "java.security.spec.*",
763  
    "java.awt.*",
764  
    "java.awt.event.*",
765  
    "java.awt.image.*",
766  
    "javax.imageio.*",
767  
    "java.math.*"
768  
  };
769  
  
770  
  static L<S> expandStarConstructors(L<S> tok) {
771  
    mainLoop: for (int i = 3; i+6 < tok.size(); i += 2) {
772  
      String t = tok.get(i), l = tok.get(i-2);
773  
      if (!t.equals("*"))
774  
        continue;
775  
      if (!tok.get(i+2).equals("("))
776  
        continue;
777  
      if (!eqOneOf(l, "}", "public", "private", "protected", ";", "{")) // is this correct...??
778  
        continue;
779  
        
780  
      // ok, it seems like a constructor declaration.
781  
      // Now find class name by going backwards.
782  
      
783  
      int j = i, level = 1;
784  
      while (j > 0 && level > 0) {
785  
        t = tok.get(j);
786  
        if (t.equals("}")) ++level;
787  
        if (t.equals("{")) --level;
788  
        j -= 2;
789  
      }
790  
      
791  
      while (j > 0) {
792  
        t = tok.get(j);
793  
        if (t.equals("class")) {
794  
          String className = tok.get(j+2);
795  
          tok.set(i, className); // exchange constructor name!
796  
          
797  
          // now for the parameters.
798  
          // Syntax: *(Learner *learner) {
799  
          // We will surely add type inference here in time... :)
800  
          
801  
          j = i+2;
802  
          while (!tok.get(j).equals("{"))
803  
            j += 2;
804  
          int block = j+1;
805  
          for (int k = i+2; k < block-1; k += 2)
806  
            if (tok.get(k).equals("*")) {
807  
              tok.remove(k);
808  
              tok.remove(k);
809  
              block -= 2;
810  
              String name = tok.get(k);
811  
              tok.addAll(block, Arrays.asList(new String[] {
812  
                "\n  ", "this", "", ".", "", name, " ", "=", " ", name, "", ";" }));
813  
            }
814  
          
815  
          continue mainLoop;
816  
        }
817  
        j -= 2;
818  
      }
819  
    }
820  
    ret tok;
821  
  }
822  
  
823  
  static L<S> processIncludes(L<S> tok) {
824  
    int safety = 0;
825  
    while (hasCodeTokens(tok, "!", "include") && ++safety < 100)
826  
      tok = processIncludesSingle_2(tok);
827  
    
828  
    tok_autoCloseBrackets(tok);
829  
    ret tok;
830  
  }
831  
  
832  
  static L<S> processIncludesSingle(L<S> tok) {
833  
    S s = join(tok);
834  
    Matcher m = Pattern.compile("\n\\s*!include (#\\d+)").matcher(s);
835  
    if (!m.find()) ret tok;
836  
    StringBuffer buf = new StringBuffer();
837  
    do {
838  
      String includedSrc = loadSnippet(m.group(1));
839  
      m.appendReplacement(buf, m.quoteReplacement("\n" + includedSrc));
840  
    } while (m.find());
841  
    m.appendTail(buf);
842  
    ret jtok(str(buf));
843  
  }
844  
845  
  static L<S> processIncludesSingle_2(L<S> tok) {
846  
    int i;
847  
    while ((i = jfind(tok, "!include #<int>")) >= 0) {
848  
      S id = tok.get(i+6);
849  
      String includedSrc = loadSnippet(id);
850  
      clearTokens(tok, i, i+8);
851  
      tok.set(i, "\n" + includedSrc + "\n");
852  
      reTok(tok, i, i+8);
853  
    }
854  
    ret tok;
855  
  }
856  
857  
  static L<S> ctex(L<S> tok) {
858  
    S s = join(tok);
859  
    Pattern regex = Pattern.compile("\\s+(no\\s+exceptions|ctex|null on exception)\\s*\\{");
860  
    
861  
    for (int i = 0; i < 100; i++) {
862  
      Matcher matcher = regex.matcher(s);
863  
      if (!matcher.find())
864  
        break;
865  
      String kind = matcher.group(1);
866  
867  
      //print("Iteration " + (i+1));
868  
      int start = matcher.start(), end = matcher.end();
869  
      int endOfBlock = ctex_findEndOfBlock(s, end);
870  
      
871  
      String catchBlock, catchWhat;
872  
      if (kind.startsWith("null")) {
873  
        catchBlock = "return null;";
874  
        catchWhat = "Throwable";
875  
      } else {
876  
        catchBlock = "throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e);";
877  
        catchWhat = "Throwable";
878  
      }
879  
        
880  
      String tryBlock = " { try {\n " +
881  
        s.substring(end, endOfBlock) + "\n} catch (" + catchWhat + " __e) { " + catchBlock + " }";
882  
      s = s.substring(0, start) + tryBlock + s.substring(endOfBlock);
883  
    }
884  
    ret jtok(s);
885  
  }
886  
  
887  
  // start is the index AFTER the opening bracket
888  
  // returns index OF closing bracket
889  
  static int ctex_findEndOfBlock(String s, int start) {
890  
    int level = 1;
891  
    for (int i = start; i < s.length(); i++) {
892  
      if (s.charAt(i) == '{') ++level;
893  
      else if (s.charAt(i) == '}') --level;
894  
      if (level == 0)
895  
        return i;
896  
    }
897  
    return s.length();
898  
  }
899  
  
900  
  static L<S> dialogHandler(L<S> tok) {
901  
    ret replaceKeywordBlock(tok,
902  
      "dialogHandler",
903  
      "new DialogHandler() {\n" +
904  
        "public void run(final DialogIO io) {",
905  
      "}}");
906  
  }
907  
  
908  
  static void quicknew2(L<S> tok) {
909  
    jreplace(tok, "new <id> <id>;", "$2 $3 = new $2;");
910  
    jreplace(tok, "new <id><<id>> <id>;", "$2<$4> $6 = new $2;");
911  
    jreplace(tok, "new <id><<id>,<id>> <id>;", "$2<$4,$6> $8 = new $2;");
912  
    jreplace(tok, "new <id><<id><<id>>> <id>;", "$2 $3 $4 $5 $6 $7 $8 $9 = new $2;");
913  
    
914  
    jreplace(tok, "for args " + "{", "for (int i = 0; i < args.length; i++) { final String arg = args[i];");
915  
    
916  
    // Constructor calls without parentheses
917  
    // So you can say something like: predictors.add(new P1);
918  
    
919  
    jreplace1(tok, "new <id>", "new $2()", new O() {
920  
      bool get(L<S> tok, int i) {
921  
        ret eqOneOf(_get(tok, i+5), "{", ",", ")", ";", ":");
922  
      }
923  
    });
924  
    
925  
    jreplace(tok, "new " + "List(", "new ArrayList(");
926  
    jreplace(tok, "new " + "Map(", "new HashMap(");
927  
    jreplace(tok, "\\*<id>[<id>] <id>;", "$2[] $6 = new $2[$4];");
928  
  }
929  
  
930  
  // OLD
931  
  static S quicknew(S s) {
932  
    s = s.replaceAll("new\\s+L<([\\w\\[\\]<>,\\s]+)>\\s+(\\w+);", "List<$1> $2 = new ArrayList<$1>();");
933  
    s = s.replaceAll("new\\s+List<([\\w\\[\\]<>,\\s]+)>\\s+(\\w+);", "List<$1> $2 = new ArrayList<$1>();");
934  
    s = s.replaceAll("new\\s+\\(Hash\\)Set<(\\w+)>\\s+(\\w+);", "Set<$1> $2 = new HashSet<$1>();");
935  
    s = s.replaceAll("new\\s+\\(Tree\\)Set<(\\w+)>\\s+(\\w+);", "Set<$1> $2 = new TreeSet<$1>();");
936  
    s = s.replaceAll("new\\s+Set<(\\w+)>\\s+(\\w+);", "Set<$1> $2 = new TreeSet<$1>();"); // TreeSet now default - pay attention to explicitly say HashSet if you need it.
937  
    s = s.replaceAll("new\\s+\\(Hash\\)Map<([\\w\\s,]+)>\\s+(\\w+);", "Map<$1> $2 = new HashMap<$1>();");
938  
    s = s.replaceAll("new\\s+\\(Tree\\)Map<([\\w\\s,]+)>\\s+(\\w+);", "Map<$1> $2 = new TreeMap<$1>();");
939  
    
940  
    // TreeMap when string as key
941  
    s = s.replaceAll("new\\s+Map<(S,[\\w\\s,]+)>\\s+(\\w+);", "Map<$1> $2 = new TreeMap<$1>();");
942  
    s = s.replaceAll("new\\s+Map<(String,[\\w\\s,]+)>\\s+(\\w+);", "Map<$1> $2 = new TreeMap<$1>();");
943  
    
944  
    // HashMap is default for everything else
945  
    s = s.replaceAll("new\\s+Map<([\\w\\s,]+)>\\s+(\\w+);", "Map<$1> $2 = new HashMap<$1>();");
946  
    
947  
    s = s.replaceAll("new\\s+(\\w+<[\\w\\s,]+>)\\s+(\\w+);", "$1 $2 = new $1();");
948  
    
949  
    ret s;
950  
  }
951  
  
952  
  static L<S> extendClasses(L<S> tok) {
953  
    int i;
954  
    while ((i = jfind(tok, "extend <id> {")) >= 0) {
955  
      S className = tok.get(i+2);
956  
      int idx = findCodeTokens(tok, i, false, "{");
957  
      int j = findEndOfBracketPart(tok, idx+2);
958  
      S content = join(subList(tok, idx+1, j-1));
959  
      L<S> c = findInnerClassOfMain(tok, className);
960  
      print("Extending class " + className + " ==> " + join(c));
961  
      clearTokens(tok.subList(i, j+1));
962  
      if (c == null) {
963  
        print("Warning: Can't extend class " + className + ", not found");
964  
        continue;
965  
      }
966  
      int startOfClass = indexOfSubList(tok, c); // magicIndexOfSubList is broken
967  
      int endOfClass = startOfClass + l(c)-1;
968  
      print("Extending class " + className + " ==> " + join(subList(tok, startOfClass, endOfClass)));
969  
      while (neq(tok.get(endOfClass), "}")) --endOfClass;
970  
      print("Extending class " + className + " ==> " + join(subList(tok, startOfClass, endOfClass)));
971  
      tok.set(endOfClass, content + "\n" + tok.get(endOfClass));
972  
      reTok(tok); // changed in 2 places, let's retok it all
973  
    }
974  
    ret tok;
975  
  }
976  
  
977  
  static void listComprehensions(L<S> tok) {
978  
    int i;
979  
    for (S op : ll(":", "in"))
980  
      while ((i = jfind(tok, "[<id> <id> " + op)) >= 0) {
981  
        Map<Integer, Integer> bracketMap = getBracketMap(tok);
982  
        S type = tok.get(i+2), id = tok.get(i+4);
983  
        int j = scanOverExpression(tok, bracketMap, i+8, "|");
984  
        S exp = join(tok.subList(i+8, j));
985  
        j += 2;
986  
        int k = scanOverExpression(tok, bracketMap, j, "]");
987  
        S where = join(tok.subList(j, k));
988  
        ++k;
989  
        
990  
        S code = "filter(" + exp + ", func(" + type + " " + id + ") { " + where + " })";
991  
        replaceTokens(tok, i, k, code);
992  
        reTok(tok, i, k);
993  
      }
994  
  }
995  
  
996  
  // lib 123 => !123
997  
  static void libs(L<S> tok) {
998  
    new TreeSet<S> libs;
999  
    int i;
1000  
    while ((i = jfind(tok, "lib <int>")) >= 0) {
1001  
      S id = tok.get(i+2);
1002  
      print("lib " + id);
1003  
      if (!libs.contains(id)) {
1004  
        libs.add(id);
1005  
        tok.set(i, "!");
1006  
        tok.set(i+1, "");
1007  
      } else {
1008  
        print("...ignoring (duplicate)");
1009  
        clearAllTokens(tok, i, i+3);
1010  
        reTok(tok, i, i+3);
1011  
      }
1012  
    }
1013  
  }
1014  
  
1015  
  // sourceCodeLine() => 1234
1016  
  static void sourceCodeLine(L<S> tok) {
1017  
    int i ;
1018  
    while ((i = jfind(tok, "sourceCodeLine()")) >= 0) {
1019  
      replaceTokens(tok, i, i+5, str(countChar(join(subList(tok, 0, i)), '\n')+1));
1020  
      reTok(tok, i, i+5);
1021  
    }
1022  
  }
1023  
  
1024  
  // done before any other processing
1025  
  static void earlyStuff(L<S> tok) {
1026  
    int i;
1027  
    
1028  
    // Note: this makes the word "quine" a special operator
1029  
    // (unusable as a function name)
1030  
    
1031  
    while ((i = jfind(tok, "quine(")) >= 0) {
1032  
      int idx = findCodeTokens(tok, i, false, "(");
1033  
      int j = findEndOfBracketPart(tok, idx+2);
1034  
      tok.set(i, "new Quine");
1035  
      tok.set(idx, "(" + quote(join(subList(tok, idx+1, j-1))) + ", ");
1036  
      reTok(tok, i, idx+1);
1037  
    }
1038  
  }
1039  
  
1040  
  static void throwFail(L<S> tok) {
1041  
    bool anyChange = false;
1042  
    for (int i = 1; i+2 < l(tok); i += 2)
1043  
      if (eq(get(tok, i+2), "fail") && !eqOneOf(get(tok, i), "throw", "RuntimeException", "return")) {
1044  
        tok.set(i+2, "throw fail");
1045  
        anyChange = true;
1046  
      }
1047  
    if (anyChange)
1048  
      reTok(tok);
1049  
  }
1050  
  
1051  
  static void namedThreads(L<S> tok) {
1052  
    for (int i = 0; i < 100; i++) {
1053  
      int idx = findCodeTokens(tok, "thread", "<quoted>", "{");
1054  
      if (idx < 0) idx = findCodeTokens(tok, "thread", "<id>", "{");
1055  
      if (idx < 0)
1056  
        break;
1057  
      int j = findEndOfBracketPart(tok, idx+4);
1058  
      S tName = tok.get(idx+2);
1059  
      
1060  
      S var = "_t_" + i;
1061  
      S pre = "{ /*nt*/ Thread " + var + " = new Thread(" + tName + ") {\n" +
1062  
        "public void run() { /* in run */ pcall { /* in thread */ \n";
1063  
      S post = "/* in thread */ } /* in run */ }\n};\n" +
1064  
        var + ".start(); }";
1065  
1066  
      tok.set(idx, pre);
1067  
      tok.set(idx+2, "");
1068  
      tok.set(idx+4, "");
1069  
      tok.set(j-1, post);
1070  
      //print(join(subList(tok, idx, j)));
1071  
      reTok(tok, idx, j);
1072  
    }
1073  
  }
1074  
  
1075  
  static void threads(L<S> tok) {
1076  
    for (bool daemon : litlist(false, true))
1077  
      for (int i = 0; i < 100; i++) {
1078  
        int idx = findCodeTokens(tok, daemon ? "daemon" : "thread", "{");
1079  
        if (idx < 0)
1080  
          break;
1081  
        int j = findEndOfBracketPart(tok, idx+2);
1082  
  
1083  
        S var = "_t_" + i;
1084  
        S pre = "{ Thread " + var + " = new Thread() {\n" +
1085  
          "public void run() { pcall\n";
1086  
        S post = "} }\n};\n" +
1087  
          (daemon ? var + ".setDaemon(true);\n" : "") +
1088  
          var + ".start(); }";
1089  
  
1090  
        tok.set(idx, pre);
1091  
        tok.set(j-1, post);
1092  
        reTok(tok, idx, j);
1093  
      }
1094  
  }
1095  
  
1096  
  static Map<S, S> sf;
1097  
  
1098  
  static L<S> standardFunctions(L<S> tok) {
1099  
    if (sf == null) {
1100  
      L<S> standardFunctions = concatLists(
1101  
        (L) loadVariableDefinition(cacheGet("#761"), "standardFunctions"),
1102  
        (L) loadVariableDefinition(cacheGet("#1006654"), "standardFunctions"));
1103  
1104  
      sf = new HashMap();
1105  
      for (String x : standardFunctions) {
1106  
        String[] f = x.split("/");
1107  
        sf.put(f[1], f[0]);
1108  
      }
1109  
    }
1110  
    
1111  
    for (int i = 0; ; i++) {
1112  
      Set<String> defd = new HashSet(findFunctions(tok));
1113  
1114  
      // changes tok
1115  
      Set<String> invocations = findFunctionInvocations(tok, sf);
1116  
1117  
      //print("Functions invoked: " + structure(invocations));
1118  
      List<String> needed = diff(invocations, defd);
1119  
      if (needed.isEmpty())
1120  
        break;
1121  
      print("Adding functions: " + join(" " , needed));
1122  
        
1123  
      new L<S> added;
1124  
      new StringBuilder buf;
1125  
      new L<S> preload;
1126  
      
1127  
      for (S x : needed)
1128  
        if (sf.containsKey(x))
1129  
          preload.add(sf.get(x));
1130  
      cachePreload(preload);
1131  
      
1132  
      for (String x : cloneList(needed)) {
1133  
        if (defd.contains(x)) continue;
1134  
        
1135  
        String id = sf.get(x);
1136  
        if (id == null) {
1137  
          print("Standard function " + x + " not found.");
1138  
          needed.remove(x);
1139  
          continue;
1140  
        }
1141  
        //print("Adding function: " + x + " (" + id + ")");
1142  
         
1143  
        S function = cacheGet(id);
1144  
        if (("\n" + function).contains("\n!")) print("Warning: " + id + " contains translators.");
1145  
        
1146  
        buf.append(function).append("\n");
1147  
        added.add(x);
1148  
        defd.addAll(findFunctionDefs(javaTok(function)));
1149  
      }
1150  
      tok = includeInMainLoaded(tok, str(buf));
1151  
      // defd = new HashSet(findFunctions(tok));
1152  
      //print("Functions added: " + structure(added));
1153  
      
1154  
      for (String x : needed)
1155  
        if (!defd.contains(x)) {
1156  
          print(join(tok));
1157  
          fail("Function not defined properly: " + x);
1158  
        }
1159  
      //print("Iteration " + (i+2));
1160  
      if (i >= 1000) fail("Too many iterations");
1161  
    }
1162  
    
1163  
    ret tok;
1164  
  }
1165  
  
1166  
  static L<S> findFunctions(L<S> tok) {
1167  
    //ret findFunctionDefinitions(join(findMainClass(tok)));
1168  
    ret findFunctionDefs(findMainClass(tok));
1169  
  }
1170  
  
1171  
  static S cacheGet(S snippetID) {
1172  
    snippetID = formatSnippetID(snippetID);
1173  
    S text = snippetCache.get(snippetID);
1174  
    if (text == null)
1175  
      snippetCache.put(snippetID, text = loadSnippet(snippetID));
1176  
    ret text;
1177  
  }
1178  
  
1179  
  static void cachePreload(L<S> ids) {
1180  
    new L<S> needed;
1181  
    for (S id : ids)
1182  
      if (!snippetCache.containsKey(formatSnippetID(id)))
1183  
        needed.add(formatSnippetID(id));
1184  
    if (l(needed) > 1) {
1185  
      L<S> texts = loadSnippets(needed);
1186  
      for (int i = 0; i < l(needed); i++)
1187  
        if (texts.get(i) != null)
1188  
          snippetCache.put(needed.get(i), texts.get(i));
1189  
    }
1190  
  }
1191  
  
1192  
  static L<S> jtok(L<S> tok) {
1193  
    ret jtok(join(tok));
1194  
  }
1195  
  
1196  
  static L<S> jtok(S s) {
1197  
    L<S> l = javaTok(s);
1198  
    ret useIndexedList ? new IndexedList2(l) : l;
1199  
  }
1200  
  
1201  
  // works on Java level (no "sclass" etc)
1202  
  // returns list of classes we have (useful for other processing)
1203  
  static Set<S> addLibraryClasses(L<S> tok, S... data) {
1204  
    new HashSet<S> have;
1205  
    for (L<S> c : innerClassesOfMain(tok))
1206  
      have.add(getClassDeclarationName(c));
1207  
    have.addAll(tok_importedClassNames(tok));
1208  
    
1209  
    L<S> idx = IndexedList2.ensureIndexed(tok);
1210  
    for (int i = 0; i+1 < l(data); i++) {
1211  
      S className = data[i], snippetID = data[i+1];
1212  
      if (idx.contains(className)
1213  
        && !have.contains(className)) {
1214  
        print("Adding class " + className + " / " + snippetID);
1215  
        snippetID = formatSnippetID(snippetID);
1216  
        S text = cacheGet(snippetID);
1217  
        includeInMainLoaded(tok, text);
1218  
        L<S> ct = javaTok(text);
1219  
        jreplace (ct, "sclass", "static class");
1220  
        jreplace (ct, "sinterface", "static interface");
1221  
        tok_autoCloseBrackets(ct);
1222  
        for (L<S> c : allClasses(ct))
1223  
          have.add(getClassDeclarationName(c));
1224  
        if (!have.contains(className))
1225  
          fail("Wrongly defined class: " + className + " / " + snippetID);
1226  
      }
1227  
    }
1228  
    
1229  
    ret have;
1230  
  }
1231  
  
1232  
  // magically append ".class" to class name references
1233  
  static void expandClassReferences(L<S> tok, Set<S> classNames) {
1234  
    bool change = false;
1235  
    for (int i = 3; i+2 < l(tok); i += 2)
1236  
      if (classNames.contains(tok.get(i))) {
1237  
        S s = tok.get(i-2), t = tok.get(i+2);
1238  
        if (eqOneOf(s, "instanceof", "new", ".", "<", "implements", "throws", "extends", "/", "nu")) continue;
1239  
        if (isIdentifier(s)) continue; // XXX?
1240  
        if (eq(s, ",") && eqOneOf(_get(tok, i-6), "implements", "throws")) continue;
1241  
        // TODO: longer lists
1242  
        
1243  
        // check for cast
1244  
        if (eq(s, "(") && eq(t, ")")
1245  
          && i >= 5) {
1246  
            if (neq(get(tok, i+4), "{")) {
1247  
              S x = tok.get(i-4);
1248  
              if (!isIdentifier(x)) continue;
1249  
              if (eqOneOf(x, "ret", "return")) continue;
1250  
            }
1251  
          }
1252  
        if (eqOneOf(t, ",", ")", ";", ":")) {
1253  
          tok.set(i, tok.get(i) + ".class");
1254  
          change = true;
1255  
        }
1256  
      }
1257  
    if (change) reTok(tok);
1258  
  }
1259  
  
1260  
  // "<id>/<ClassName>" => "((ClassName) <id>)"
1261  
  static void slashCasts(L<S> tok, final Set<S> classNames) {
1262  
    jreplace(tok, "<id>/<id>", "(($3) $1)", new O() {
1263  
      O get(L<S> tok, int i) {
1264  
        ret classNames.contains(tok.get(i+5));
1265  
      }
1266  
    });
1267  
  }
1268  
  
1269  
  // +var => "var", +var
1270  
  static void expandVarCopies(L<S> tok) {
1271  
    bool change = false;
1272  
    for (int i = 3; i+2 < l(tok); i += 2) {
1273  
      if (!eq(tok.get(i), "+")) continue;
1274  
      if (!eqOneOf(tok.get(i-2), "(", ",")) continue;
1275  
      S s = tok.get(i+2);
1276  
      if (!isIdentifier(s)) continue;
1277  
      tok.set(i, quote(s) + ", ");
1278  
      change = true;
1279  
    }
1280  
    if (change) reTok(tok);
1281  
  }
1282  
  
1283  
  static void processConceptsDot(L<S> tok) {
1284  
    bool change;
1285  
    do {
1286  
      change = false;
1287  
      for (int i : jfindAll(tok, "concepts."))
1288  
        if (contains(get(tok, i+3), "\n")) {
1289  
          replaceTokens(tok, i, i+3, "!" + "include #1004863 // Dynamic Concepts");
1290  
          reTok(tok, i, i+3);
1291  
          change = true;
1292  
          break;
1293  
        }
1294  
    } while (change);
1295  
  }
1296  
  
1297  
  static void addFieldOrder(L<S> tok, int i) {
1298  
    int idx = findCodeTokens(tok, i, false, "{");
1299  
    if (idx < 0) ret;
1300  
    int j = findEndOfBracketPart(tok, idx+2);
1301  
    L<S> vars = allVarNames(subList(tok, idx+1, j-1));
1302  
    print("addFieldOrder " + struct(vars));
1303  
    if (!vars.contains("_fieldOrder")
1304  
      && !isSortedList(vars)) {
1305  
      print("Adding field order");
1306  
      tok.set(idx+2, "static String _fieldOrder = " + quote(join(" ", vars)) + ";\n  " + tok.get(idx+2));
1307  
      // reTok has to be done by caller
1308  
    }
1309  
  }
1310  
  
1311  
  static void caseAsVariableName(L<S> tok) {
1312  
    if (!tok.contains("case")) ret;
1313  
    for (int i = 1; i+2 < l(tok); i += 2) {
1314  
      S t = tok.get(i+2);
1315  
      if (tok.get(i).equals("case")
1316  
        && !(t.startsWith("'") || isInteger(t) || isIdentifier(t)))
1317  
        tok.set(i, "_case");
1318  
    }
1319  
  }
1320  
  
1321  
  static void continueAsFunctionName(L<S> tok) {
1322  
    jreplace(tok, "continue(", "_continue(");
1323  
  }
1324  
  
1325  
  // func bla => "bla" - and "please include function bla."
1326  
  static void functionReferences(L<S> tok) {
1327  
    int i;
1328  
    for (S keyword : ll("f", "func"))
1329  
      while ((i = jfind(tok, keyword + " <id>", new O() {
1330  
        O get(L<S> tok, int i) {
1331  
          ret !eq(tok.get(i+3), "instanceof");
1332  
        }
1333  
      })) >= 0) {
1334  
        S f = tok.get(i+2);
1335  
        clearTokens(tok, i, i+2);
1336  
        tok.set(i+2, quote(f));
1337  
        reTok(tok, i, i+2);
1338  
        tok.set(l(tok)-1, last(tok) + "\nplease include function " + f + ".");
1339  
        reTok(tok, l(tok)-1, l(tok));
1340  
      }
1341  
  }
1342  
  
1343  
  // # 123 => "#123"
1344  
  static void directSnippetRefs(L<S> tok) {
1345  
    int i;
1346  
    while ((i = jfind(tok, "#<int>", new O() {
1347  
      bool get(L<S> tok, int i) {
1348  
        ret neq(_get(tok, i-1), "include");
1349  
      }
1350  
    })) >= 0) {
1351  
      S id = tok.get(i+2);
1352  
      clearTokens(tok, i+1, i+3);
1353  
      tok.set(i, quote("#" + id));
1354  
      reTok(tok, i, i+3);
1355  
    }
1356  
  }
1357  
  
1358  
  static void quicknu(L<S> tok) {
1359  
    jreplace(tok, "nu <id>(", "nu($2.class, ");
1360  
    jreplace(tok, "nu <id>", "new $2");
1361  
  }
1362  
  
1363  
  // fill variable innerClasses_list
1364  
  static void innerClassesVar(L<S> tok) {
1365  
    if (!tok.contains("myInnerClasses_list")) ret;
1366  
    
1367  
    new L<S> have;
1368  
    for (L<S> c : innerClassesOfMain(tok))
1369  
      have.add(getClassDeclarationName(c));
1370  
1371  
    int i = jfind(tok, ">myInnerClasses_list;");
1372  
    if (i < 0) ret;
1373  
    tok.set(i+4, "=litlist(\n" + joinQuoted(", ", have) + ");");
1374  
    reTok(tok, i+4, i+5);
1375  
  }
1376  
}

Author comment

Began life as a copy of #759

download  show line numbers  debug dex  old transpilations   

Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1006723
Snippet name: Higher-Level-Transpiled #759 Spike [old]
Eternal ID of this version: #1006723/5
Text MD5: a6c22aa10a7deebb5e1a08a5ee215a1b
Transpilation MD5: 8249eb1ac931a10d7e21c6ee70896a73
Author: stefan
Category:
Type: JavaX translator
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2017-02-03 00:09:23
Source code size: 46123 bytes / 1376 lines
Pitched / IR pitched: No / No
Views / Downloads: 437 / 452
Version history: 4 change(s)
Referenced in: [show references]