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

782
LINES

< > BotCompany Repo | #1031762 // unstructure_X (based on unstructure v17)

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

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

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

Author comment

Began life as a copy of #1030946

download  show line numbers  debug dex  old transpilations   

Travelled to 4 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, vouqrxazstgt

No comments. add comment

Snippet ID: #1031762
Snippet name: unstructure_X (based on unstructure v17)
Eternal ID of this version: #1031762/12
Text MD5: adfecf134d30e4767ca1970a4ae23961
Transpilation MD5: 927b231d663b0e81af2a1d1ef3d07fea
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-06-29 08:29:10
Source code size: 21395 bytes / 782 lines
Pitched / IR pitched: No / No
Views / Downloads: 197 / 372
Version history: 11 change(s)
Referenced in: [show references]