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