Skip to content

Latest commit

 

History

History
54 lines (44 loc) · 5.62 KB

project.org

File metadata and controls

54 lines (44 loc) · 5.62 KB

Project Notes and Todos

Directed traversal is like breadth-first because it needs to match an expression before it will enter it, unlike the depth-first ones which greedily go deep then ascend. That’s why (success) works right in breadth-first but not for directed. This could be fixed with substitute against the original pattern! And the substitute matcher could also be precompiled?

  • [X] use substitute in directed when (success) is called

Generally a breadth-first traversal rule may be interesting?

  • [ ] Build a general breadth-first rule combinator.
  • [ ] Build an iterative version.

Match map could be made to work if I mark the metadata as unordered and then force a fixed sort on the keys.

  • [X] Also, why not just pull the values out of the match map inside the match handler rather than before the handler? There is no benefit to turning them into args… Then the map match becomes no problem, right? I could get rid of the more complex ArrayMap stuff…
  • [X] Directed could work with plain rule combinators, it would just have to skip all the fancy stuff with those ones. (or all combinators could somehow support directed…)
  • [ ] Directed could have a set of “wrapper” rules that are just applied like in-order before entering the main rules. Those could handle unwrapping s-expr based type annotations.
    • [ ] TODO: write out what rules and data would look like with non-magic s-expr based type annotations.

Nanopass compiler

Goal

Nanopass is mostly a set of pattern matching tools, but everything is all mixed together in the most complex set of macros I’ve ever encountered. By reverse engineering that project into this, I can extract some really interesting applications of pattern matching that that project has evolved. The proof that I’ve done it is that I should be able to port over entire compilers written in Nanopass to this framework, and also follow the exercises in the IU compilers course using my framework.

Next steps

Dialect should add the correct prefixes to ?e* type matchers so that I can easily look up which vars are non-terminals and then easily add the -> or >- to their modes so that the autogenerated clause thing can happen.

  • [X] capture abbr in metadata
  • [ ] write out a couple full language rules once I have all of the other pieces working first, though so that I understand what really needs to be done (if anything). I think I’m ready to do this.

The alternative is to get hierarchical language expr matching working? Not totally confident on this. But if it works would probably be nice. Regardless the expressions need to be able to be traversed to find the parts that I want to munge.

I think directed maybe needs to be able to search the input for an expression that it wants to then do directed traversal on. This would be a breadth-first search. These are the clauses that need to be imported from the language def.

tagging

  • I am not happy with how metadata-based tagging works.
  • I think just simple tag wrapper s-exprs would be much more comprehensible and would be relatively easy to manage. The big problem is that it’s not easy to tell if metadata is present inside structures, some types can’t have metadata, and then behaviour just becomes confusing trying to match against this invisible aspect of data that is hard to control.

Racket-like macro system.

I think what I’ve created here is most of the Racket macro system and I furthermore think it’d be reasonably easy to implement the rest of it. For instance, couldn’t hygene be trivially added to sub? My pattern matching and substitution is already more powerful in most ways and only lacking a handful of pieces, mainly map and set syntax mapping

Ideas

dialect-case

I’d like to be able to traverse down to a given form type automatically, so the following could be a complete example. A bit of magic to get the traversal to the right place, then no magic in the response, just a function.

Question: how to deal with %env? Maybe I have a bit of magic looking for arity1 vs arity2, and also look explicitly for rules, and if found include them directly into the rule structure to enable further rule-combinator hyjinx.

(dialect-case Selected
              Stmt (fn [s] (do-something-with-any-stmt s)))

metadata

Some utilities to attach metadata in the right places

(success (with-meta ... (merge (meta (:rule/datum %env)) {... ...})))

automatic :rule/history metadata

On every rule result that captures the prev form in a vector and if there is already history, push the new prev form onto the end of the vector, so with multiple applications it could end up looking something like, :rule/history [(add 1 2) ((funref add.58) 1 2) ((funref add.58) (int 1) (int 2)) (addq (int 1) (int 2))]

  • sometimes a rule results in a list of things that then get spliced into a parent form. Somehow capture that? Perhaps with a special rule form that is meant for returning spliced lists of results? Maybe add the metadata to the first form in the list? Or to each form in the list?
  • Maybe the metadata should be a graph? A graph could be nice but generally right now graph objects are very opaque structures so some work needs to go into making them more intuitive / informative.

macro for scheme-style repeats using ... . Even maybe just on rules.

Actually … is a semi-valid symbol! It can’t be let-bound but can be defined with def, and '... is valid. Just do a simple transform: (def ?n [?arg ...] ?e ...) becomes (def ?n [(?:* ?arg)] (?:* ?e)) or scheme-style (let ([?v ?e] ...) ?b) becomes (let ((?:* [?v ?e])) ?b) the scheme-style is definitely more readable, but less powerful.