Libraryless. Click here for Pure Java version (3315L/20K).
sclass MetaTransformer { sinterface StructureHandler { default O transform(O o, IF1 recurse) { null; } void visit(O o, IVF1 recurse); } L<StructureHandler> structureHandlers; //bool keepUnknown; // assume true for now Set seen; // initialize to identityHashSet() if you want to check for cycles *() {} *(StructureHandler... handlers) { structureHandlers = asList(handlers); } void addStructureHandler aka add(StructureHandler sh) { structureHandlers.add(sh); } // if f returns null, go through structure // if f returns an object, do not recurse into it // TODO: honor seen O transform(IF1 f, O o) { ping(); O x = f.get(o); ifdef MetaTransformer_debug printVars_str("MetaTransformer.transform", +f, +o, +x); endifdef if (x != null) ret x; IF1 recurse = liftFunction(f); fOr (StructureHandler h : structureHandlers) { ping(); ifdef MetaTransformer_debug print("Calling structure handler " + h + " on " + className(o)); endifdef try object h.transform(o, recurse); } //ret keepUnknown ? o : null; ret o; } // transform without result void visit(IVF1 f, O o) { ping(); if (o == null) ret; if (seen != null && !seen.add(o)) ret; f.get(o); fOr (StructureHandler h : structureHandlers) { ping(); ifdef MetaTransformer_debug print("Calling structure handler " + h + " on " + className(o)); endifdef IVF1 recurse = x -> { markPointer(o, x); visit(f, x); }; h.visit(o, recurse); } } void visit_vstack(IVF1 f, O o) { vstackCompute(new visit_vstackComputable(f, o)); } record visit_vstackComputable(IVF1 f, O o) extends VStackComputableWithStep { void step(VStack stack) { if (step == 0) { ping(); if (o == null) ret with stack.ret(); step++; } if (step == 1) { if (seen != null && !seen.add(o)) ret with stack.ret(); ++step; } if (step == 2) { f.get(o); ++step; } stack.replace(new ForEach_vstack<>(structureHandlers, h -> { ifdef MetaTransformer_debug print("Calling structure handler " + h + " on " + className(o)); endifdef IVF1 recurse = x -> { markPointer(o, x); stack.call(new visit_vstackComputable(f, x)); }; h.visit(o, recurse); })); } } // lift transformer function to handle structures IF1 liftFunction(IF1 f) { ret o -> transform(f, o); } // check if any element satisfies a predicate. // Note: might even be faster without the cancel point logic bool any(IPred<O> pred, O o) { new Flag flag; withCancelPoint(cp -> visit(x -> { if (pred.get(x)) { flag.raise(); cancelTo(cp); } }, o) ); ret flag.isUp(); } void addVisitor(IVF1 visitor) { if (visitor == null) ret; addStructureHandler(new StructureHandler { public void visit(O o, IVF1 recurse) { visitor.get(o); } }); } void avoidCycles { seen = identityHashSet(); } swappable void markPointer(O a, O b) {} }
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: | 340 / 837 |
Version history: | 38 change(s) |
Referenced in: | #1034167 - Standard Classes + Interfaces (LIVE, continuation of #1003674) |