... | @@ -7,19 +7,44 @@ |
... | @@ -7,19 +7,44 @@ |
|
|
|
|
|
The new [HsSyn](implementing-trees-that-grow/hs-syn) AST supporting the TTG idiom (from now on referred to as TTG [HsSyn](implementing-trees-that-grow/hs-syn)) is engineered to subsume five different representations of Haskell syntax:
|
|
The new [HsSyn](implementing-trees-that-grow/hs-syn) AST supporting the TTG idiom (from now on referred to as TTG [HsSyn](implementing-trees-that-grow/hs-syn)) is engineered to subsume five different representations of Haskell syntax:
|
|
|
|
|
|
- the AST used in GHC's parsing phase
|
|
- AST GhcPs: the AST used in GHC's parsing phase
|
|
- the AST used in GHC's renaming phase
|
|
- AST GhcRn: the AST used in GHC's renaming phase
|
|
- the AST used in GHC's typechecking phase
|
|
- AST GhcTc: the AST used in GHC's typechecking phase
|
|
- the AST used in Template Haskell
|
|
- AST TH: the AST used in Template Haskell
|
|
- the AST used in an external tool such as Haskell-Src-Exts
|
|
- AST HSE: the AST used in an external tool such as Haskell-Src-Exts
|
|
|
|
|
|
|
|
|
|
The subsumption of above five ASTs is done by providing instances for the extension type families.
|
|
The subsumption of above five ASTs is done by providing instances for the extension type families.
|
|
For instance, the AST for GHC's parsing, renaming, and typechecking are defined by providing instances of the extension type families using accordingly the indices `GhcPs`, `GhcRn`, and `GhcTc`.
|
|
For instance, the AST for GHC's parsing, renaming, and typechecking are defined by providing instances of the extension type families using accordingly the indices `GhcPs`, `GhcRn`, and `GhcTc`.
|
|
[ Here](https://github.com/ghc/ghc/blob/master/compiler/hsSyn/HsPat.hs#L287-L336) is the actual providing such instances for the `Pat` datatype of patterns in the TTG [HsSyn](implementing-trees-that-grow/hs-syn).
|
|
[ Here](https://github.com/ghc/ghc/blob/master/compiler/hsSyn/HsExpr.hs#L737-L835) is the actual code providing such instances for the `HsExpr` datatype of expressions in the TTG [HsSyn](implementing-trees-that-grow/hs-syn).
|
|
|
|
|
|
Subsuming above five trees fixes the scope of the design space. For example, TTG [HsSyn](implementing-trees-that-grow/hs-syn) is not intended to subsume the AST in the GHC's backend (i.e., GHC Core), but it can indeed be used for other purposes like pretty-printing.
|
|
|
|
|
|
|
|
|
|
Subsuming above five trees fixes the scope of the design space. For example, TTG [HsSyn](implementing-trees-that-grow/hs-syn) is not intended to subsume the AST in the GHC's backend (i.e., GHC Core), but it can indeed be used for other purposes like prettyprinting and IDEs.
|
|
|
|
|
|
## Guiding Principles
|
|
## Guiding Principles
|
|
|
|
|
|
1. todo |
|
1. The instantiation of TTG [HsSyn](implementing-trees-that-grow/hs-syn) should result in a tree that does not have extra fields and constructors.
|
|
|
|
|
|
|
|
>
|
|
|
|
> For example, the `HsExpr GhsPs` expressions of AST Ps should not have the constructor `HsUnboundVar` of the post-renaming phases, or its `HsMultiIf` constructor should also not have an unused field (of the type `Type`) to store the related type produced in the typechecking phase.
|
|
|
|
|
|
|
|
>
|
|
|
|
> As a result, the instantiated TTG [HsSyn](implementing-trees-that-grow/hs-syn) should not depend on the code from the other phases. Hence, the base (uninstantiated) TTG [HsSyn](implementing-trees-that-grow/hs-syn) should not depend on any GHC/TH/HSE-specific code.
|
|
|
|
|
|
|
|
>
|
|
|
|
> For example, if `HsExpr GhsPs` expressions of AST Ps had the constructor `HsUnboundVar` then it had to depend on the code defining `UnboundVar` (a field of `HsUnboundVar`) in the renaming phase, or if its constructor `MultiIf` had a field of type `Type` then it had to depend on the code defining `Type` in the typechecking phase.
|
|
|
|
|
|
|
|
1. The base TTG [HsSyn](implementing-trees-that-grow/hs-syn) should have all the constructors common across all five ASTs, and these constructors should have all the fields common across all five ASTs (even if the type of some fields vary from an AST to another).
|
|
|
|
|
|
|
|
>
|
|
|
|
> SPJ refers to these common fields as "payload fields" (as opposed to extension fields).
|
|
|
|
|
|
|
|
1. The constructors that are not common are introduced using TTG's new constructor extensions.
|
|
|
|
|
|
|
|
1. For common constructors, their fields that are not common are grouped together and introduced using TTG's new field extensions.
|
|
|
|
|
|
|
|
1. For common constructors, their common fields (within common constructors) with a varying type, are given a type using a new type family that extracts from the phase descriptor the type specific to each AST.
|
|
|
|
|
|
|
|
>
|
|
|
|
> For example, the type of the common (payload) field of the common constructor `HsVar`of `HsExpr x` is `IdP x` where `IdP` is a type family and `x` the phase descriptor. |