Commit d8c1a50
committed
First checkin of partial meta function support, with
This commit includes "just enough" to make this first meta function work, which can be used like this...
```
Human: @interface type = {
speak: (this);
}
```
... where the implementation of `interface` is just about line-for-line from my paper P0707, and now (just barely!) compiles and runs in cppfront (and I did test the `.require` failure cases and it's quite lovely to see them merge with the compiler's own built-in diagnostics):
```
//-----------------------------------------------------------------------
// interface: an abstract base class having only pure virtual functions
auto interface( meta::type_declaration& t ) -> void {
bool has_dtor = false;
for (auto m : t.get_members()) {
m.require( !m.is_object(),
"interfaces may not contain data objects");
if (m.is_function()) {
auto mf = m.as_function();
mf.require( !mf.is_copy_or_move(),
"interfaces may not copy or move; consider a virtual clone() instead");
mf.require( !mf.has_initializer(),
"interface functions must not have a function body; remove the '=' initializer");
mf.require( mf.make_public(),
"interface functions must be public");
mf.make_function_virtual();
has_dtor |= mf.is_destructor();
}
}
if (!has_dtor) {
t.require( t.add_member( "operator=: (virtual move this) = { }"),
"could not add pure virtual destructor");
}
}
```
That's the only example that works so far.
To make this example work, so far I've added:
- The beginnings of a reflection API.
- The beginnings of generation from source code: The above `t.add_member` call now takes the source code fragment string, lexes it, parses it, and adds it to the `meta::type_declaration` object `t`.
- The first compile-time meta function that participates in interpreting the meaning of a type definition immediately after the type grammar is initially parsed (we'll never modify a type after it's defined, that would be ODR-bad).
I have NOT yet added the following, and won't get to them in the short term (thanks in advance for understanding):
- There is not yet a general reflection operator/expression.
- There is not yet a general Cpp2 interpreter that runs inside the cppfront compiler and lets users write meta functions like `interface` as external code outside the compiler. For now I've added `interface`, and I plan to add a few more from P0707, as meta functions provided within the compiler. But with this commit, `interface` is legitimately doing everything except being run through an interpreter -- it's using the `meta::` API and exercising it so I can learn how that API should expand and become richer, it's spinning up a new lexer and parser to handle code generation to add a member, it's stitching the generated result into the parse tree as if it had been written by the user explicitly... it's doing everything I envisioned for it in P0707 except for being run through an interpreter.
This commit is just one step. That said, it is a pretty big step, and I'm quite pleased to finally have reached this point.
---
This example is now part of the updated `pure2-types-inheritance.cpp2` test case:
// Before this commit it was this
Human: type = {
speak: (virtual this);
}
// Now it's this... and this fixed a subtle bug (can you spot it?)
Human: @interface type = {
speak: (this);
}
That's a small change, but it actually also silently fixed a bug that I had written in the original code but hadn't noticed: Before this commit, the `Human` interface did not have a virtual destructor (oops). But now it does, because part of `interface`'s implementation is to generate a virtual destructor if the user didn't write one, and so by letting the user (today, that was me) express their intent, we get to do more on their behalf. I didn't even notice the omission until I saw the diff for the test case's generated `.cpp` had added a `virtual ~Human()`... sweet.
Granted, if `Human` were a class I was writing for real use, I would have later discovered that I forgot to write a virtual destructor when I did more testing or tried to do a polymorphic destruction, or maybe a lint/checker tool might have told me. But by declaratively expressing my intent, I got to not only catch the problem earlier, but even prevent it.
I think it's a promising data point that my own first attempt to use a metaclass in such a simple way already fixed a latent simple bug in my own code that I hadn't noticed. Cool beans.
---
Re syntax: I considered several options to request a meta function `m` be applied to the type being defined, including variations of `is(m)` and `as(m)` and `type(m)` and `$m`. I'm going with `@m` for now, and not because of Python envy... there are two main reasons:
- I think "generation of new code is happening here" is such a fundamental and important new concept that it should be very visible, and actually warrants taking a precious new symbol. The idea of "generation" is likely to be more widely used, so being able to have a symbol reserved for that meaning everywhere is useful. The list of unused symbols is quite short (Cpp2 already took `$` for capture), and the `@` swirl maybe even visually connotes generation (like the swirl in a stirred pot -- we're stirring/cooking something up here -- or maybe it's just me).
- I want the syntax to not close the door on applying meta functions to declarations other than types. So putting the decoration up front right after `:` is important, because putting it at the end of the type would likely much harder to read for variables and especially functions.interface meta type function1 parent 65fcd0f commit d8c1a50
File tree
9 files changed
+945
-184
lines changed- regression-tests
- test-results
- source
9 files changed
+945
-184
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | | - | |
3 | | - | |
| 2 | + | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
| |||
27 | 28 | | |
28 | 29 | | |
29 | 30 | | |
30 | | - | |
| 31 | + | |
31 | 32 | | |
32 | 33 | | |
33 | 34 | | |
| 35 | + | |
34 | 36 | | |
35 | 37 | | |
36 | 38 | | |
| |||
86 | 88 | | |
87 | 89 | | |
88 | 90 | | |
| 91 | + | |
| 92 | + | |
89 | 93 | | |
90 | 94 | | |
91 | 95 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
57 | | - | |
58 | | - | |
| 57 | + | |
| 58 | + | |
59 | 59 | | |
60 | 60 | | |
61 | 61 | | |
| |||
258 | 258 | | |
259 | 259 | | |
260 | 260 | | |
261 | | - | |
262 | | - | |
263 | | - | |
264 | | - | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
265 | 265 | | |
266 | 266 | | |
267 | 267 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
724 | 724 | | |
725 | 725 | | |
726 | 726 | | |
727 | | - | |
| 727 | + | |
728 | 728 | | |
729 | 729 | | |
730 | 730 | | |
| |||
1228 | 1228 | | |
1229 | 1229 | | |
1230 | 1230 | | |
1231 | | - | |
| 1231 | + | |
1232 | 1232 | | |
1233 | 1233 | | |
1234 | 1234 | | |
| |||
1329 | 1329 | | |
1330 | 1330 | | |
1331 | 1331 | | |
1332 | | - | |
| 1332 | + | |
1333 | 1333 | | |
1334 | 1334 | | |
1335 | 1335 | | |
| |||
1398 | 1398 | | |
1399 | 1399 | | |
1400 | 1400 | | |
1401 | | - | |
| 1401 | + | |
1402 | 1402 | | |
1403 | 1403 | | |
1404 | 1404 | | |
| |||
1412 | 1412 | | |
1413 | 1413 | | |
1414 | 1414 | | |
1415 | | - | |
| 1415 | + | |
1416 | 1416 | | |
1417 | 1417 | | |
1418 | 1418 | | |
| |||
3226 | 3226 | | |
3227 | 3227 | | |
3228 | 3228 | | |
3229 | | - | |
| 3229 | + | |
3230 | 3230 | | |
3231 | 3231 | | |
3232 | 3232 | | |
| |||
3322 | 3322 | | |
3323 | 3323 | | |
3324 | 3324 | | |
3325 | | - | |
| 3325 | + | |
3326 | 3326 | | |
3327 | 3327 | | |
3328 | 3328 | | |
| |||
4660 | 4660 | | |
4661 | 4661 | | |
4662 | 4662 | | |
| 4663 | + | |
| 4664 | + | |
| 4665 | + | |
| 4666 | + | |
| 4667 | + | |
| 4668 | + | |
| 4669 | + | |
| 4670 | + | |
| 4671 | + | |
| 4672 | + | |
| 4673 | + | |
| 4674 | + | |
| 4675 | + | |
| 4676 | + | |
| 4677 | + | |
| 4678 | + | |
| 4679 | + | |
| 4680 | + | |
| 4681 | + | |
| 4682 | + | |
| 4683 | + | |
| 4684 | + | |
| 4685 | + | |
| 4686 | + | |
| 4687 | + | |
| 4688 | + | |
| 4689 | + | |
| 4690 | + | |
| 4691 | + | |
| 4692 | + | |
| 4693 | + | |
| 4694 | + | |
| 4695 | + | |
| 4696 | + | |
| 4697 | + | |
| 4698 | + | |
| 4699 | + | |
| 4700 | + | |
| 4701 | + | |
| 4702 | + | |
| 4703 | + | |
| 4704 | + | |
| 4705 | + | |
| 4706 | + | |
| 4707 | + | |
| 4708 | + | |
| 4709 | + | |
| 4710 | + | |
| 4711 | + | |
| 4712 | + | |
| 4713 | + | |
| 4714 | + | |
| 4715 | + | |
| 4716 | + | |
| 4717 | + | |
| 4718 | + | |
| 4719 | + | |
| 4720 | + | |
| 4721 | + | |
| 4722 | + | |
| 4723 | + | |
| 4724 | + | |
| 4725 | + | |
4663 | 4726 | | |
4664 | 4727 | | |
4665 | 4728 | | |
| |||
4700 | 4763 | | |
4701 | 4764 | | |
4702 | 4765 | | |
4703 | | - | |
4704 | | - | |
| 4766 | + | |
| 4767 | + | |
4705 | 4768 | | |
4706 | 4769 | | |
4707 | 4770 | | |
| |||
4859 | 4922 | | |
4860 | 4923 | | |
4861 | 4924 | | |
4862 | | - | |
| 4925 | + | |
4863 | 4926 | | |
4864 | | - | |
| 4927 | + | |
4865 | 4928 | | |
4866 | 4929 | | |
4867 | 4930 | | |
| |||
5319 | 5382 | | |
5320 | 5383 | | |
5321 | 5384 | | |
5322 | | - | |
| 5385 | + | |
5323 | 5386 | | |
5324 | | - | |
5325 | | - | |
| 5387 | + | |
5326 | 5388 | | |
5327 | 5389 | | |
5328 | 5390 | | |
| |||
5331 | 5393 | | |
5332 | 5394 | | |
5333 | 5395 | | |
5334 | | - | |
| 5396 | + | |
| 5397 | + | |
5335 | 5398 | | |
5336 | | - | |
| 5399 | + | |
| 5400 | + | |
5337 | 5401 | | |
| 5402 | + | |
5338 | 5403 | | |
5339 | 5404 | | |
5340 | 5405 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
846 | 846 | | |
847 | 847 | | |
848 | 848 | | |
849 | | - | |
850 | 849 | | |
851 | 850 | | |
852 | 851 | | |
853 | 852 | | |
854 | 853 | | |
855 | 854 | | |
856 | | - | |
857 | 855 | | |
858 | 856 | | |
859 | 857 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
86 | 86 | | |
87 | 87 | | |
88 | 88 | | |
| 89 | + | |
89 | 90 | | |
90 | 91 | | |
91 | 92 | | |
| |||
182 | 183 | | |
183 | 184 | | |
184 | 185 | | |
| 186 | + | |
185 | 187 | | |
186 | 188 | | |
187 | 189 | | |
| |||
515 | 517 | | |
516 | 518 | | |
517 | 519 | | |
518 | | - | |
| 520 | + | |
519 | 521 | | |
520 | 522 | | |
521 | 523 | | |
522 | 524 | | |
523 | 525 | | |
524 | 526 | | |
525 | 527 | | |
| 528 | + | |
526 | 529 | | |
527 | 530 | | |
528 | 531 | | |
529 | 532 | | |
530 | 533 | | |
531 | | - | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
532 | 537 | | |
533 | 538 | | |
534 | 539 | | |
| |||
677 | 682 | | |
678 | 683 | | |
679 | 684 | | |
680 | | - | |
| 685 | + | |
681 | 686 | | |
682 | 687 | | |
683 | 688 | | |
| |||
1286 | 1291 | | |
1287 | 1292 | | |
1288 | 1293 | | |
| 1294 | + | |
| 1295 | + | |
| 1296 | + | |
1289 | 1297 | | |
1290 | 1298 | | |
1291 | 1299 | | |
| |||
1721 | 1729 | | |
1722 | 1730 | | |
1723 | 1731 | | |
1724 | | - | |
| 1732 | + | |
1725 | 1733 | | |
1726 | 1734 | | |
1727 | 1735 | | |
| |||
1732 | 1740 | | |
1733 | 1741 | | |
1734 | 1742 | | |
1735 | | - | |
| 1743 | + | |
1736 | 1744 | | |
1737 | 1745 | | |
1738 | 1746 | | |
| |||
1879 | 1887 | | |
1880 | 1888 | | |
1881 | 1889 | | |
| 1890 | + | |
| 1891 | + | |
1882 | 1892 | | |
1883 | 1893 | | |
1884 | 1894 | | |
0 commit comments