Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Biplate Macro #2] New Uniplate Derive Macro #290

Merged
merged 2 commits into from
Sep 20, 2024

Commits on Sep 19, 2024

  1. uniplate_derive: add new Uniplate derive macro

    Reimplement the uniplate-derive macro to allow for Biplates and
    "multiple type traversals" as discussed in [Niklas Dewally, 2024‐03:
    Implementing Uniplates and Biplates with Structure Preserving Trees].
    (currently at
    https://github.com/conjure-cp/conjure-oxide/wiki/2024%E2%80%9003-Implementing-Uniplates-and-Biplates-with-Structure-Preserving-Trees).
    
    Implementation overview
    =======================
    
    The library syn supports the creation of custom AST nodes. Using the
    Parse trait, one can implement parsers for these custom nodes by
    combining existing Rust AST nodes together as well as parsing Rust
    tokens by hand.
    
    The macro code has two parts: parsing into a custom AST, and using this
    AST for code-gen. This simplifies code-gen, as only the data needed for
    Uniplate is encoded in the AST. This also allows for better error
    reporting, as Most errors are now reported during parsing, allowing
    errors to be associated with the specific tokens that caused them.
    
    The biggest change in Uniplate's AST compared to Rust's is the
    representation of types. Uniplate has three kinds of type: boxed pointer
    types, plateable types, and unpalatable types.
    Plateable types include the current type being derived, or other types
    explicitly specified through the walk_through attribute in the macro
    invocation.
    
    Boxed pointer types represent smart pointers such as Box and Rc. These
    use the .borrow() function instead of & to pass the inner value to the
    Biplate instance. Generating instances for Box<A> and Rc<A> would mean
    that values are constantly moved from stack to heap - this avoids this.
    
    Implementations for standard library iterator types and primitives are
    provided by Uniplate. These implementations are generated by declarative
    macro, allowing easy extension to more collection types in the future.
    
    Testing
    =======
    
    Add trybuild, a library for UI testing derive macros. The Rust tester
    does not run at-all when test code does not compile, but we need to test
    whether our macro gives a compile error when it should. trybuild also
    checks that the error messages given by the compiler have not changed.
    
    Two test ASTs are used for Uniplate and Biplates: a toy
    statement-expression found in the original paper, and the current
    Conjure Oxide AST. Property-based testing in paper.rs shows that
    children() and with_children() work for random homogenous AST's,
    including with boxes and iterators. As these two methods essentially act
    as wrappers for the child tree and context function returned by the
    uniplate() / biplate() methods, this test is sufficient to show that
    automatically derived Uniplate implementations act as intended.
    
    Signed-off-by: Niklas Dewally <niklas@dewally.com>
    niklasdewally committed Sep 19, 2024
    Configuration menu
    Copy the full SHA
    ce43062 View commit details
    Browse the repository at this point in the history
  2. core: replace manual uniplate impls with derive macro

    Replace the manual implementation of the Uniplate and Biplate traits for
    the AST with the derive macro.
    
    Adding uniplate_derive to the ast broke is_enum_variant, therefore this
    commit also removes and replaces all invocations of is_xxx() functions
    with let..else or pattern matching.
    
    Signed-off-by: Niklas Dewally <niklas@dewally.com>
    niklasdewally committed Sep 19, 2024
    Configuration menu
    Copy the full SHA
    4b6a1a3 View commit details
    Browse the repository at this point in the history