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

532
LINES

< > BotCompany Repo | #1002474 // Standard functions (new)

JavaX translator [tags: use-pretranspiled]

Libraryless. Click here for Pure Java version (1889L/13K/41K).

1  
!636 (modern)
2  
3  
public class main {
4  
  !include #1001496 // Matches
5  
  !include #1001065 // DialogIO
6  
  
7  
  static boolean debug = false;
8  
  
9  
  static new Map<S, S> cache;
10  
  
11  
  public static void main(String[] args) throws IOException {
12  
    L<S> standardFunctions = (L) loadVariableDefinition(
13  
      cacheGet("#761"), "standardFunctions");
14  
    long startTime = now();
15  
    String s = loadMainJava();
16  
    
17  
    Map<String, String> sf = new HashMap();
18  
    for (String x : standardFunctions) {
19  
      String[] f = x.split("/");
20  
      sf.put(f[1], f[0]);
21  
    }
22  
    
23  
    for (int i = 0; ; i++) {
24  
      Set<String> defd = new HashSet(findFunctions(s));
25  
      List<String> tok = javaTok(s);
26  
      
27  
      // changes tok
28  
      Set<String> invocations = findFunctionInvocations(tok, sf);
29  
      s = join(tok);
30  
      
31  
      print("Functions invoked: " + structure(invocations));
32  
      List<String> needed = diff(invocations, defd);
33  
      print("Functions needed: " + structure(needed));
34  
      if (needed.isEmpty())
35  
        break;
36  
        
37  
      new L<S> added;
38  
      new StringBuilder buf;
39  
      for (String x : needed) {
40  
        if (defd.contains(x)) continue;
41  
        
42  
        String id = sf.get(x);
43  
        //print("Adding function: " + x + " (" + id + ")");
44  
         
45  
        S function = cacheGet(id);
46  
        if (("\n" + function).contains("\n!")) print("Warning: " + id + " contains translators.");
47  
        
48  
        buf.append(function).append("\n");
49  
        added.add(x);
50  
        defd.addAll(findFunctions(function));
51  
      }
52  
      s = addFunctions(s, str(buf));
53  
      defd = new HashSet(findFunctions(s));
54  
      print("Functions added: " + structure(added));
55  
      
56  
      for (String x : needed)
57  
        if (!defd.contains(x))
58  
          fail("Function not defined properly: " + x);
59  
      print("Iteration " + (i+2));
60  
      if (i >= 1000) fail("Too many iterations");
61  
    }
62  
    saveMainJava(s);
63  
    print("629: " + (now()-startTime) + " ms");
64  
  }
65  
66  
  static boolean substringIs(String s, int i, String pat) {
67  
    return i >= 0 && i+pat.length() < s.length() && s.substring(i, i+pat.length()).equals(pat);
68  
  }
69  
  
70  
  // OK, this should be fast enough.
71  
  static List<String> findFunctions(String src) {
72  
    int idx = src.indexOf("main {"); // yes it's a hack...
73  
    if (idx >= 0) src = src.substring(idx);
74  
75  
    return findFunctionDefinitions(src);
76  
  }
77  
  
78  
  public static String addFunction(String s, String fID) throws IOException {
79  
    int i = s.lastIndexOf('}');
80  
    S function = cacheGet(fID);
81  
    if (("\n" + function).contains("\n!")) print("Warning: " + fID + " contains translators.");
82  
    return s.substring(0, i) + "\n" + function +"\n" + s.substring(i);
83  
  }
84  
  
85  
  public static String addFunctions(String s, String functions) throws IOException {
86  
    int i = s.lastIndexOf('}');
87  
    return s.substring(0, i) + "\n" + functions + s.substring(i);
88  
  }
89  
  
90  
  public static List<String> toLines(String s) {
91  
    List<String> lines = new ArrayList<String>();
92  
    int start = 0;
93  
    while (true) {
94  
      int i = toLines_nextLineBreak(s, start);
95  
      if (i < 0) {
96  
        if (s.length() > start) lines.add(s.substring(start));
97  
        break;
98  
      }
99  
100  
      lines.add(s.substring(start, i));
101  
      if (s.charAt(i) == '\r' && i+1 < s.length() && s.charAt(i+1) == '\n')
102  
        i += 2;
103  
      else
104  
        ++i;
105  
106  
      start = i;
107  
    }
108  
    return lines;
109  
  }
110  
111  
  private static int toLines_nextLineBreak(String s, int start) {
112  
    for (int i = start; i < s.length(); i++) {
113  
      char c = s.charAt(i);
114  
      if (c == '\r' || c == '\n')
115  
        return i;
116  
    }
117  
    return -1;
118  
  }
119  
  
120  
  static String mainJava;
121  
  
122  
  static String loadMainJava() throws IOException {
123  
    if (mainJava != null) return mainJava;
124  
    return loadTextFile("input/main.java", "");
125  
  }
126  
127  
  static void saveMainJava(String s) throws IOException {
128  
    if (mainJava != null)
129  
      mainJava = s;
130  
    else
131  
      saveTextFile("output/main.java", s);
132  
  }
133  
  
134  
  static void saveMainJava(List<String> tok) throws IOException {
135  
    saveMainJava(join(tok));
136  
  }
137  
  
138  
  public static long parseSnippetID(String snippetID) {
139  
    return Long.parseLong(shortenSnippetID(snippetID));
140  
  }
141  
142  
  private static String shortenSnippetID(String snippetID) {
143  
    if (snippetID.startsWith("#"))
144  
      snippetID = snippetID.substring(1);
145  
    String httpBlaBla = "http://tinybrain.de/";
146  
    if (snippetID.startsWith(httpBlaBla))
147  
      snippetID = snippetID.substring(httpBlaBla.length());
148  
    return snippetID;
149  
  }
150  
151  
  public static boolean isSnippetID(String snippetID) {
152  
    snippetID = shortenSnippetID(snippetID);
153  
    return isInteger(snippetID) && Long.parseLong(snippetID) != 0;
154  
  }
155  
156  
  public static boolean isInteger(String s) {
157  
    return Pattern.matches("\\-?\\d+", s);
158  
  }
159  
  
160  
  private static String loadPage(URL url) throws IOException {
161  
    print("Loading: " + url.toExternalForm());
162  
    URLConnection con = url.openConnection();
163  
    return loadPage(con, url);
164  
  }
165  
166  
  public static String loadPage(URLConnection con, URL url) throws IOException {
167  
    String contentType = con.getContentType();
168  
    if (contentType == null)
169  
      throw new IOException("Page could not be read: " + url);
170  
    //Log.info("Content-Type: " + contentType);
171  
    String charset = guessCharset(contentType);
172  
    Reader r = new InputStreamReader(con.getInputStream(), charset);
173  
    StringBuilder buf = new StringBuilder();
174  
    while (true) {
175  
      int ch = r.read();
176  
      if (ch < 0)
177  
        break;
178  
      //Log.info("Chars read: " + buf.length());
179  
      buf.append((char) ch);
180  
    }
181  
    return buf.toString();
182  
  }
183  
184  
  public static String guessCharset(String contentType) {
185  
    Pattern p = Pattern.compile("text/html;\\s+charset=([^\\s]+)\\s*");
186  
    Matcher m = p.matcher(contentType);
187  
    /* If Content-Type doesn't match this pre-conception, choose default and hope for the best. */
188  
    return m.matches() ? m.group(1) : "ISO-8859-1";
189  
  }
190  
  
191  
  static RuntimeException fail() {
192  
    throw new RuntimeException("fail");
193  
  }
194  
  
195  
  static RuntimeException fail(Object msg) {
196  
    throw new RuntimeException(String.valueOf(msg));
197  
  }
198  
  
199  
// replacement for class JavaTok
200  
// maybe incomplete, might want to add floating point numbers
201  
// todo also: extended multi-line strings
202  
203  
static List<String> javaTok(String s) {
204  
  List<String> tok = new ArrayList<String>();
205  
  int l = s.length();
206  
  
207  
  int i = 0;
208  
  while (i < l) {
209  
    int j = i;
210  
    char c; String cc;
211  
    
212  
    // scan for whitespace
213  
    while (j < l) {
214  
      c = s.charAt(j);
215  
      cc = s.substring(j, Math.min(j+2, l));
216  
      if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
217  
        ++j;
218  
      else if (cc.equals("/*")) {
219  
        do ++j; while (j < l && !s.substring(j, Math.min(j+2, l)).equals("*/"));
220  
        j = Math.min(j+2, l);
221  
      } else if (cc.equals("//")) {
222  
        do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0);
223  
      } else
224  
        break;
225  
    }
226  
    
227  
    tok.add(s.substring(i, j));
228  
    i = j;
229  
    if (i >= l) break;
230  
    c = s.charAt(i); // cc is not needed in rest of loop body
231  
    cc = s.substring(i, Math.min(i+2, l));
232  
233  
    // scan for non-whitespace
234  
    if (c == '\'' || c == '"') {
235  
      char opener = c;
236  
      ++j;
237  
      while (j < l) {
238  
        if (s.charAt(j) == opener) {
239  
          ++j;
240  
          break;
241  
        } else if (s.charAt(j) == '\\' && j+1 < l)
242  
          j += 2;
243  
        else
244  
          ++j;
245  
      }
246  
    } else if (Character.isJavaIdentifierStart(c))
247  
      do ++j; while (j < l && Character.isJavaIdentifierPart(s.charAt(j)));
248  
    else if (Character.isDigit(c)) {
249  
      do ++j; while (j < l && Character.isDigit(s.charAt(j)));
250  
      if (j < l && s.charAt(j) == 'L') ++j; // Long constants like 1L
251  
    } else if (cc.equals("[[")) {
252  
      do ++j; while (j+1 < l && !s.substring(j, j+2).equals("]]"));
253  
      j = Math.min(j+2, l);
254  
    } else
255  
      ++j;
256  
257  
    tok.add(s.substring(i, j));
258  
    i = j;
259  
  }
260  
  
261  
  if ((tok.size() % 2) == 0) tok.add("");
262  
  return tok;
263  
}
264  
265  
static List<String> javaTok(List<String> tok) {
266  
  return javaTok(join(tok));
267  
}
268  
269  
  public static String join(String glue, Iterable<String> strings) {
270  
    StringBuilder buf = new StringBuilder();
271  
    Iterator<String> i = strings.iterator();
272  
    if (i.hasNext()) {
273  
      buf.append(i.next());
274  
      while (i.hasNext())
275  
        buf.append(glue).append(i.next());
276  
    }
277  
    return buf.toString();
278  
  }
