This is a refocused version of #8. I'm closing #8 and opening this to help refocus discussion, given that we've split out parts of #8 and almost all of the comments there are outdated in one way or another.
NOTE: I merged in #24 (because I need it to sanity check that things work here). Please direct all discussion of things in lambda-buffers-common to that PR.
NOTE: This needs some cleaning up, which I will do tomorrow. Please focus discussion on the substantive content of the PR and not on (e.g.) missing export lists or disabled warnings or whatever. I promise I'll catch most/all of those tomorrow :P
This PR contains an initial implementation of code generation and typeclass machinery. Here's a brief explanation of the modules:
Common
LambdaBuffers.CodeGen.Common.Compat contains functions for translating the lambda-buffers-common types into the representation used by the rest of the machinery in lambda-buffers-codegen
LambdaBuffers.CodeGen.Common.Match contains a function for determining whether one pattern instance is a substitution instance of another, which is used in several places.
LambdaBuffers.CodeGen.Common.Types contains the basic Pat pattern type used in several places.
Gen
LambdaBuffers.CodeGen.Gen.Generator contains the basic machinery for operating on patterns. This is adapted from an applicative parser implementation for succinctness, reusability of codegen components, and to provide an ergonomic interface when writing code generator functions.
LambdaBuffers.CodeGen.Gen.Generator.PP contains small formatting utilities (generally speaking relevant to Rust codegen) that abstract out of some common patterns encountered when writing the Rust example
LambdaBuffers.CodeGen.Gen.RustGen.RustTy contains an example implementation of a Rust code generator for types (not instances, see next item in list) using the machinery.
LambdaBuffers.CodeGen.Gen.RustGen.Instances.Eq contains an example implementation of a code generator for Eq instances in Rust
Resolve
LambdaBuffers.CodeGen.Resolve.Rules contains the basic data types used to represent instance rules, type classes, and constraints.
LambdaBuffers.CodeGen.Resolve.Solve contains basic constraint solving logic. On its own, this doesn't do anything particularly interesting, but is a core component of the deriver (see next list item)
LambdaBuffers.CodeGen.Resolve.Derive contains the deriving logic, which integrates the code generation and constraint solving tools in order to attempt to derive the instances indicated by users
The codegen side of things, by contrast, was more brainstorm-ey and we might be able to do better. I think what I did ends up being more succinct/ergonomic/reusable than a naive implementation would but eh it needs some input from y'all.
ps @bladyjoker I don't understand how to use the new buildAbstraction nix function so I reverted to the old style for codegenBuild. Feel free to fix or lmk how the new thing works
This is a refocused version of #8. I'm closing #8 and opening this to help refocus discussion, given that we've split out parts of #8 and almost all of the comments there are outdated in one way or another.
NOTE: I merged in #24 (because I need it to sanity check that things work here). Please direct all discussion of things in
lambda-buffers-common
to that PR.NOTE: This needs some cleaning up, which I will do tomorrow. Please focus discussion on the substantive content of the PR and not on (e.g.) missing export lists or disabled warnings or whatever. I promise I'll catch most/all of those tomorrow :P
This PR contains an initial implementation of code generation and typeclass machinery. Here's a brief explanation of the modules:
Common
LambdaBuffers.CodeGen.Common.Compat
contains functions for translating thelambda-buffers-common
types into the representation used by the rest of the machinery inlambda-buffers-codegen
LambdaBuffers.CodeGen.Common.Match
contains a function for determining whether one pattern instance is a substitution instance of another, which is used in several places.LambdaBuffers.CodeGen.Common.Types
contains the basicPat
pattern type used in several places.Gen
LambdaBuffers.CodeGen.Gen.Generator
contains the basic machinery for operating on patterns. This is adapted from an applicative parser implementation for succinctness, reusability of codegen components, and to provide an ergonomic interface when writing code generator functions.LambdaBuffers.CodeGen.Gen.Generator.PP
contains small formatting utilities (generally speaking relevant to Rust codegen) that abstract out of some common patterns encountered when writing the Rust exampleLambdaBuffers.CodeGen.Gen.RustGen.RustTy
contains an example implementation of a Rust code generator for types (not instances, see next item in list) using the machinery.LambdaBuffers.CodeGen.Gen.RustGen.Instances.Eq
contains an example implementation of a code generator forEq
instances in RustResolve
LambdaBuffers.CodeGen.Resolve.Rules
contains the basic data types used to represent instance rules, type classes, and constraints.LambdaBuffers.CodeGen.Resolve.Solve
contains basic constraint solving logic. On its own, this doesn't do anything particularly interesting, but is a core component of the deriver (see next list item)LambdaBuffers.CodeGen.Resolve.Derive
contains the deriving logic, which integrates the code generation and constraint solving tools in order to attempt to derive the instances indicated by usersThe typeclass side of things is explained in painstaking detail in the typeclass documentation. Whatever we end up doing for typeclasses is going to have to look something like what I have here.
The codegen side of things, by contrast, was more brainstorm-ey and we might be able to do better. I think what I did ends up being more succinct/ergonomic/reusable than a naive implementation would but eh it needs some input from y'all.