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

126
LINES

< > BotCompany Repo | #1027774 // MetaTransformer

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

Libraryless. Click here for Pure Java version (3315L/20K).

1  
sclass MetaTransformer {
2  
  sinterface StructureHandler {
3  
    default O transform(O o, IF1 recurse) { null; }
4  
    void visit(O o, IVF1 recurse);
5  
  }
6  
  
7  
  L<StructureHandler> structureHandlers;
8  
  //bool keepUnknown; // assume true for now
9  
  Set seen; // initialize to identityHashSet() if you want to check for cycles
10  
  
11  
  *() {}
12  
  *(StructureHandler... handlers) { structureHandlers = asList(handlers); }
13  
  
14  
  void addStructureHandler aka add(StructureHandler sh) {
15  
    structureHandlers.add(sh);
16  
  }
17  
  
18  
  // if f returns null, go through structure
19  
  // if f returns an object, do not recurse into it
20  
  // TODO: honor seen
21  
  O transform(IF1 f, O o) {
22  
    ping();
23  
    O x = f.get(o);
24  
    ifdef MetaTransformer_debug
25  
      printVars_str("MetaTransformer.transform", +f, +o, +x);
26  
    endifdef
27  
    if (x != null) ret x;
28  
    
29  
    IF1 recurse = liftFunction(f);
30  
    fOr (StructureHandler h : structureHandlers) {
31  
      ping();
32  
      ifdef MetaTransformer_debug
33  
        print("Calling structure handler " + h + " on " + className(o));
34  
      endifdef
35  
      try object h.transform(o, recurse);
36  
    }
37  
    
38  
    //ret keepUnknown ? o : null;
39  
    ret o;
40  
  }
41  
  
42  
  // transform without result
43  
  void visit(IVF1 f, O o) {
44  
    ping();
45  
    if (o == null) ret;
46  
    if (seen != null && !seen.add(o)) ret;
47  
    f.get(o);
48  
    
49  
    fOr (StructureHandler h : structureHandlers) {
50  
      ping();
51  
      ifdef MetaTransformer_debug
52  
        print("Calling structure handler " + h + " on " + className(o));
53  
      endifdef
54  
      IVF1 recurse = x -> {
55  
        markPointer(o, x);
56  
        visit(f, x);
57  
      };
58  
      h.visit(o, recurse);
59  
    }
60  
  }
61  
  
62  
  void visit_vstack(IVF1 f, O o) {
63  
    vstackCompute(new visit_vstackComputable(f, o));
64  
  }
65  
  
66  
  record visit_vstackComputable(IVF1 f, O o) extends VStackComputableWithStep {
67  
    void step(VStack stack) {
68  
      if (step == 0) {
69  
        ping();
70  
        if (o == null) ret with stack.ret();
71  
        step++;
72  
      }
73  
      
74  
      if (step == 1) {
75  
        if (seen != null && !seen.add(o)) ret with stack.ret();
76  
        ++step;
77  
      }
78  
      
79  
      if (step == 2) {
80  
        f.get(o);
81  
        ++step;
82  
      }
83  
      
84  
      stack.replace(new ForEach_vstack<>(structureHandlers, h -> {
85  
        ifdef MetaTransformer_debug
86  
          print("Calling structure handler " + h + " on " + className(o));
87  
        endifdef
88  
        IVF1 recurse = x -> {
89  
          markPointer(o, x);
90  
          stack.call(new visit_vstackComputable(f, x));
91  
        };
92  
        h.visit(o, recurse);
93  
      }));
94  
    }
95  
  }
96  
  
97  
  // lift transformer function to handle structures
98  
  IF1 liftFunction(IF1 f) {
99  
    ret o -> transform(f, o);
100  
  }
101  
  
102  
  // check if any element satisfies a predicate.
103  
  // Note: might even be faster without the cancel point logic
104  
  bool any(IPred<O> pred, O o) {
105  
    new Flag flag;
106  
    withCancelPoint(cp ->
107  
      visit(x -> { if (pred.get(x)) { flag.raise(); cancelTo(cp); } }, o)
108  
    );
109  
    ret flag.isUp();
110  
  }
111  
  
112  
  void addVisitor(IVF1 visitor) {
113  
    if (visitor == null) ret;
114  
    addStructureHandler(new StructureHandler {
115  
      public void visit(O o, IVF1 recurse) {
116  
        visitor.get(o);
117  
      }
118  
    });
119  
  }
120  
  
121  
  void avoidCycles {
122  
    seen = identityHashSet();
123  
  }
124  
  
125  
  swappable void markPointer(O a, O b) {}
126  
}

Author comment

Began life as a copy of #1027751

download  show line numbers  debug dex  old transpilations   

Travelled to 7 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv

No comments. add comment

Snippet ID: #1027774
Snippet name: MetaTransformer
Eternal ID of this version: #1027774/39
Text MD5: 7bc1ba1ee2245f85963e160efe0a1c20
Transpilation MD5: a936ed4dd735eb13a972444ffbdde981
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-06-29 06:50:46
Source code size: 3344 bytes / 126 lines
Pitched / IR pitched: No / No
Views / Downloads: 341 / 839
Version history: 38 change(s)
Referenced in: [show references]