279  
  
280  
  public static String join(String glue, String[] strings) {
281  
    return join(glue, Arrays.asList(strings));
282  
  }
283  
  
284  
  public static String join(Iterable<String> strings) {
285  
    return join("", strings);
286  
  }
287  
  
288  
  public static String join(String[] strings) {
289  
    return join("", strings);
290  
  }  
291  
  
292  
// leaves tok properly tokenized
293  
// returns true iff anything was replaced
294  
static boolean jreplace(List<String> tok, String in, String out) {
295  
  return jreplace(tok, in, out, false, true);
296  
}
297  
298  
static boolean jreplace(List<String> tok, String in, String out, boolean ignoreCase, boolean reTok) {
299  
  List<String> tokin = javaTok(in);
300  
  replaceSublist(tokin, litlist("<", "", "quoted", "", ">"), litlist("<quoted>"));
301  
  replaceSublist(tokin, litlist("<", "", "id", "", ">"), litlist("<id>"));
302  
  
303  
  boolean anyChange = false;
304  
  for (int n = 0; n < 10000; n++) {
305  
    int i = findCodeTokens(tok, ignoreCase, toStringArray(codeTokensOnly(tokin)));
306  
    if (i < 0) {
307  
      if (anyChange && reTok)
308  
        replaceCollection(tok, javaTok(tok));
309  
      return anyChange;
310  
    }
311  
    List<String> subList = tok.subList(i-1, i+l(tokin)-1); // N to N
312  
    String expansion = jreplace_expandRefs(out, subList);
313  
    clearAllTokens(tok.subList(i, i+l(tokin)-2)); // code to code
314  
    tok.set(i, expansion);
315  
    anyChange = true;
316  
  }
317  
  throw fail("woot? 10000!");
318  
}
319  
320  
// "$1" is first code token, "$2" second code token etc.
321  
static String jreplace_expandRefs(String s, List<String> tokref) {
322  
  List<String> tok = javaTok(s);
323  
  for (int i = 1; i < l(tok)-2; i += 2) {
324  
    if (tok.get(i).startsWith("$") && isInteger(tok.get(i).substring(1))) {
325  
      String x = tokref.get(-1+parseInt(tok.get(i).substring(1))*2);
326  
      tok.set(i, x);
327  
    }
328  
  }
329  
  return join(tok);
330  
}
331  
332  
  static void replaceToken(List<String> tok, String in, String out) {
333  
    renameToken(tok, in, out);
334  
  }
