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

Macro type-checking: support arithmetic conversions #299

Merged
merged 2 commits into from
Jan 15, 2025
Merged

Conversation

sheaf
Copy link
Collaborator

@sheaf sheaf commented Nov 22, 2024

This PR generalises macro type-checking to handle C arithmetic
conversion rules as per the C standard.

What this means is that in a C expression such as

  a + b

the values a and b are allowed to have different types, with
implicit conversions being inserted. For example:

  • a :: CFloat, b :: CInt => convert b to CFloat before adding
  • a :: Int, b :: UInt => convert a to UInt before adding

This is achieved as follows:

  • a new package, c-expr, with the following components:

    • c-expr-core, a public sublibrary which:

      • defines standard C types and C operators,
      • implements the C arithmetic conversion rules
      • defines a collection of type-classes that can be used for
        a DSL for C arithmetic expressions
      • uses Template Haskell to define a function that can, given
        a platform, implement all the instances of these typeclasses
        for types such as CInt, CUInt, CFloat, pointers, etc
    • c-expr, the main library, which exports platform-dependent
      modules such as C.Expr.Posix32 or C.Expr.Win64 with
      type-class instances for all the C arithmetic typeclasses

    • a test-suite, which uses hsbindgen-libclang to invoke Clang on
      test programs in order to check that the implementation
      of C arithmetic conversion rules in c-expr-core are
      compatible with Clang

  • the C macro typechecker imports c-expr-core, which it uses to
    compute type family reduction (e.g. the SubRes type family
    which computes the return type of the subtraction operator given
    its argument types)

  • hs-bindgen generates programs that will depend on c-expr, e.g.
    to turn a C macro into a Haskell function we will generate a module
    that imports the C arithmetic operator DSL provided by c-expr

To do this, we also needed to significantly generalise the macro
typechecker:

  • Make class constraints more general by allowing what GHC calls
    FlexibleContexts and FlexibleInstances,

  • Use a special monad for constraint solving, TcSolveM.
    This monad keeps track of a work list and a set of
    inert (= fully processed) constraints.

  • Solving a constraint using a top-level instance may now add
    additional constraints to the work list.

  • Instances are keyed using a TrieMap, similar to GHC's RoughMap,
    which avoids traversing all instances when doing instance matching.

@sheaf sheaf changed the title Tc macro conversions Macro type-checking: support arithmetic conversions Nov 22, 2024
@sheaf sheaf force-pushed the tc-macro-conversions branch 2 times, most recently from 7ea2449 to 0d74ee3 Compare December 5, 2024 09:15
@sheaf sheaf force-pushed the tc-macro-conversions branch from 54d5786 to 20a2374 Compare December 5, 2024 16:50
@sheaf sheaf force-pushed the tc-macro-conversions branch 9 times, most recently from 2692ed0 to 1f54608 Compare December 27, 2024 15:57
typing-c/src/C/Typing/Clang.hs Outdated Show resolved Hide resolved
typing-c/src/C/Typing/Clang.hs Outdated Show resolved Hide resolved
typing-c/src/C/Typing/Clang.hs Outdated Show resolved Hide resolved
typing-c/typing-c.cabal Outdated Show resolved Hide resolved
typing-c/src/C/Type.hs Outdated Show resolved Hide resolved
Copy link
Collaborator Author

@sheaf sheaf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For platform-dependent instances, we should provide separate modules with the instances for all supported platforms. Possibly also a Host platform that uses CPP to re-export the appropriate module.

typing-c/typing-c.cabal Outdated Show resolved Hide resolved
typing-c/typing-c.cabal Outdated Show resolved Hide resolved
typing-c/typing-c.cabal Outdated Show resolved Hide resolved
typing-c/typing-c.cabal Outdated Show resolved Hide resolved
@sheaf sheaf force-pushed the tc-macro-conversions branch 13 times, most recently from 65eb9e7 to 3485941 Compare January 13, 2025 15:43
sheaf added 2 commits January 13, 2025 17:04
This commit generalises macro type-checking to handle C arithmetic
conversion rules as per the C standard.

What this means is that in a C expression such as

  a + b

the values 'a' and 'b' are allowed to have different types, with
implicit conversions being inserted. For example:

  - a :: CFloat, b :: CInt => convert b to CFloat before adding
  - a :: Int, b :: UInt => convert a to UInt before adding

This is achieved as follows:

  - a new package, c-expr, with the following components:

    - c-expr-core, a public sublibrary which:

        - defines standard C types and C operators,
        - implements the C arithmetic conversion rules
        - defines a collection of type-classes that can be used for
          a DSL for C arithmetic expressions
        - uses Template Haskell to define a function that can, given
          a platform, implement all the instances of these typeclasses
          for types such as CInt, CUInt, CFloat, pointers, etc

    - c-expr, the main library, which exports **platform-dependent**
      modules such as `C.Expr.Posix32` or `C.Expr.Win64` with
      type-class instances for all the C arithmetic typeclasses

    - a test-suite, which uses hsbindgen-libclang to invoke Clang on
      test programs in order to check that the implementation
      of C arithmetic conversion rules in 'c-expr-core' are
      compatible with Clang

  - the C macro typechecker imports c-expr-core, which it uses to
    compute type family reduction (e.g. the 'SubRes' type family
    which computes the return type of the subtraction operator given
    its argument types)

  - hs-bindgen generates programs that will depend on c-expr, e.g.
    to turn a C macro into a Haskell function we will generate a module
    that imports the C arithmetic operator DSL provided by c-expr

To do this, we also needed to significantly generalise the macro
typechecker:

  - Make class constraints more general by allowing what GHC calls
    FlexibleContexts and FlexibleInstances,

  - Use a special monad for constraint solving, TcSolveM.
    This monad keeps track of a work list and a set of
    inert (= fully processed) constraints.

  - Solving a constraint using a top-level instance may now add
    additional constraints to the work list.

  - Instances are keyed using a TrieMap, similar to GHC's RoughMap,
    which avoids traversing all instances when doing instance matching.
This commit includes all the test changes subsequent to the previous
commit. It was kept separate for the sake of rebasing.
@sheaf sheaf force-pushed the tc-macro-conversions branch from cf0f847 to 305271b Compare January 13, 2025 16:04
@sheaf sheaf marked this pull request as ready for review January 13, 2025 16:17
@edsko edsko merged commit 9f636f0 into main Jan 15, 2025
10 checks passed
@edsko edsko deleted the tc-macro-conversions branch January 15, 2025 10:07
@edsko
Copy link
Collaborator

edsko commented Jan 15, 2025

Big chunk of work! Great to get this in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants