1 | !747 |
2 | |
3 | m { |
4 | !include #1001496 // Matches |
5 | !include #1000882 // EGDiff |
6 | !include #1000883 // BlockDiffer |
7 | !include #1001065 // DialoGIO |
8 | |
9 | !include #1002662 // isTrue |
10 | |
11 | !include #1003674 // Standard Classes List |
12 | |
13 | static int varCount; |
14 | |
15 | static new Map<S, S> snippetCache; |
16 | |
17 | p { |
18 | print("759 STARTING " + identityHashCode(main.class)); |
19 | varCount = 0; |
20 | L<S> tok = tokMainJava(); |
21 | |
22 | L ts = findTranslators(toLines(join(tok))); |
23 | print("Translators in source at start: " + structure(ts)); |
24 | |
25 | // "duplicate" statement |
26 | |
27 | L<S> lines = toLines(join(tok)); |
28 | call(getJavaX(), "findTranslators", lines); |
29 | new Matches m; |
30 | if (match("duplicate *", fromLines(lines), m)) { |
31 | // actual copying - unused |
32 | // tok = javaTok(loadSnippet(m.get(0))); |
33 | |
34 | // reference by include() |
35 | tok = javaTok("m { p { callMain(include(" + quote(m.get(0)) + ")); } }"); |
36 | } |
37 | |
38 | // add m { } |
39 | |
40 | if (!hasCodeTokens(tok, "m", "{") && !hasCodeTokens(tok, "main", "{") && !hasCodeTokens(tok, "class", "main")) |
41 | tok = javaTok(moveImportsUp("m {\n" + join(tok) + "\n}")); |
42 | |
43 | // standard translate |
44 | |
45 | //tok = rtq(tok, "#636"); |
46 | tok = autoImports(tok); |
47 | |
48 | ts = findTranslators(toLines(join(tok))); |
49 | print("Translators in source: " + structure(ts)); |
50 | tok = javaTok(defaultTranslate(join(tok))); |
51 | |
52 | print("end of default translate"); |
53 | //print(join(tok)); |
54 | |
55 | tok = processIncludes(tok); // before standard functions |
56 | earlyStuff(tok); |
57 | |
58 | int safety = 0; |
59 | boolean same; |
60 | do { |
61 | S before = join(tok); |
62 | tok = standardFunctions(tok); |
63 | tok = stdstuff(tok); // standard functions and all the keywords |
64 | S diff; |
65 | long startTime = now(); |
66 | diff = unidiff(before, join(tok)); |
67 | print("unidiff: " + (now()-startTime) + " ms"); |
68 | same = eq(diff, ""); |
69 | if (!same) { |
70 | print("Not same " + safety + "."); |
71 | //print(indent(2, diff)); |
72 | } |
73 | if (safety++ >= 10) fail("safety 10 error!"); |
74 | } while (!same); |
75 | |
76 | // POST-PROCESSING after stdstuff loop |
77 | |
78 | tok = javaTok(quicknew(join(tok))); |
79 | tok = extendClasses(tok); |
80 | libs(tok); |
81 | sourceCodeLine(tok); |
82 | throwFail(tok); |
83 | |
84 | saveMainJava(tok); |
85 | } |
86 | |
87 | // now also for interfaces |
88 | static L<S> loadClass(L<S> tok, S className, S snippetID) { |
89 | if (containsToken(tok, className) |
90 | && !hasCodeTokens(tok, "class", className) && !hasCodeTokens(tok, "interface", className) |
91 | && !tok_importsClassNamed(tok, className)) { |
92 | snippetID = formatSnippetID(snippetID); |
93 | S text = snippetCache.get(snippetID); |
94 | if (text == null) |
95 | snippetCache.put(snippetID, text = loadSnippet(snippetID)); |
96 | tok = includeInMainLoaded(tok, text); |
97 | } |
98 | ret tok; |
99 | } |
100 | |
101 | static L<S> stdstuff(L<S> tok) { |
102 | //if (++level >= 10) fail("woot? 10"); |
103 | |
104 | print("stdstuff!"); |
105 | L<S> lines = toLines(join(tok)); |
106 | L ts = findTranslators(lines); |
107 | tok = javaTok(fromLines(lines)); |
108 | if (nempty(ts)) { |
109 | //print("Warning: Contains translators."); |
110 | print("DROPPING TRANSLATORS: " + structure(ts)); |
111 | } |
112 | |
113 | tok = quickmain(tok); |
114 | tok = processIncludes(tok); |
115 | earlyStuff(tok); |
116 | tok = multilineStrings(tok); |
117 | listComprehensions(tok); |
118 | |
119 | tok = replaceKeywordBlock(tok, "answer", |
120 | "static S answer(S s) {\nnew Matches m;\n", |
121 | "\nret null;\n}"); |
122 | |
123 | tok = replaceKeywordBlock(tok, "loading", |
124 | "{ JWindow _loading_window = showLoadingAnimation(); try {", |
125 | "} finally { disposeWindow(_loading_window); }}"); |
126 | |
127 | tok = replaceKeywordBlock(tok, "html", |
128 | "static O html(S uri, fMap<S, S> params) {\n", "}"); |
129 | |
130 | // "static sync" => static synchronized |
131 | jreplace(tok, "static sync", "static synchronized"); |
132 | |
133 | // "sclass" => static class |
134 | jreplace(tok, "sclass", "static class"); |
135 | |
136 | // "asclass" => abstract static class |
137 | jreplace(tok, "asclass", "abstract static class"); |
138 | |
139 | // "sinterface" => static interface |
140 | jreplace(tok, "sinterface", "static interface"); |
141 | |
142 | // "ssynchronized" => static synchronized |
143 | jreplace(tok, "ssynchronized", "static synchronized"); |
144 | |
145 | jreplace(tok, "ssvoid", "static synchronized void"); |
146 | jreplace(tok, "svoid", "static void"); |
147 | jreplace(tok, "sbool", "static bool"); |
148 | jreplace(tok, "sint", "static int"); |
149 | jreplace(tok, "snew", "static new"); |
150 | jreplace(tok, "sv <id>", "static void $2"); |
151 | jreplace(tok, "pvoid", "public void"); |
152 | |
153 | // "sS" => static S |
154 | jreplace(tok, "sS", "static S"); |
155 | |
156 | // "sO" => static O |
157 | jreplace(tok, "sO", "static O"); |
158 | |
159 | // "sL" => static L |
160 | jreplace(tok, "sL", "static L"); |
161 | |
162 | // "toString {" => "public S toString() {" |
163 | jreplace(tok, "toString {", "public S toString() {"); |
164 | |
165 | jreplace(tok, "Int", "Integer"); |
166 | jreplace(tok, "Bool", "Boolean"); |
167 | |
168 | // "catch {" => "catch (Throwable _e) {" |
169 | jreplace(tok, "catch {", "catch (Throwable _e) {"); |
170 | |
171 | // "catch X e {" => "catch (X e) {" |
172 | jreplace(tok, "catch <id> <id> {", "catch ($2 $3) {"); |
173 | |
174 | // "catch e {" => "catch (Throwable e) {" (if e is lowercase) |
175 | jreplace(tok, "catch <id> {", "catch (Throwable $2) {", new O() { |
176 | bool check(L<S> tok, int i) { |
177 | S word = tok.get(i+3); |
178 | ret startsWithLowerCase(word); |
179 | } |
180 | }); |
181 | |
182 | // some crazy fancy syntax |
183 | jreplace(tok, "set <id>;", "$2 = true;"); |
184 | |
185 | jreplace(tok, "fS", "final S"); |
186 | jreplace(tok, "fO", "final O"); |
187 | jreplace(tok, "fL", "final L"); |
188 | jreplace(tok, "fMap", "final Map"); |
189 | jreplace(tok, "fRunnable", "final Runnable"); |
190 | jreplace(tok, "f int", "final int"); |
191 | |
192 | jreplace(tok, "new <id> {", "new $2() {"); |
193 | |
194 | // shortened method declarations - hopefully that works |
195 | |
196 | jreplace(tok, "void <id> {", "$1 $2() {"); |
197 | jreplace(tok, "String <id> {", "$1 $2() {"); |
198 | jreplace(tok, "Object <id> {", "$1 $2() {"); |
199 | jreplace(tok, "List <id> {", "$1 $2() {"); |
200 | |
201 | // "is a X" => instanceof X |
202 | |
203 | jreplace(tok, "is a <id>", "instanceof $3"); |
204 | |
205 | // func keyword for lambdas - now automatically quines toString() |
206 | |
207 | int i; |
208 | while ((i = jfind(tok, "func(")) >= 0) { |
209 | int argsFrom = i+4, argsTo = findCodeTokens(tok, i, false, ")"); |
210 | int idx = findCodeTokens(tok, argsTo, false, "{"); |
211 | int j = findEndOfBracketPart(tok, idx+2); |
212 | L<S> contents = subList(tok, idx+1, j-1); |
213 | replaceTokens(tok, i, j, "new O { O get(" + join(subList(tok, argsFrom, argsTo-1)) + ") { " + tok_addReturn(contents) + " }\n" + |
214 | " public S toString() { ret " + quote(trim(join(contents))) + "; }}"); |
215 | reTok(tok); |
216 | } |
217 | |
218 | while ((i = jfind(tok, "voidfunc(")) >= 0) { |
219 | int argsFrom = i+4, argsTo = findCodeTokens(tok, i, false, ")"); |
220 | int idx = findCodeTokens(tok, argsTo, false, "{"); |
221 | int j = findEndOfBracketPart(tok, idx+2); |
222 | L<S> contents = subList(tok, idx+1, j-1); |
223 | replaceTokens(tok, i, j, "new O { void get(" + join(subList(tok, argsFrom, argsTo-1)) + ") { " + join(contents) + " }\n" + |
224 | " public S toString() { ret " + quote(trim(join(contents))) + "; }}"); |
225 | reTok(tok); |
226 | } |
227 | |
228 | while ((i = jfind(tok, "func {")) >= 0) { |
229 | int idx = findCodeTokens(tok, i, false, "{"); |
230 | int j = findEndOfBracketPart(tok, idx+2); |
231 | L<S> contents = subList(tok, idx+1, j-1); |
232 | replaceTokens(tok, i, j, "new O { O get() { " + tok_addReturn(contents) + " }\n" + |
233 | " public S toString() { ret " + quote(trim(join(contents))) + "; }}"); |
234 | reTok(tok); |
235 | } |
236 | /*tok = replaceKeywordBlock(tok, "func", |
237 | "new O { O get() { ret", |
238 | ";}}");*/ |
239 | |
240 | // * constructors |
241 | if (hasCodeTokens(tok, "\\*", "(")) |
242 | tok = expandStarConstructors(tok); |
243 | |
244 | // Do this BEFORE awt replacement! ("p-awt" contains "awt" token) |
245 | tok = replaceKeywordBlock(tok, "p-substance", "p-awt { substance();", "}"); |
246 | tok = replaceKeywordBlock(tok, "p-awt", "p { awt {", "}}"); |
247 | |
248 | tok = replaceKeywordBlock(tok, |
249 | "awt", |
250 | "swingLater(r {", |
251 | "});"); |
252 | |
253 | // crazy stuff |
254 | |
255 | jreplace (tok, "for <id> over <id>:", "for (int $2 = 0; $2 < l($4); $2++)"); |
256 | |
257 | // STANDARD CLASSES & INTERFACES |
258 | |
259 | for (S line : toLinesFullTrim(standardClasses)) { |
260 | int idx = line.indexOf('/'); |
261 | tok = loadClass(tok, line.substring(0, idx), line.substring(idx+1)); |
262 | } |
263 | |
264 | tok = loadClass(tok, "Quine", "#1003601"); |
265 | tok = loadClass(tok, "Var", "#1003550"); |
266 | tok = loadClass(tok, "TableFinder", "#1000850"); |
267 | tok = loadClass(tok, "Snippet", "#1003519"); |
268 | tok = loadClass(tok, "GermanDateAdapter", "#1003510"); |
269 | tok = loadClass(tok, "BF", "#1003489"); |
270 | tok = loadClass(tok, "BotChat", "#1003499"); |
271 | tok = loadClass(tok, "StrictTreeMap", "#1003482"); |
272 | tok = loadClass(tok, "E", "#1003474"); |
273 | tok = loadClass(tok, "Dialog", "#1003356"); |
274 | tok = loadClass(tok, "OccTree2", "#1003407"); |
275 | tok = loadClass(tok, "OccTree", "#1003331"); |
276 | tok = loadClass(tok, "EGDiff", "#1000882"); |
277 | tok = loadClass(tok, "BlockDiffer", "#1000883"); |
278 | tok = loadClass(tok, "Q", "#1000934"); |
279 | tok = loadClass(tok, "F", "#1003033"); |
280 | tok = loadClass(tok, "LoadEnv", "#1002955"); |
281 | tok = loadClass(tok, "CIString", "#1002873"); |
282 | tok = loadClass(tok, "PersistentCIMap", "#1002872"); |
283 | tok = loadClass(tok, "EvalTransform", "#1002867"); |
284 | tok = loadClass(tok, "Prolog", "#1002884"); // Yay! |
285 | tok = loadClass(tok, "IEngine", "#1002809"); |
286 | tok = loadClass(tok, "Native", "#1002774"); |
287 | tok = loadClass(tok, "ProgramScan", "#1000804"); |
288 | tok = loadClass(tok, "SNLMatches", "#1002748"); |
289 | tok = loadClass(tok, "SNLInfo", "#1002744"); |
290 | tok = loadClass(tok, "Lisp", "#1002696"); |
291 | tok = loadClass(tok, "Explain", "#1002529"); |
292 | tok = loadClass(tok, "NanoHTTPD", "#1001651"); |
293 | tok = loadClass(tok, "Source", "#1002461"); |
294 | tok = loadClass(tok, "ShowBigText", "#1001425"); |
295 | tok = loadClass(tok, "DialogIO", "#1001065"); |
296 | tok = loadClass(tok, "Matches", "#1001496"); |
297 | tok = loadClass(tok, "MultiMap", "#1001296"); |
298 | tok = loadClass(tok, "MultiSet", "#1000988"); |
299 | tok = loadClass(tok, "MultiHashSet", "#1003597"); |
300 | tok = loadClass(tok, "PersistentLog", "#1001972"); |
301 | tok = loadClass(tok, "PersistentMap", "#1002063"); |
302 | tok = loadClass(tok, "PersistentTreeMap", "#1003529"); |
303 | tok = loadClass(tok, "Rat", "#1002052"); |
304 | tok = loadClass(tok, "DiskTextMap", "#1002087"); |
305 | |
306 | // image classes (now static) |
307 | |
308 | tok = loadClass(tok, "ImageSurface", "#1002470"); |
309 | tok = loadClass(tok, "RGB", "#1002470"); |
310 | tok = loadClass(tok, "RGBImage", "#1002470"); |
311 | |
312 | // the infamous missing functions (usually caused by class Matches) |
313 | if (!hasCodeTokens(tok, "String", "unquote") && containsToken(tok, "unquote")) { |
314 | print("Adding unquote"); |
315 | tok = includeInMain(tok, "#1001735"); |
316 | } |
317 | |
318 | if (!hasCodeTokens(tok, "String", "formatSnippetID") && containsToken(tok, "formatSnippetID")) { |
319 | print("Adding formatSnippetID"); |
320 | tok = includeInMain(tok, "#1000709"); |
321 | } |
322 | |
323 | /*boolean needsExpander = containsToken(tok, "S") || containsToken(tok, "L") || containsToken(tok, "O") || containsToken(tok, "ret"); |
324 | if (needsExpander) |
325 | tok = rtq(tok, "#723");*/ |
326 | tok = expandShortTypes(tok); |
327 | |
328 | if (containsToken(tok, "cast")) { |
329 | //tok = rtq(tok, "#1000482"); |
330 | S s = join(tok); |
331 | s = s.replaceAll("(\\w+<[\\w\\s,\\[\\]]+>|\\w+|\\w+\\[\\]|\\w+\\[\\]\\[\\])\\s+(\\w+)\\s*=\\s*cast(\\W[^;]*);", "$1 $2 = ($1) ($3);"); |
332 | tok = javaTok(s); |
333 | } |
334 | |
335 | for (S keyword : ll("runnable", "r")) |
336 | tok = replaceKeywordBlock(tok, |
337 | keyword, |
338 | "new Runnable() { public void run() { try {", |
339 | "} catch (Exception __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}}"); |
340 | |
341 | /*if (hasCodeTokens(tok, "runnable", "{")) |
342 | tok = rtq(tok, "#711");*/ |
343 | |
344 | tok = replaceKeywordBlock(tok, |
345 | "expectException", |
346 | "{ bool __ok = false; try {", |
347 | "} catch { __ok = true; } assertTrue(\"expected exception\", __ok); }"); |
348 | |
349 | while ((i = tok.indexOf("tex")) >= 0) { |
350 | tok.set(i, "throws Exception"); |
351 | tok = javaTok(tok); |
352 | } |
353 | |
354 | while ((i = findCodeTokens(tok, "while", "true")) >= 0) { |
355 | tok.set(i+2, "(true)"); |
356 | tok = javaTok(tok); |
357 | } |
358 | |
359 | // "null;" instead of "return null;" |
360 | jreplace(tok, "{ null;", "$1 return null;"); |
361 | jreplace(tok, "} null;", "$1 return null;"); |
362 | jreplace(tok, "; null;", "$1 return null;"); |
363 | jreplace(tok, ") null;", "$1 return null;"); |
364 | |
365 | // "false;" instead of "return false;" |
366 | jreplace(tok, "} false;", "} return false;"); |
367 | jreplace(tok, "; false;", "; return false;"); |
368 | jreplace(tok, ") false;", ") return false;"); |
369 | |
370 | // "true;" instead of "return true;" |
371 | jreplace(tok, "} true;", "} return true;"); |
372 | jreplace(tok, "; true;", "; return true;"); |
373 | jreplace(tok, ") true;", ") return true;"); |
374 | |
375 | // "myFunction;" instead of "myFunction();" - quite rough |
376 | O cond = new O() { |
377 | bool check(L<S> tok, int i) { |
378 | S word = tok.get(i+3); |
379 | //print("single word: " + word); |
380 | ret !litlist("break", "continue", "return").contains(word); |
381 | } |
382 | }; |
383 | for (S pre : litlist("}", ";")) |
384 | jreplace(tok, pre + " <id>;", "$1 $2();", cond); |
385 | |
386 | // shorter match syntax for answer methods |
387 | |
388 | jreplace(tok, "if <quoted>", "if (match($2, s, m))"); |
389 | jreplace(tok, "if match <quoted>", "if (match($3, s, m))"); |
390 | |
391 | // extra commas ("litlist(1, 2,)") |
392 | |
393 | jreplace(tok, ",)", ")"); |
394 | |
395 | // additional translations (if necessary) |
396 | |
397 | if (hasCodeTokens(tok, "pcall", "{")) |
398 | tok = replaceKeywordBlock(tok, |
399 | "pcall", |
400 | "try {", |
401 | "} catch (Throwable __e) { printStackTrace(__e); }"); |
402 | |
403 | tok = dialogHandler(tok); |
404 | |
405 | tok = replaceKeywordBlock(tok, "exceptionToUser", |
406 | "try {", |
407 | "} catch (Throwable __e) { ret exceptionToUser(__e); }"); |
408 | |
409 | if (hasCodeTokens(tok, "twice", "{")) |
410 | tok = replaceKeywordBlock(tok, "twice", |
411 | "for (int __twice = 0; __twice < 2; __twice++) {", |
412 | "}"); |
413 | |
414 | while ((i = findCodeTokens(tok, "repeat", "*", "{")) >= 0) { |
415 | S v = makeVar("repeat"); |
416 | tok.set(i, "for (int " + v + " = 0; " + v + " < " + tok.get(i+2) + "; " + v + "++)"); |
417 | tok.set(i+2, ""); |
418 | tok = javaTok(tok); |
419 | } |
420 | |
421 | tok = replaceKeywordBlockDyn(tok, |
422 | "time", |
423 | new O() { S[] get() { |
424 | S var = makeVar("startTime"); |
425 | ret new S[] { |
426 | "{ long " + var + " = now(); try { ", |
427 | "} finally { " + var + " = now()-" + var + "; saveTiming(" + var + "); } }"}; |
428 | }}); |
429 | |
430 | if (hasCodeTokens(tok, "assertFail", "{")) { |
431 | S var = makeVar("oops"); |
432 | |
433 | tok = replaceKeywordBlock(tok, |
434 | "assertFail", |
435 | "boolean " + var + " = false; try {", |
436 | "\n" + var + " = true; } catch (Exception e) { /* ok */ } assertFalse(" + var + ");"); |
437 | } |
438 | |
439 | tok = replaceKeywordBlock(tok, |
440 | "yo", |
441 | "try {", |
442 | "} catch (Exception " + makeVar("e") + ") { ret false; }"); |
443 | |
444 | tok = replaceKeywordBlock(tok, |
445 | "awtIfNecessary", |
446 | "swingNowOrLater(r {", |
447 | "});"); |
448 | |
449 | if (hasCodeTokens(tok, "ctex")) |
450 | tok = ctex(tok); |
451 | |
452 | tok = replaceKeywordBlock(tok, |
453 | "actionListener", |
454 | "new java.awt.event.ActionListener() { " + |
455 | "public void actionPerformed(java.awt.event.ActionEvent _evt) {", |
456 | "}}"); |
457 | |
458 | /*if (hasCodeTokens(tok, "actionListener", "{")) |
459 | tok = rtq(tok, "#614");*/ |
460 | |
461 | // named threads |
462 | if (hasCodeTokens(tok, "thread", "<quoted>", "{")) |
463 | tok = rtq(tok, "#1001362"); |
464 | |
465 | // unnamed threads |
466 | if (hasCodeTokens(tok, "thread", "{") || hasCodeTokens(tok, "daemon", "{")) |
467 | tok = rtq(tok, "#721"); |
468 | |
469 | // try answer |
470 | while ((i = findCodeTokens(tok, "try", "answer")) >= 0) { |
471 | int j = findEndOfStatement(tok, i); |
472 | S v = makeVar("a"); |
473 | tok.set(i, "S " + v); |
474 | tok.set(i+2, "="); |
475 | tok.set(j-1, "; if (!empty(" + v + ")) ret " + v + ";"); |
476 | tok = javaTok(tok); |
477 | } |
478 | |
479 | tok = javaTok(moveImportsUp(join(tok))); |
480 | |
481 | ret tok; |
482 | } |
483 | |
484 | static L<S> multilineStrings(L<S> tok) { |
485 | for (int i = 1; i < tok.size(); i += 2) { |
486 | S t = tok.get(i); |
487 | if (t.startsWith("[") && isQuoted (t)) |
488 | tok.set(i, quote(unquote(t))); |
489 | } |
490 | ret tok; |
491 | } |
492 | |
493 | static L<S> quickmain(L<S> tok) { |
494 | int i = findCodeTokens(tok, "main", "{"); |
495 | if (i < 0) i = findCodeTokens(tok, "m", "{"); |
496 | if (i >= 0 && !(i-2 > 0 && tok.get(i-2).equals("class"))) |
497 | tok.set(i, "public class main"); |
498 | |
499 | i = findCodeTokens(tok, "psvm", "{"); |
500 | if (i < 0) i = findCodeTokens(tok, "p", "{"); |
501 | if (i >= 0) |
502 | tok.set(i, "public static void main(String[] args) throws Exception"); |
503 | |
504 | ret javaTok(tok); |
505 | } |
506 | |
507 | static S makeVar(S name) { |
508 | ret "_" + name + "_" + varCount++; |
509 | } |
510 | |
511 | static S makeVar() { ret makeVar(""); } |
512 | |
513 | static L<S> standardFunctions(L<S> tok) { |
514 | ret rtq(tok, "#1002474"); |
515 | } |
516 | |
517 | static L<S> rtq(L<S> tok, S id) { |
518 | ret runTranslatorQuick(tok, id); |
519 | } |
520 | |
521 | static L<S> expandShortTypes(L<S> tok) { |
522 | // replace <int> with <Integer> |
523 | for (int i = 1; i+4 < tok.size(); i += 2) |
524 | if (tok.get(i).equals("<") |
525 | && litlist(">", ",").contains(tok.get(i+4))) { |
526 | String type = tok.get(i+2); |
527 | if (type.equals("int")) type = "Integer"; |
528 | else if (type.equals("long")) type = "Long"; |
529 | tok.set(i+2, type); |
530 | } |
531 | |
532 | // O = Object, S = String, ret = return |
533 | for (int i = 1; i < tok.size(); i += 2) { |
534 | String t = tok.get(i); |
535 | if (t.equals("O")) t = "Object"; |
536 | if (t.equals("S")) t = "String"; |
537 | else if (t.equals("L")) t = "List"; |
538 | else if (t.equals("F")) t = "Function"; |
539 | else if (t.equals("ret")) t = "return"; |
540 | 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 |
541 | tok.set(i, t); |
542 | } |
543 | |
544 | ret tok; |
545 | } |
546 | |
547 | static L<S> autoImports(L<S> tok) { |
548 | S s = join(tok); |
549 | List<String> imports = findImports(s); |
550 | new StringBuilder buf; |
551 | for (String c : standardImportClasses) |
552 | if (!(imports.contains(c))) |
553 | buf.append("import " + c + ";\n"); |
554 | if (buf.length() == 0) ret tok; |
555 | ret javaTok(buf+s); |
556 | } |
557 | |
558 | static String[] standardImportClasses = { |
559 | "java.util.*", |
560 | "java.util.zip.*", |
561 | "java.util.List", |
562 | "java.util.regex.*", |
563 | "java.util.concurrent.*", |
564 | "java.util.concurrent.atomic.*", |
565 | "javax.swing.*", |
566 | "javax.swing.event.*", |
567 | "javax.swing.text.*", |
568 | "javax.swing.table.*", |
569 | "java.io.*", |
570 | "java.net.*", |
571 | "java.lang.reflect.*", |
572 | "java.lang.ref.*", |
573 | "java.lang.management.*", |
574 | "java.security.*", |
575 | "java.security.spec.*", |
576 | "java.awt.*", |
577 | "java.awt.event.*", |
578 | "java.awt.image.*", |
579 | "javax.imageio.*", |
580 | "java.math.*" |
581 | }; |
582 | |
583 | static L<S> expandStarConstructors(L<S> tok) { |
584 | mainLoop: for (int i = 3; i+6 < tok.size(); i += 2) { |
585 | String t = tok.get(i), l = tok.get(i-2); |
586 | if (!t.equals("*")) |
587 | continue; |
588 | if (!tok.get(i+2).equals("(")) |
589 | continue; |
590 | if (!eqOneOf(l, "}", "public", "private", "protected", ";", "{")) // is this correct...?? |
591 | continue; |
592 | |
593 | // ok, it seems like a constructor declaration. |
594 | // Now find class name by going backwards. |
595 | |
596 | int j = i, level = 1; |
597 | while (j > 0 && level > 0) { |
598 | t = tok.get(j); |
599 | if (t.equals("}")) ++level; |
600 | if (t.equals("{")) --level; |
601 | j -= 2; |
602 | } |
603 | |
604 | while (j > 0) { |
605 | t = tok.get(j); |
606 | if (t.equals("class")) { |
607 | String className = tok.get(j+2); |
608 | tok.set(i, className); // exchange constructor name! |
609 | |
610 | // now for the parameters. |
611 | // Syntax: *(Learner *learner) { |
612 | // We will surely add type inference here in time... :) |
613 | |
614 | j = i+2; |
615 | while (!tok.get(j).equals("{")) |
616 | j += 2; |
617 | int block = j+1; |
618 | for (int k = i+2; k < block-1; k += 2) |
619 | if (tok.get(k).equals("*")) { |
620 | tok.remove(k); |
621 | tok.remove(k); |
622 | block -= 2; |
623 | String name = tok.get(k); |
624 | tok.addAll(block, Arrays.asList(new String[] { |
625 | "\n ", "this", "", ".", "", name, " ", "=", " ", name, "", ";" })); |
626 | } |
627 | |
628 | continue mainLoop; |
629 | } |
630 | j -= 2; |
631 | } |
632 | } |
633 | ret tok; |
634 | } |
635 | |
636 | static L<S> processIncludes(L<S> tok) { |
637 | int safety = 0; |
638 | while (hasCodeTokens(tok, "!", "include") && ++safety < 100) |
639 | tok = processIncludesSingle(tok); |
640 | ret tok; |
641 | } |
642 | |
643 | static L<S> processIncludesSingle(L<S> tok) { |
644 | S s = join(tok); |
645 | Matcher m = Pattern.compile("\n\\s*!include (#\\d+)").matcher(s); |
646 | StringBuffer buf = new StringBuffer(); |
647 | while (m.find()) { |
648 | String includedSrc = loadSnippet(m.group(1)); |
649 | m.appendReplacement(buf, m.quoteReplacement("\n" + includedSrc)); |
650 | } |
651 | m.appendTail(buf); |
652 | ret javaTok(str(buf)); |
653 | } |
654 | |
655 | static L<S> ctex(L<S> tok) { |
656 | S s = join(tok); |
657 | Pattern regex = Pattern.compile("\\s+(no\\s+exceptions|ctex|null on exception)\\s*\\{"); |
658 | |
659 | for (int i = 0; i < 100; i++) { |
660 | Matcher matcher = regex.matcher(s); |
661 | if (!matcher.find()) |
662 | break; |
663 | String kind = matcher.group(1); |
664 | |
665 | System.out.println("Iteration " + (i+1)); |
666 | int start = matcher.start(), end = matcher.end(); |
667 | int endOfBlock = ctex_findEndOfBlock(s, end); |
668 | |
669 | String catchBlock, catchWhat; |
670 | if (kind.startsWith("null")) { |
671 | catchBlock = "return null;"; |
672 | catchWhat = "Throwable"; |
673 | } else { |
674 | catchBlock = "throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e);"; |
675 | catchWhat = "Throwable"; |
676 | } |
677 | |
678 | String tryBlock = " { try {\n " + |
679 | s.substring(end, endOfBlock) + "\n} catch (" + catchWhat + " __e) { " + catchBlock + " }"; |
680 | s = s.substring(0, start) + tryBlock + s.substring(endOfBlock); |
681 | } |
682 | ret javaTok(s); |
683 | } |
684 | |
685 | // start is the index AFTER the opening bracket |
686 | // returns index OF closing bracket |
687 | static int ctex_findEndOfBlock(String s, int start) { |
688 | int level = 1; |
689 | for (int i = start; i < s.length(); i++) { |
690 | if (s.charAt(i) == '{') ++level; |
691 | else if (s.charAt(i) == '}') --level; |
692 | if (level == 0) |
693 | return i; |
694 | } |
695 | return s.length(); |
696 | } |
697 | |
698 | static L<S> dialogHandler(L<S> tok) { |
699 | ret replaceKeywordBlock(tok, |
700 | "dialogHandler", |
701 | "new DialogHandler() {\n" + |
702 | "public void run(final DialogIO io) {", |
703 | "}}"); |
704 | } |
705 | |
706 | /*static S defaultTrans(S s) { |
707 | findTranslators... |
708 | }*/ |
709 | |
710 | static S quicknew(S s) { |
711 | // TODO: switch to tokenizing! |
712 | s = s.replaceAll("new\\s+(\\w+)\\s+(\\w+);", "$1 $2 = new $1();"); |
713 | s = s.replaceAll("new\\s+L<([\\w\\[\\]<>,\\s]+)>\\s+(\\w+);", "List<$1> $2 = new ArrayList<$1>();"); |
714 | s = s.replaceAll("new\\s+List<([\\w\\[\\]<>,\\s]+)>\\s+(\\w+);", "List<$1> $2 = new ArrayList<$1>();"); |
715 | s = s.replaceAll("new\\s+\\(Hash\\)Set<(\\w+)>\\s+(\\w+);", "Set<$1> $2 = new HashSet<$1>();"); |
716 | s = s.replaceAll("new\\s+\\(Tree\\)Set<(\\w+)>\\s+(\\w+);", "Set<$1> $2 = new TreeSet<$1>();"); |
717 | 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. |
718 | s = s.replaceAll("new\\s+\\(Hash\\)Map<([\\w\\s,]+)>\\s+(\\w+);", "Map<$1> $2 = new HashMap<$1>();"); |
719 | s = s.replaceAll("new\\s+\\(Tree\\)Map<([\\w\\s,]+)>\\s+(\\w+);", "Map<$1> $2 = new TreeMap<$1>();"); |
720 | |
721 | // TreeMap when string as key |
722 | s = s.replaceAll("new\\s+Map<(S,[\\w\\s,]+)>\\s+(\\w+);", "Map<$1> $2 = new TreeMap<$1>();"); |
723 | s = s.replaceAll("new\\s+Map<(String,[\\w\\s,]+)>\\s+(\\w+);", "Map<$1> $2 = new TreeMap<$1>();"); |
724 | |
725 | // HashMap is default for everything else |
726 | s = s.replaceAll("new\\s+Map<([\\w\\s,]+)>\\s+(\\w+);", "Map<$1> $2 = new HashMap<$1>();"); |
727 | |
728 | s = s.replaceAll("new\\s+(\\w+<[\\w\\s,]+>)\\s+(\\w+);", "$1 $2 = new $1();"); |
729 | |
730 | // Constructor calls without parantheses |
731 | // So you can say something like: predictors.add(new P1); |
732 | |
733 | s = s.replaceAll("new\\s+(\\w+)\\s*([,\\);])", "new $1()$2"); |
734 | |
735 | // replace "new List" with "new ArrayList" |
736 | s = s.replaceAll("new\\s+List\\s*\\(", "new ArrayList("); |
737 | |
738 | // for args |
739 | |
740 | s = s.replace("for args {", "for (int i = 0; i < args.length; i++) { final String arg = args[i];"); |
741 | ret s; |
742 | } |
743 | |
744 | static L<S> extendClasses(L<S> tok) { |
745 | int i; |
746 | while ((i = jfind(tok, "extend <id> {")) >= 0) { |
747 | S className = tok.get(i+2); |
748 | int idx = findCodeTokens(tok, i, false, "{"); |
749 | int j = findEndOfBracketPart(tok, idx+2); |
750 | S content = join(subList(tok, idx+1, j-1)); |
751 | L<S> c = findInnerClassOfMain(tok, className); |
752 | clearTokens(tok.subList(i, j+1)); |
753 | if (c == null) { |
754 | print("Warning: Can't extend class " + className + ", not found"); |
755 | continue; |
756 | } |
757 | int endOfClass = magicIndexOfSubList(tok, c) + l(c)-1; |
758 | while (neq(tok.get(endOfClass), "}")) --endOfClass; |
759 | tok.set(endOfClass, content + "\n" + tok.get(endOfClass)); |
760 | reTok(tok); |
761 | } |
762 | ret tok; |
763 | } |
764 | |
765 | static void listComprehensions(L<S> tok) { |
766 | int i; |
767 | while ((i = jfind(tok, "[<id> <id> in")) >= 0) { |
768 | Map<Integer, Integer> bracketMap = getBracketMap(tok); |
769 | S type = tok.get(i+2), id = tok.get(i+4); |
770 | int j = scanOverExpression(tok, bracketMap, i+8, "|"); |
771 | S exp = join(tok.subList(i+8, j)); |
772 | j += 2; |
773 | int k = scanOverExpression(tok, bracketMap, j, "]"); |
774 | S where = join(tok.subList(j, k)); |
775 | ++k; |
776 | |
777 | S code = "filter(" + exp + ", func(" + type + " " + id + ") { " + where + " })"; |
778 | replaceTokens(tok, i, k, code); |
779 | reTok(tok); |
780 | } |
781 | } |
782 | |
783 | // lib 123 => !123 |
784 | static void libs(L<S> tok) { |
785 | new Set<S> libs; |
786 | int i; |
787 | while ((i = jfind(tok, "lib <int>")) >= 0) { |
788 | S id = tok.get(i+2); |
789 | print("lib " + id); |
790 | if (!libs.contains(id)) { |
791 | libs.add(id); |
792 | tok.set(i, "!"); |
793 | tok.set(i+1, ""); |
794 | } else { |
795 | print("...ignoring (duplicate)"); |
796 | clearAllTokens(tok, i, i+3); |
797 | reTok(tok); |
798 | } |
799 | } |
800 | } |
801 | |
802 | // sourceCodeLine() => 1234 |
803 | static void sourceCodeLine(L<S> tok) { |
804 | int i ; |
805 | while ((i = jfind(tok, "sourceCodeLine()")) >= 0) { |
806 | replaceTokens(tok, i, i+5, str(countChar(join(subList(tok, 0, i)), '\n')+1)); |
807 | reTok(tok); |
808 | } |
809 | } |
810 | |
811 | // done before any other processing |
812 | static void earlyStuff(L<S> tok) { |
813 | int i; |
814 | |
815 | // Note: this makes the word "quine" a special operator |
816 | // (unusable as a function name) |
817 | |
818 | while ((i = jfind(tok, "quine(")) >= 0) { |
819 | int idx = findCodeTokens(tok, i, false, "("); |
820 | int j = findEndOfBracketPart(tok, idx+2); |
821 | tok.set(i, "new Quine"); |
822 | tok.set(idx, "(" + quote(join(subList(tok, idx+1, j-1))) + ", "); |
823 | reTok(tok); |
824 | } |
825 | } |
826 | |
827 | static void throwFail(L<S> tok) { |
828 | bool anyChange = false; |
829 | for (int i = 1; i+2 < l(tok); i += 2) |
830 | if (eq(get(tok, i+2), "fail") && !eqOneOf(get(tok, i), "throw", "RuntimeException", "return")) { |
831 | tok.set(i+2, "throw fail"); |
832 | anyChange = true; |
833 | } |
834 | if (anyChange) |
835 | reTok(tok); |
836 | } |
837 | } |
Began life as a copy of #759
download show line numbers debug dex old transpilations
Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1003874 |
Snippet name: | Backup of #759 Before Integration |
Eternal ID of this version: | #1003874/1 |
Text MD5: | 186e7642ec4fe7c1806f020f386aa7c6 |
Author: | stefan |
Category: | |
Type: | JavaX translator |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2016-07-29 15:31:14 |
Source code size: | 28383 bytes / 837 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 638 / 555 |
Referenced in: | [show references] |