Finalize the X Macro article

Signed-off-by: Danila Fedorin <danila.fedorin@gmail.com>
This commit is contained in:
Danila Fedorin 2023-10-14 15:38:54 -07:00
parent dd232cedb5
commit c189da3671
2 changed files with 13 additions and 13 deletions

View File

@ -1,7 +1,6 @@
---
title: "My Favorite C++ Pattern: X Macros"
date: 2023-10-09T15:06:11-07:00
draft: true
tags: ["C++", "Chapel", "Compilers"]
description: "In this post, I talk about my favorite C/C++ pattern involving macros."
---
@ -12,7 +11,7 @@ then, I've used the pattern many more times, and have been very satisfied with
how it turned out. However, it feels like the pattern is relatively unknown, so
I thought I'd show it off, and some of its applications in the
[Chapel compiler](https://github.com/chapel-lang/chapel/). I've slightly tweaked
a lot of the snippets I directly present in this article for the sake of simpler
a lot of the snippets I directly show in this article for the sake of simpler
presentation; I've included links to the original code (available on GitHub)
if you want to see the unabridged version.
@ -44,7 +43,7 @@ returned. Some strings, however, occur a lot in the compiler, to the point that
it would be inefficient to perform the whole "find-or-create" operation every
time. One example is the `"this"` string, which is an identifier with a lot of
special behavior in the language (much like `this` in languages such as Java).
To support these frequent flier strings, the compiler initializes them once,
To support such frequent flier strings, the compiler initializes them once,
and creates a variable per-string that can be accessed to get that string's value.
There's that repetitive code. Defining a brand new variable for each string,
@ -75,11 +74,11 @@ X(bytes , "bytes")
// A lot more of these...
{{< /githubsnippet >}}
What's This `X` thing? That right there is the essence of the pattern: the macro
`X` _isn't defined in the header!_. Effectively, `all-global-strings.h` is just
What's this `X` thing? That right there is the essence of the pattern: the macro
`X` _isn't defined in the header!_ Effectively, `all-global-strings.h` is just
a list, and we can "iterate" over this list to generate some code for each
one of its elements, in as many places as we want. What I mean by this is
that we can then write code like this:
that we can then write code like the following:
{{< githubsnippet "chapel-lang/chapel" "cd108338d321d0b3edf6258e0b2a58459d88a348" "frontend/include/chpl/framework/global-strings.h" "C++" 76 >}}
struct GlobalStrings {
@ -150,8 +149,8 @@ that _use_ the compiler. I'll go through the use cases in turn.
#### Tags and Dynamic Casting
First, to deal with a general absence of
[RTTI](https://en.wikipedia.org/wiki/Run-time_type_information), it is used
to declare an "tag" enum. Each AST node has a tag matching its class;
[RTTI](https://en.wikipedia.org/wiki/Run-time_type_information), the hierarchy header
is used to declare a "tag" enum. Each AST node has a tag matching its class;
this allows us inspect the AST and perform safe casts similar to `dynamic_cast`.
Note that for parent classes (defined via `BEGIN_SUBCLASSES`), we actually
end up creating _two_ tags: one `START_...` and one `END_...`. The reason
@ -240,7 +239,7 @@ isLoop(AstTag::While) // Returns true; a 'while' loop is a loop.
```
On the top-level AST node class, we generate `isWhateverNode` and
`toWhateverNode` for each AST class. Thus, user code is able to inspect the
`toWhateverNode` for each AST subclass. Thus, user code is able to inspect the
AST and perform (checked) casts using plain methods. I omit `isWhateverNode`
here for brevity (its definition is very simple), and include only
`toWhateverNode`.
@ -288,7 +287,7 @@ random snippet of code I pulled out:
Thus, developers adding new AST nodes are not required to manually implement
the `isWhatever`, `toWhatever`, and other functions. This and a fair bit
of other AST functionality (which I will cover in the next subsection) is
automatically generating using X Macros.
automatically generated using X Macros.
{{< dialog >}}
{{< message "question" "reader" >}}
@ -599,7 +598,8 @@ struct PerNodeInfo {
};
{{< /githubsnippet >}}
Then, when I need to add methods, I do something like the following:
Then, when I need to add methods, I use template specialization by writing
something like the following:
```C++
template <>
@ -673,7 +673,7 @@ unfortunate remnants of C++'s past. However, I think that what I've demonstrated
demonstrates the versatility of the X Macro pattern -- feel free to apply it to
the degree that you find appropriate.
The thing I like the most pattern is that the header files read quite nicely:
The thing I like the most about this pattern is that the header files read quite nicely:
you end up with a very declarative "scaffold" of what's going on. The
`uast-classes-list.h` makes for an excellent and fairly readable reference of
all the AST nodes in the Chapel compiler. The `method-tables.h` header provides

View File

@ -1,6 +1,6 @@
---
title: "Proving My Compiler Code Incorrect With Alloy"
date: 2023-06-04T21:56:00-07:00
date: 2023-10-14T15:38:17-07:00
tags: ["Chapel", "Compilers", "Alloy"]
description: "In this post, I apply Alloy to a piece of code in the Chapel compiler to find a bug."
---