335  
336  
static <A> void replaceCollection(Collection<A> dest, Collection<A> src) {
337  
  dest.clear();
338  
  dest.addAll(src);
339  
}
340  
341  
static <A> ArrayList<A> litlist(A... a) {
342  
  return new ArrayList<A>(Arrays.asList(a));
343  
}
344  
 static List<String> codeTokensOnly(List<String> tok) {
345  
    List<String> l = new ArrayList<String>();
346  
    for (int i = 1; i < tok.size(); i += 2)
347  
      l.add(tok.get(i));
348  
    return l;
349  
  }
350  
  
351  
static void replaceSublist(List<String> l, List<String> x, List<String> y) {
352  
  int i = 0;
353  
  while (true) {
354  
    i = indexOfSubList(l, x, i);
355  
    if (i < 0) return;
356  
    
357  
    // It's inefficient :D
358  
    for (int j = 0; j < l(x); j++) l.remove(i);
359  
    l.addAll(i, y);
360  
    i += l(y);
361  
  }
362  
}
363  
364  
static int l(Object[] array) {
365  
  return array == null ? 0 : array.length;
366  
}
367  
368  
static int l(Collection c) {
369  
  return c == null ? 0 : c.size();
370  
}
371  
372  
static int l(Map m) {
373  
  return m == null ? 0 : m.size();
374  
}
375  
376  
static int l(String s) {
377  
  return s == null ? 0 : s.length();
378  
} 
379  
380  
381  
static int parseInt(String s) {
382  
  return Integer.parseInt(s);
383  
}
384  
385  
  static void renameToken(List<String> tok, String in, String out) {
386  
    int renames = 0;
387  
    for (int i = 1; i < tok.size(); i += 2) {
388  
      if (tok.get(i).equals(in)) {
389  
        tok.set(i, out);
390  
        ++renames;
391  
      }
392  
    }
393  
  }
394  
  
395  
396  
static String[] toStringArray(List<String> list) {
397  
  return list.toArray(new String[list.size()]);
398  
}
399  
400  
static String[] toStringArray(Object o) {
401  
  if (o instanceof String[])
402  
    return (String[]) o;
403  
  else if (o instanceof List)
404  
    return toStringArray((List<String>) o);
405  
  else
406  
    throw fail("Not a list or array: " + o);
407  
}
408  
409  
  static int findCodeTokens(List<String> tok, String... tokens) {
410  
    return findCodeTokens(tok, 1, false, tokens);
411  
  }
412  
  
413  
  static int findCodeTokens(List<String> tok, boolean ignoreCase, String... tokens) {
414  
    return findCodeTokens(tok, 1, ignoreCase, tokens);
415  
  }
416  
  
417  
  static int findCodeTokens(List<String> tok, int startIdx, boolean ignoreCase, String... tokens) {
418  
    outer: for (int i = startIdx | 1; i+tokens.length*2-2 < tok.size(); i += 2) {
419  
      for (int j = 0; j < tokens.length; j++) {
420  
        String p = tokens[j], t = tok.get(i+j*2);
421  
        boolean match;
422  
        if (eq(p, "*")) match = true;
423  
        else if (eq(p, "<quoted>")) match = isQuoted(t);
424  
        else if (eq(p, "<id>")) match = isIdentifier(t);
425  
        else match = ignoreCase ? eqic(p, t) : eq(p, t);
426  
        
427  
        if (!match)
428  
          continue outer;
429  
      }
430  
      return i;
431  
    }
432  
    return -1;
433  
  }
434  
  
435  
  
436  
  static void clearAllTokens(List<String> tok) {
437  
    for (int i = 0; i < tok.size(); i++)
438  
      tok.set(i, "");
439  
  }
440  
  
441  
  static void clearAllTokens(List<String> tok, int i, int j) {
442  
    for (; i < j; i++)
443  
      tok.set(i, "");
444  
  }
445  
446  
static boolean isIdentifier(String s) {
447  
  return isJavaIdentifier(s);
448  
}
449  
450  
static boolean eqic(String a, String b) {
451  
  if ((a == null) != (b == null)) return false;
452  
  if (a == null) return true;
453  
  return a.equalsIgnoreCase(b);
454  
}
455  
456  
457  
// supports the usual quotings (', ", variable length double brackets)
458  
static boolean isQuoted(String s) {
459  
  if (s.startsWith("'") || s.startsWith("\"")) return true;
460  
  if (!s.startsWith("[")) return false;
461  
  int i = 1;
462  
  while (i < s.length() && s.charAt(i) == '=') ++i;
463  
  return i < s.length() && s.charAt(i) == '[';
464  
  //return Pattern.compile("^\\[=*\\[").matcher(s).find();
465  
}
466  
467  
468  
static boolean eq(Object a, Object b) {
469  
  if (a == null) return b == null;
470  
  if (a.equals(b)) return true;
471  
  if (a instanceof BigInteger) {
472  
    if (b instanceof Integer) return a.equals(BigInteger.valueOf((Integer) b));
473  
    if (b instanceof Long) return a.equals(BigInteger.valueOf((Long) b));
474  
  }
475  
  return false;
476  
}
477  
478  
static boolean isJavaIdentifier(String s) {
479  
  if (s.length() == 0 || !Character.isJavaIdentifierStart(s.charAt(0)))
480  
    return false;
481  
  for (int i = 1; i < s.length(); i++)
482  
    if (!Character.isJavaIdentifierPart(s.charAt(i)))
483  
      return false;
484  
  return true;
485  
}
486  
487  
static <A> int indexOfSubList(List<A> x, List<A> y, int i) {
488  
  outer: for (; i+l(y) <= l(x); i++) {
489  
    for (int j = 0; j < l(y); j++)
490  
      if (neq(x.get(i+j), y.get(j)))
491  
        continue outer;
492  
    return i;
493  
  }
494  
  return -1;
495  
}
496  
497  
static boolean neq(Object a, Object b) {
498  
  return !eq(a, b);
499  
}
500  
501  
static long now() {
502  
  return System.currentTimeMillis();
503  
}
504  
505  
static List<String> diff(Collection<String> a, Set<String> b) {
506  
  List<String> l = new ArrayList();
507  
  for (String s : a)
508  
    if (!b.contains(s))
509  
      l.add(s);
510  
  return l;
511  
}
512  
513  
static int jfind(List<String> tok, String in) {
514  
  List<String> tokin = javaTok(in);
515  
  replaceSublist(tokin, litlist("<", "", "quoted", "", ">"), litlist("<quoted>"));
516  
  replaceSublist(tokin, litlist("<", "", "id", "", ">"), litlist("<id>"));
517  
  
518  
  return findCodeTokens(tok, false, toStringArray(codeTokensOnly(tokin)));
519  
}
520  
  static S cacheGet(S id) ctex {
521  
    id = formatSnippetID(id);
522  
    S text = cache.get(id);
523  
    if (text != null) {
524  
      //print("Snippet CACHED " + fID);
525  
    } else {
526  
      //print("Snippet LOAD " + fID);
527  
      text = loadSnippet(id, false);
528  
      cache.put(id, text);
529  
    }
530  
    ret text;
531  
  }
532  
}

Author comment

Began life as a copy of #629

download  show line numbers  debug dex  old transpilations   

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

No comments. add comment

Snippet ID: #1002474
Snippet name: Standard functions (new)
Eternal ID of this version: #1002474/1
Text MD5: dc0e2cbb548caae70570d3764e08efec
Transpilation MD5: d9eda32662880c79fdf2f9324559eb64
Author: stefan
Category: javax
Type: JavaX translator
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2016-07-28 16:25:24
Source code size: 15667 bytes / 532 lines
Pitched / IR pitched: No / No
Views / Downloads: 921 / 9689
Referenced in: [show references]