Mixin C

Paul Backus snarwin at gmail.com
Fri Mar 8 03:23:12 UTC 2024


What if instead of importing C files like D modules, we could 
write bits of C code directly in the middle of our D code, like 
we do with inline ASM?

It might look something like this:

```d
void main()
{
     mixin(C) {
         #include <stdio.h>
         printf("Hello from C!\n");
     }
}
```

Here's how it could work:

1. The compiler takes the content of the `mixin(C)` block and 
passes it through the external C preprocessor.
2. The result of (1) is parsed as a C AST fragment using the 
ImportC parser.
3. The result of (2) is spliced into the AST in place of the 
`mixin(C)` block, and undergoes semantic analysis using ImportC 
semantics.

Mixin C would solve two big issues with the current ImportC 
approach: the poor preprocessor support, and the conflicts 
between `.c` and `.d` files in the compiler's import paths.

Because Mixin C runs the preprocessor at the point of *usage* 
rather than the point of *definition*, it allows you to make full 
use of C APIs that rely on the preprocessor, without having to 
translate macros to D (either automatically or by hand).

Because Mixin C blocks appear as code fragments inside `.d` 
files, rather than as separate `.c` files, you'll never have to 
worry about accidentally importing a C file when you meant to 
import a D module.

By the way, if you did want to treat a `.c` or `.h` file like its 
own module, you'd still be able to do so with Mixin C. Just write 
a simple `.d` wrapper, like this:

```d
module libwhatever;

mixin(C) {
     #include <libwhatever.h>
}
```

I haven't spent much time fleshing out the details of this idea, 
but it seems pretty promising. What do you guys think?


More information about the dip.ideas mailing list