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

844
LINES

< > BotCompany Repo | #1034649 // unstructure (v18, with enums, LIVE)

JavaX fragment (include) [tags: use-pretranspiled]

Transpiled version (8914L) is out of date.

1  
scope unstructure
2  
3  
// TODO: cyclic structures involving certain lists & sets
4  
5  
ifdef UseEclipseCollections
6  
!include once #1027304 // Eclipse Collections
7  
endifdef
8  
9  
sO unstructure(String text) {
10  
  ret unstructure(text, false);
11  
}
12  
13  
sO unstructure(S text, bool allDynamic) {
14  
  ret unstructure(text, allDynamic, null);
15  
}
16  
17  
sO unstructure(S text, IF1<S, Class> classFinder) {
18  
  ret unstructure(text, false, classFinder);
19  
}
20  
21  
static int structure_internStringsLongerThan = 50;
22  
static int unstructure_unquoteBufSize = 100;
23  
24  
static int unstructure_tokrefs; // stats
25  
26  
abstract sclass unstructure_Receiver {
27  
  abstract void set(O o);
28  
}
29  
30  
// classFinder: func(name) -> class (optional)
31  
static Object unstructure(String text, boolean allDynamic,
32  
  O classFinder) {
33  
  if (text == null) ret null;
34  
  ret unstructure_tok(javaTokC_noMLS_iterator(text), allDynamic, classFinder);
35  
}
36  
37  
static O unstructure_reader(BufferedReader reader) {
38  
  ret unstructure_tok(javaTokC_noMLS_onReader(reader), false, null);
39  
}
40  
41  
interface #Handler {
42  
  void parse(int refID, int tokIndex, unstructure_Receiver out);
43  
}
44  
  
45  
static O unstructure_tok(final Producer<S> tok, final boolean allDynamic, final O _classFinder) {
46  
  final boolean debug = unstructure_debug;
47  
  
48  
  final class X {
49  
    int i = -1;
50  
    final O classFinder = _classFinder != null ? _classFinder : _defaultClassFinder();
51  
    S mcDollar = actualMCDollar();
52  
53  
    // use Eclipse primitive collection if possible (smaller & hopefully faster?)
54  
    ifdef UseEclipseCollections
55  
    new IntObjectHashMap<O> refs;
56  
    new IntObjectHashMap<O> tokrefs;
57  
    endifdef
58  
    ifndef UseEclipseCollections
59  
    new HashMap<Integer, O> refs;
60  
    new HashMap<Integer, O> tokrefs;
61  
    endifndef
62  
    
63  
    new HashSet<S> concepts;
64  
    new L<Runnable> stack;
65  
    new SS baseClassMap;
66  
    new HashMap<Class, Constructor> innerClassConstructors;
67  
    S curT;
68  
    char[] unquoteBuf = new char[unstructure_unquoteBufSize];
69  
    
70  
    // value is a class or a Handler
71  
    final new HashMap<S, O> handlers;
72  
    
73  
    *() {
74  
      pcall {
75  
        Class mc = cast callF(_classFinder, "<main>");
76  
        if (mc != null) mcDollar = mc.getName() + "$";
77  
      }
78  
      
79  
      makeHandlers();
80  
    }
81  
    
82  
    replace HandlerArgs with (Handler) (refID, tokIndex, out).
83  
    
84  
    void makeHandlers {
85  
      Handler h;
86  
      
87  
      handlers.put("bigint", HandlerArgs
88  
        -> out.set(parseBigInt()));
89  
        
90  
      handlers.put("d", HandlerArgs
91  
        -> out.set(parseDouble()));
92  
        
93  
      handlers.put("fl", HandlerArgs
94  
        -> out.set(parseFloat()));
95  
        
96  
      handlers.put("sh", HandlerArgs -> {
97  
        consume();
98  
        S t = tpp();
99  
        if (t.equals("-")) {
100  
          t = tpp();
101  
          out.set((short) (-parseInt(t)); ret;
102  
        }
103  
        out.set((short) parseInt(t));
104  
      });
105  
      
106  
      handlers.put("enum", HandlerArgs -> {
107  
        consume();
108  
        S t = tpp();
109  
        assertTrue(isJavaIdentifier(t));
110  
        S fullClassName = mcDollar + t;
111  
        Class _c = findAClass(fullClassName);
112  
        if (_c == null) fail("Enum class not found: " + fullClassName);
113  
        int ordinal = parseInt(tpp());
114  
        out.set(_c.getEnumConstants()[ordinal]);
115  
      });
116  
117  
      handlers.put("false", h = HandlerArgs -> {
118  
        consume(); out.set(false);
119  
      });
120  
      handlers.put("f", h);
121  
      
122  
      handlers.put("true", h = HandlerArgs -> {
123  
        consume(); out.set(true);
124  
      });
125  
      handlers.put("t", h);
126  
      
127  
      handlers.put("{", HandlerArgs -> parseMap(out));
128  
      
129  
      handlers.put("[", HandlerArgs -> {
130  
        new ArrayList l;
131  
        if (refID >= 0) refs.put(refID, l);
132  
        this.parseList(l, out);
133  
      });
134  
      
135  
      handlers.put("bitset", HandlerArgs -> parseBitSet(out));
136  
      
137  
      handlers.put("array", h = HandlerArgs -> parseArray(out));
138  
      handlers.put("intarray", h);
139  
      handlers.put("dblarray", h);
140  
      
141  
    } // end of makeHandlers - add more handlers here
142  
143  
    Class findAClass(S fullClassName) null on exception {
144  
      ret classFinder != null ? (Class) callF(classFinder, fullClassName) : findClass_fullName(fullClassName);
145  
    }
146  
    
147  
    S unquote(S s) {
148  
      ret unquoteUsingCharArray(s, unquoteBuf); 
149  
    }
150  
151  
    // look at current token
152  
    S t() {
153  
      ret curT;
154  
    }
155  
    
156  
    // get current token, move to next
157  
    S tpp() {
158  
      S t = curT;
159  
      consume();
160  
      ret t;
161  
    }
162  
    
163  
    void parse(final unstructure_Receiver out) {
164  
      S t = t();
165  
      
166  
      int refID;
167  
      if (structure_isMarker(t, 0, l(t))) {
168  
        refID = parseInt(t.substring(1));
169  
        consume();
170  
      } else refID = -1;
171  
      
172  
      // if (debug) print("parse: " + quote(t));
173  
      
174  
      final int tokIndex = i;  
175  
      parse_inner(refID, tokIndex, new unstructure_Receiver {
176  
        void set(O o) {
177  
          if (refID >= 0)
178  
            refs.put(refID, o);
179  
          if (o != null)
180  
            tokrefs.put(tokIndex, o);
181  
          out.set(o);
182  
        }
183  
      });
184  
    }
185  
    
186  
    void parse_inner(int refID, int tokIndex, unstructure_Receiver out) {
187  
      S t = t();
188  
      
189  
      // if (debug) print("parse_inner: " + quote(t));
190  
      
191  
      O handler = handlers.get(t);
192  
      if (handler cast Handler)
193  
        ret with handler.parse(refID, tokIndex, out);
194  
        
195  
      Class c = cast handler;
196  
      if (c == null) {
197  
        if (t.startsWith("\"")) {
198  
          S s = internIfLongerThan(unquote(tpp()), structure_internStringsLongerThan);
199  
          out.set(s); ret;
200  
        }
201  
        
202  
        if (t.startsWith("'")) {
203  
          out.set(unquoteCharacter(tpp())); ret;
204  
        }
205  
        if (t.equals("-")) {
206  
          consume();
207  
          t = tpp();
208  
          out.set(isLongConstant(t) ? (O) (-parseLong(t)) : (O) (-parseInt(t))); ret;
209  
        }
210  
        if (isInteger(t) || isLongConstant(t)) {
211  
          consume();
212  
          //if (debug) print("isLongConstant " + quote(t) + " => " + isLongConstant(t));
213  
          if (isLongConstant(t)) {
214  
            out.set(parseLong(t)); ret;
215  
          }
216  
          long l = parseLong(t);
217  
          bool isInt = l == (int) l;
218  
          ifdef unstructure_debug
219  
            print("l=" + l + ", isInt: " + isInt);
220  
          endifdef
221  
          out.set(isInt ? (O) Integer.valueOf((int) l) : (O) Long.valueOf(l)); ret;
222  
        }
223  
        if (t.equals("-")) {
224  
          consume();
225  
          t = tpp();
226  
          out.set(isLongConstant(t) ? (O) (-parseLong(t)) : (O) (-parseInt(t))); ret;
227  
        }
228  
        if (isInteger(t) || isLongConstant(t)) {
229  
          consume();
230  
          //if (debug) print("isLongConstant " + quote(t) + " => " + isLongConstant(t));
231  
          if (isLongConstant(t)) {
232  
            out.set(parseLong(t)); ret;
233  
          }
234  
          long l = parseLong(t);
235  
          bool isInt = l == (int) l;
236  
          ifdef unstructure_debug
237  
            print("l=" + l + ", isInt: " + isInt);
238  
          endifdef
239  
          out.set(isInt ? (O) Integer.valueOf((int) l) : (O) Long.valueOf(l)); ret;
240  
        }
241  
        
242  
        if (t.equals("File")) {
243  
          consume();
244  
          File f = new File(unquote(tpp()));
245  
          out.set(f); ret;
246  
        }
247  
        
248  
        if (t.startsWith("r") && isInteger(t.substring(1))) {
249  
          consume();
250  
          int ref = Integer.parseInt(t.substring(1));
251  
          O o = refs.get(ref);
252  
          if (o == null)
253  
            warn("unsatisfied back reference " + ref);
254  
          out.set(o); ret;
255  
        }
256  
      
257  
        if (t.startsWith("t") && isInteger(t.substring(1))) {
258  
          consume();
259  
          int ref = Integer.parseInt(t.substring(1));
260  
          O o = tokrefs.get(ref);
261  
          if (o == null)
262  
            warn("unsatisfied token reference " + ref + " at " + tokIndex);
263  
          out.set(o); ret;
264  
        }
265  
        
266  
        if (t.equals("hashset")) ret with parseHashSet(out);
267  
        if (t.equals("lhs")) ret with parseLinkedHashSet(out);
268  
        if (t.equals("treeset")) ret with parseTreeSet(out);
269  
        if (t.equals("ciset")) ret with parseCISet(out);
270  
        
271  
        if (eqOneOf(t, "hashmap", "hm")) {
272  
          consume();
273  
          parseMap(new HashMap, out);
274  
          ret;
275  
        }
276  
        if (t.equals("lhm")) {
277  
          consume();
278  
          parseMap(new LinkedHashMap, out);
279  
          ret;
280  
        }
281  
        if (t.equals("tm")) {
282  
          consume();
283  
          parseMap(new TreeMap, out);
284  
          ret;
285  
        }
286  
        if (t.equals("cimap")) {
287  
          consume();
288  
          parseMap(ciMap(), out);
289  
          ret;
290  
        }
291  
        
292  
        if (t.equals("ll")) {
293  
          consume();
294  
          new LinkedList l;
295  
          if (refID >= 0) refs.put(refID, l);
296  
          ret with parseList(l, out);
297  
        }
298  
299  
        if (t.equals("syncLL")) { // legacy
300  
          consume();
301  
          ret with parseList(synchroLinkedList(), out);
302  
        }
303  
304  
        if (t.equals("sync")) {
305  
          consume();
306  
          ret with parse(new unstructure_Receiver {
307  
            void set(O value) {
308  
              if (value instanceof Map) {
309  
                ifndef Android // Java 7
310  
                if (value cast NavigableMap)
311  
                  ret with out.set(synchroNavigableMap(value);
312  
                endifndef
313  
                if (value cast SortedMap)
314  
                  ret with out.set(synchroSortedMap(value);
315  
                ret with out.set(synchroMap((Map) value));
316  
              } else
317  
                ret with out.set(synchroList((L) value);
318  
            }
319  
          });
320  
        }
321  
        
322  
        if (t.equals("ba")) {
323  
          consume();
324  
          S hex = unquote(tpp());
325  
          out.set(hexToBytes(hex)); ret;
326  
        }
327  
        if (t.equals("boolarray")) {
328  
          consume();
329  
          int n = parseInt(tpp());
330  
          S hex = unquote(tpp());
331  
          out.set(boolArrayFromBytes(hexToBytes(hex), n)); ret;
332  
        }
333  
        if (t.equals("class")) {
334  
          out.set(parseClass()); ret;
335  
        }
336  
        if (t.equals("l")) {
337  
          parseLisp(out); ret;
338  
        }
339  
        if (t.equals("null")) {
340  
          consume(); out.set(null); ret;
341  
        }
342  
        
343  
        if (eq(t, "c")) {
344  
          consume();
345  
          t = t();
346  
          assertTrue(isJavaIdentifier(t));
347  
          concepts.add(t);
348  
        }
349  
        
350  
        // custom deserialization (new static method method)
351  
        if (eq(t, "cu")) {
352  
          consume();
353  
          t = tpp();
354  
          assertTrue(isJavaIdentifier(t));
355  
          S fullClassName = mcDollar + t;
356  
          Class _c = findAClass(fullClassName);
357  
          if (_c == null) fail("Class not found: " + fullClassName);
358  
          parse(new unstructure_Receiver {
359  
            void set(O value) {
360  
              ifdef unstructure_debug
361  
                print("Consumed custom object, next token: " + t());
362  
              endifdef
363  
              out.set(call(_c, "_deserialize", value);
364  
            }
365  
          });
366  
          ret;
367  
        }
368  
      }
369  
      
370  
      if (eq(t, "j")) {
371  
        consume();
372  
        out.set(parseJava()); ret;
373  
      }
374  
      
375  
      if (eq(t, "bc")) {
376  
        consume();
377  
        S c1 = tpp();
378  
        S c2 = tpp();
379  
        baseClassMap.put(c1, c2);
380  
        ret with parse_inner(refID, i, out);
381  
      }
382  
      
383  
      // add more tokens here
384  
385  
      // Now we want to find our target class c
386  
      // Have we failed to look up the class before?
387  
      //bool seenBefore = handlers.containsKey(cname);
388  
389  
      // If we have seen the class before, we skip all of this
390  
      // and simply leave c as null
391  
      // TODO - how do we fill className?
392  
      //if (!seenBefore) {
393  
        if (c == null && !isJavaIdentifier(t))
394  
          throw new RuntimeException("Unknown token " + (i+1) + ": " + quote(t));
395  
          
396  
        // any other class name (or package name)
397  
        consume();
398  
        S className, fullClassName;
399  
        
400  
        // Is it a package name?
401  
        if (eq(t(), ".")) {
402  
          consume();
403  
          className = fullClassName = t + "." + assertIdentifier(tpp());
404  
        } else {
405  
          className = t;
406  
          fullClassName = mcDollar + t;
407  
        }
408  
        
409  
        if (c == null && !allDynamic) {
410  
          // First, find class
411  
          c = findAClass(fullClassName);
412  
          handlers.put(className, c);
413  
        }
414  
        
415  
        // check for existing base class
416  
        if (c == null && !allDynamic) {
417  
          new Set<S> seen;
418  
          S parent = className;
419  
          while true {
420  
            S baseName = baseClassMap.get(parent);
421  
            if (baseName == null)
422  
              break;
423  
            if (!seen.add(baseName))
424  
              fail("Cyclic superclass info: " + baseName);
425  
            c = findAClass(mcDollar + baseName);
426  
            if (c == null)
427  
              print("Base class " + baseName + " of " + parent +  " doesn't exist either");
428  
            else if (isAbstract(c))
429  
              print("Can't instantiate abstract base class: " + c);
430  
            else {
431  
              printVars_str("Reverting to base class", +className, +baseName, +c);
432  
              handlers.put(className, c);
433  
              break;
434  
            }
435  
            parent = baseName;
436  
          }
437  
        }
438  
      //}
439  
          
440  
      // Check if it has an outer reference
441  
      bool hasBracket = eq(t(), "(");
442  
      if (hasBracket) consume();
443  
      bool hasOuter = hasBracket && startsWith(t(), "this$");
444  
      
445  
      DynamicObject dO = null;
446  
      O o = null;
447  
      fS thingName = t;
448  
      pcall {
449  
        if (c != null) {
450  
          if (hasOuter) try {
451  
            Constructor ctor = innerClassConstructors.get(c);
452  
            if (ctor == null)
453  
              innerClassConstructors.put(c, ctor = nuStubInnerObject_findConstructor(c, classFinder));
454  
            o = ctor.newInstance(new O[] {null});
455  
          } catch Exception e {
456  
            print("Error deserializing " + c + ": " + e);
457  
            o = nuEmptyObject(c);
458  
          } else
459  
            o = nuEmptyObject(c);
460  
          if (o instanceof DynamicObject) dO = (DynamicObject) o;
461  
        } else {
462  
          if (concepts.contains(t) && (c = findAClass(mcDollar + "Concept")) != null)
463  
            o = dO = (DynamicObject) nuEmptyObject(c);
464  
          else
465  
            dO = new DynamicObject;
466  
          dO.className = className;
467  
          ifdef unstructure_debug
468  
            print("Made dynamic object " + t + " " + shortClassName(dO));
469  
          endifdef
470  
        }
471  
      } // end of pcall
472  
      
473  
      // Creating instance failed? Use DynamicObject
474  
      if (o == null && dO == null)
475  
        dO = new DynamicObject;
476  
      
477  
      // Save in references list early because contents of object
478  
      // might link back to main object
479  
      
480  
      if (refID >= 0)
481  
        refs.put(refID, o != null ? o : dO);
482  
      tokrefs.put(tokIndex, o != null ? o : dO);
483  
      
484  
      // NOW parse the fields!
485  
      
486  
      new /*Linked*/HashMap<S, O> fields; // no longer preserving order (why did we do this?)
487  
      O _o = o;
488  
      DynamicObject _dO = dO;
489  
      if (hasBracket) {
490  
        stack.add(r {
491  
          ifdef unstructure_debug
492  
            print("in object values, token: " + t());
493  
          endifdef
494  
          if (eq(t(), ",")) consume();
495  
          if (eq(t(), ")")) {
496  
            consume(")");
497  
            objRead(_o, _dO, fields, hasOuter);
498  
            out.set(_o != null ? _o : _dO);
499  
          } else {
500  
            final S key = unquote(tpp());
501  
            S t = tpp();
502  
            if (!eq(t, "="))
503  
              fail("= expected, got " + t + " after " + quote(key) + " in object " + thingName /*+ " " + sfu(fields)*/);
504  
            stack.add(this);
505  
            parse(new unstructure_Receiver {
506  
              void set(O value) {
507  
                fields.put(key, value);
508  
                /*ifdef unstructure_debug
509  
                  print("Got field value " + value + ", next token: " + t());
510  
                endifdef*/
511  
                //if (eq(t(), ",")) consume();
512  
              }
513  
            });
514  
          }
515  
        });
516  
      } else {
517  
        objRead(o, dO, fields, hasOuter);
518  
        out.set(o != null ? o : dO);
519  
      }
520  
    }
521  
    
522  
    void objRead(O o, DynamicObject dO, MapSO fields, bool hasOuter) {
523  
      ifdef unstructure_debug
524  
      print("objRead " + className(o) + " " + className(dO) + " " + struct(fields));
525  
      endifdef
526  
      
527  
      // translate between diferent compilers (this$0 vs this$1)
528  
      O outer = fields.get("this$0");
529  
      if (outer != null) fields.put("this$1", outer);
530  
      else {
531  
        outer = fields.get("this$1");
532  
        if (outer != null) fields.put("this$0", outer);
533  
      }
534  
      
535  
      if (o != null) {
536  
        if (dO != null) {
537  
          ifdef unstructure_debug
538  
            printStructure("setOptAllDyn", fields);
539  
          endifdef
540  
          setOptAllDyn_pcall(dO, fields);
541  
        } else {
542  
          setOptAll_pcall(o, fields);
543  
          ifdef unstructure_debug
544  
            print("objRead now: " + struct(o));
545  
          endifdef
546  
        }
547  
        if (hasOuter)
548  
          fixOuterRefs(o);
549  
      } else for (Map.Entry<S, O> e : fields.entrySet())
550  
        setDynObjectValue(dO, intern(e.getKey()), e.getValue());
551  
552  
      if (o != null)
553  
        pcallOpt_noArgs(o, "_doneLoading");
554  
    }
555  
    
556  
    void parseSet(final Set set, final unstructure_Receiver out) {
557  
      this.parseList(new ArrayList, new unstructure_Receiver {
558  
        void set(O o) {
559  
          set.addAll((L) o);
560  
          out.set(set);
561  
        }
562  
      });
563  
    }
564  
    
565  
    void parseLisp(final unstructure_Receiver out) {
566  
      ifclass Lisp
567  
        consume("l");
568  
        consume("(");
569  
        final new ArrayList list;
570  
        stack.add(r {
571  
          if (eq(t(), ")")) {
572  
            consume(")");
573  
            out.set(Lisp((S) list.get(0), subList(list, 1)));
574  
          } else {
575  
            stack.add(this);
576  
            parse(new unstructure_Receiver {
577  
              void set(O o) {
578  
                list.add(o);
579  
                if (eq(t(), ",")) consume();
580  
              }
581  
            });
582  
          }
583  
        });
584  
        if (false) // skip fail line
585  
      endif
586  
      
587  
      fail("class Lisp not included");
588  
    }
589  
    
590  
    void parseBitSet(final unstructure_Receiver out) {
591  
      consume("bitset");
592  
      consume("{");
593  
      final new BitSet bs;
594  
      stack.add(r {
595  
        if (eq(t(), "}")) {
596  
          consume("}");
597  
          out.set(bs);
598  
        } else {
599  
          stack.add(this);
600  
          parse(new unstructure_Receiver {
601  
            void set(O o) {
602  
              bs.set((Integer) o);
603  
              if (eq(t(), ",")) consume();
604  
            }
605  
          });
606  
        }
607  
      });
608  
    }
609  
    
610  
    void parseList(final L list, final unstructure_Receiver out) {
611  
      tokrefs.put(i, list);
612  
      consume("[");
613  
      stack.add(r {
614  
        if (eq(t(), "]")) {
615  
          consume();
616  
          ifdef unstructure_debug
617  
            print("Consumed list, next token: " + t());
618  
          endifdef
619  
          out.set(list);
620  
        } else {
621  
          stack.add(this);
622  
          parse(new unstructure_Receiver {
623  
            void set(O o) {
624  
              //if (debug) print("List element type: " + getClassName(o));
625  
              list.add(o);
626  
              if (eq(t(), ",")) consume();
627  
            }
628  
          });
629  
        }
630  
      });
631  
    }
632  
    
633  
    void parseArray(unstructure_Receiver out) {
634  
      S _type = tpp();
635  
      int dims;
636  
637  
      if (eq(t(), "S")) { // string array
638  
        _type = "S";
639  
        consume();
640  
      }
641  
      
642  
      if (eq(t(), "/")) { // multi-dimensional array
643  
        consume();
644  
        dims = parseInt(tpp());
645  
      } else
646  
        dims = 1;
647  
      
648  
      consume("{");
649  
      List list = new ArrayList;
650  
      S type = _type;
651  
      
652  
      stack.add(r {
653  
        if (eq(t(), "}")) {
654  
          consume("}");
655  
          if (dims > 1) {
656  
            Class atype;
657  
            if (type.equals("intarray")) atype = int.class;
658  
            else if (type.equals("S")) atype = S.class;
659  
            else todo("multi-dimensional arrays of other types");
660  
            
661  
            out.set(list.toArray((O[]) newMultiDimensionalOuterArray(atype, dims, l(list))));
662  
          } else
663  
            out.set(
664  
              type.equals("intarray") ? toIntArray(list)
665  
              : type.equals("dblarray") ? toDoubleArray(list)
666  
              : type.equals("S") ? toStringArray(list)
667  
              : list.toArray());
668  
        } else {
669  
          stack.add(this);
670  
          parse(new unstructure_Receiver {
671  
            void set(O o) {
672  
              list.add(o);
673  
              if (eq(t(), ",")) consume();
674  
            }
675  
          });
676  
        }
677  
      });
678  
    }
679  
    
680  
    Object parseClass() {
681  
      consume("class");
682  
      consume("(");
683  
      S name = unquote(tpp());
684  
      consume(")");
685  
      Class c = allDynamic ? null : findAClass(name);
686  
      if (c != null) ret c;
687  
      new DynamicObject dO;
688  
      dO.className = "java.lang.Class";
689  
      name = dropPrefix(mcDollar, name);
690  
      dO.fieldValues.put("name", name);
691  
      ret dO;
692  
    }
693  
    
694  
    Object parseBigInt() {
695  
      consume("bigint");
696  
      consume("(");
697  
      S val = tpp();
698  
      if (eq(val, "-"))
699  
        val = "-" + tpp();
700  
      consume(")");
701  
      ret new BigInteger(val);
702  
    }
703  
    
704  
    Object parseDouble() {
705  
      consume("d");
706  
      consume("(");
707  
      S val = unquote(tpp());
708  
      consume(")");
709  
      ret Double.parseDouble(val);
710  
    }
711  
    
712  
    Object parseFloat() {
713  
      consume("fl");
714  
      S val;
715  
      if (eq(t(), "(")) {
716  
        consume("(");
717  
        val = unquote(tpp());
718  
        consume(")");
719  
      } else {
720  
        val = unquote(tpp());
721  
      }
722  
      ret Float.parseFloat(val);
723  
    }
724  
    
725  
    void parseHashSet(unstructure_Receiver out) {
726  
      consume("hashset");
727  
      parseSet(new HashSet, out);
728  
    }
729  
    
730  
    void parseLinkedHashSet(unstructure_Receiver out) {
731  
      consume("lhs");
732  
      parseSet(new LinkedHashSet, out);
733  
    }
734  
    
735  
    void parseTreeSet(unstructure_Receiver out) {
736  
      consume("treeset");
737  
      parseSet(new TreeSet, out);
738  
    }
739  
    
740  
    void parseCISet(unstructure_Receiver out) {
741  
      consume("ciset");
742  
      parseSet(ciSet(), out);
743  
    }
744  
    
745  
    void parseMap(unstructure_Receiver out) {
746  
      parseMap(new TreeMap, out);
747  
    }
748  
    
749  
    O parseJava() {
750  
      S j = unquote(tpp());
751  
      new Matches m;
752  
      if (jmatch("java.awt.Color[r=*,g=*,b=*]", j, m))
753  
        ret nuObject("java.awt.Color", parseInt($1), parseInt($2), parseInt($3));
754  
      else {
755  
        warn("Unknown Java object: " + j);
756  
        null;
757  
      }
758  
    }
759  
    
760  
    void parseMap(final Map map, final unstructure_Receiver out) {
761  
      consume("{");
762  
      stack.add(new Runnable {
763  
        bool v;
764  
        O key;
765  
        
766  
        public void run() { 
767  
          if (v) {
768  
            v = false;
769  
            stack.add(this);
770  
            if (!eq(tpp(), "="))
771  
              fail("= expected, got " + t() + " in map of size " + l(map));
772  
773  
            parse(new unstructure_Receiver {
774  
              void set(O value) {
775  
                map.put(key, value);
776  
                ifdef unstructure_debug
777  
                  print("parseMap: Got value " + getClassName(value) + ", next token: " + quote(t()));
778  
                endifdef
779  
                if (eq(t(), ",")) consume();
780  
              }
781  
            });
782  
          } else {
783  
            if (eq(t(), "}")) {
784  
              consume("}");
785  
              out.set(map);
786  
            } else {
787  
              v = true;
788  
              stack.add(this);
789  
              parse(new unstructure_Receiver {
790  
                void set(O o) {
791  
                  key = o;
792  
                }
793  
              });
794  
            }
795  
          } // if v else
796  
        } // run()
797  
      });
798  
    }
799  
    
800  
    /*void parseSub(unstructure_Receiver out) {
801  
      int n = l(stack);
802  
      parse(out);
803  
      while (l(stack) > n)
804  
        stack
805  
    }*/
806  
    
807  
    void consume() { curT = tok.next(); ++i; }
808  
    
809  
    void consume(S s) {
810  
      if (!eq(t(), s)) {
811  
        /*S prevToken = i-1 >= 0 ? tok.get(i-1) : "";
812  
        S nextTokens = join(tok.subList(i, Math.min(i+2, tok.size())));
813  
        fail(quote(s) + " expected: " + prevToken + " " + nextTokens + " (" + i + "/" + tok.size() + ")");*/
814  
        fail(quote(s) + " expected, got " + quote(t()));
815  
      }
816  
      consume();
817  
    }
818  
    
819  
    // outer wrapper function getting first token and unwinding the stack
820  
    void parse_initial(unstructure_Receiver out) {
821  
      consume(); // get first token
822  
      parse(out);
823  
      while (nempty(stack))
824  
        popLast(stack).run();
825  
    }
826  
  }
827  
  
828  
  ThreadLocal<Bool> tlLoading = dynamicObjectIsLoading_threadLocal();
829  
  Bool b = tlLoading!;
830  
  tlLoading.set(true);
831  
  try {
832  
    final new Var v;
833  
    new X x;
834  
    x.parse_initial(new unstructure_Receiver {
835  
      void set(O o) { v.set(o); }
836  
    });
837  
    unstructure_tokrefs = x.tokrefs.size();
838  
    ret v.get();
839  
  } finally {
840  
    tlLoading.set(b);
841  
  }
842  
}
843  
844  
static boolean unstructure_debug;

Author comment

Began life as a copy of #1030946

download  show line numbers  debug dex  old transpilations   

Travelled to 3 computer(s): bhatertpkbcr, mowyntqkapby, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1034649
Snippet name: unstructure (v18, with enums, LIVE)
Eternal ID of this version: #1034649/8
Text MD5: db2eb14b035002437978127c6531fe63
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-05-06 16:09:53
Source code size: 25242 bytes / 844 lines
Pitched / IR pitched: No / No
Views / Downloads: 130 / 193
Version history: 7 change(s)
Referenced in: [show references]