blog

My blog.

Home

Source code

git clone https://projects.rickardlindberg.me/scm/blog.git

Website

https://blog.rickardlindberg.me

Recent events

2025-12-15 22:23 Rickard pushed to blog

commit 23be08c456f904d2b50f77e1a245dc63e77187bc
Author: Rickard Lindberg <rickard@rickardlindberg.me>
Date:   Mon Dec 15 22:23:09 2025 +0100

    New post maze math puzzles

diff --git a/posts/2025/12/15/maze-math-puzzles/post.md b/posts/2025/12/15/maze-math-puzzles/post.md
new file mode 100644
index 0000000..1b4725f
--- /dev/null
+++ b/posts/2025/12/15/maze-math-puzzles/post.md
@@ -0,0 +1,233 @@
+---
+date: 2025-12-15 22:18:00
+title: Maze Math Puzzles
+tags: aoc
+---
+
+<style type="text/css">
+pre { padding: 10px; }
+pre.highlight                    { background: #002b36; }
+pre.highlight                    { color: #93a1a1; }
+pre.highlight span.Meta          { color: #d33682; }
+pre.highlight span.Reserved      { color: #859900; }
+pre.highlight span.String        { color: #2aa198; }
+pre.highlight span.CharString    { color: #ffffff; }
+pre.highlight span.Escape        { color: #dc322f; }
+pre.highlight span.RuleName      { color: #268bd2; }
+pre.highlight span.VariableName  { color: #b58900; }
+</style>
+
+Inspired by [](post:2025/12/13/advent-of-code-2025/post.md), I wanted to make
+some kind of similar puzzle for my son. He usually takes some interest in me
+solving the problems. He even helped me program some solutions last year. But
+it mostly meant I told him what keys to press. Programming is a little hard.
+But he likes math.
+
+So I came up with an idea to generate maze math problems.
+
+Your task is to walk from start to end in a maze. You also carry a backpack
+with a number in it. That number is initially 1. When you cross another number
+on your way to the end, you add the number that you have in your backpack with
+the number you just encountered and put the result back in your backpack. When
+you cross an operator, it changes what operation you perform the next time you
+cross a number. The puzzle answer is the number that you have in your backpack
+when you reach the end.
+
+Here is the first puzzle that I generated that I had my son solve:
+
+<pre class="highlight">#########################################
+# <span class="Reserved">S</span>     #                               #
+#####   #   #############################
+#       #                               #
+#   #####   #########################   #
+#   #       #     <span class="RuleName">4</span>                     #
+#   #########   #####################   #
+#         <span class="VariableName">*</span>   <span class="RuleName">2</span> # <span class="VariableName">*</span>                 # <span class="VariableName">+</span> #
+#################   #########   #   #   #
+#     <span class="RuleName">3</span>             #           #   #   #
+#########   #########   #########   #   #
+# <span class="RuleName">4</span>     # <span class="VariableName">*</span>     #       #   #     <span class="VariableName">+</span> #   #
+#   #   #########   #####   #   #####   #
+#   #               #         <span class="RuleName">4</span> # <span class="RuleName">3</span>     #
+#   #############################   #####
+#     <span class="RuleName">2</span>                     #       # <span class="RuleName">2</span> #
+#########################   #   #####   #
+#     <span class="RuleName">3</span>               <span class="VariableName">+</span>     #     <span class="Escape">E</span>     #
+#   #################################   #
+#                                       #
+#########################################
+</pre>
+
+I had to explain the rules a few times before he got it. But then he was able
+to solve it. It was both a little challenging to remember the number in the
+backpack and to remember what operation to perform. The mazes don't seem to be
+too hard to solve right now. Perhaps I have done something wrong in the
+generation code? There are often few choices that you can make.
+
+Can you figure out the answer?
+
+The program that generates the mazes also helpfully shows the answer and the
+path from start to end:
+
+<pre class="highlight">Answer = <span class="RuleName">1</span><span class="RuleName">1</span>
+#########################################
+# <span class="Reserved">S</span>   <span class="Meta">.</span> #                               #
+#####   #   #############################
+# <span class="Meta">.</span>   <span class="Meta">.</span> #                               #
+#   #####   #########################   #
+# <span class="Meta">.</span> #       # <span class="Meta">.</span>   <span class="RuleName">4</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> #
+#   #########   #####################   #
+# <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="VariableName">*</span>   <span class="RuleName">2</span> # <span class="VariableName">*</span>                 # <span class="VariableName">+</span> #
+#################   #########   #   #   #
+#     <span class="RuleName">3</span>             #           #   # <span class="Meta">.</span> #
+#########   #########   #########   #   #
+# <span class="RuleName">4</span>     # <span class="VariableName">*</span>     #       #   #     <span class="VariableName">+</span> # <span class="Meta">.</span> #
+#   #   #########   #####   #   #####   #
+#   #               #         <span class="RuleName">4</span> # <span class="RuleName">3</span>   <span class="Meta">.</span> #
+#   #############################   #####
+#     <span class="RuleName">2</span>                     # <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="RuleName">2</span> #
+#########################   #   #####   #
+#     <span class="RuleName">3</span>               <span class="VariableName">+</span>     # <span class="Meta">.</span>   <span class="Escape">E</span>     #
+#   #################################   #
+#                                       #
+#########################################
+</pre>
+
+Right now only numbers 1, 2, 3, and 4 are used and operators `+` and `*`. We
+can easily make the problems harder by adding bigger numbers and more
+operators.
+
+We can also get harder problems by generating mazes a few times at random. Here
+is one for example:
+
+<pre class="highlight">#########################################
+# <span class="Reserved">S</span>       <span class="RuleName">2</span> #                           #
+#########   #   #########   #############
+#       #   #   #       #     <span class="RuleName">3</span>         #
+#   #   #   #####   #   #############   #
+#   #   #   #       #         <span class="VariableName">+</span>   <span class="VariableName">*</span> # <span class="RuleName">4</span> #
+#   #   #   #   #################   #   #
+#   #   #       #               # <span class="RuleName">3</span> #   #
+#   #################   #####   #   #   #
+#         <span class="RuleName">2</span>         #   #       #       #
+#############   #   #####   #   #####   #
+#             <span class="RuleName">3</span> # <span class="VariableName">+</span>   <span class="RuleName">4</span>     #   #       #
+#   #############################   #####
+#                               #       #
+#############################   #####   #
+#                 <span class="VariableName">*</span>         #   #     <span class="RuleName">4</span> #
+#   #####################   #   #   #####
+#   # <span class="VariableName">*</span>                       <span class="VariableName">+</span> # <span class="Escape">E</span> #   #
+#   #############################   #   #
+#                                 <span class="RuleName">2</span>     #
+#########################################
+Answer = <span class="RuleName">3</span><span class="RuleName">6</span>
+#########################################
+# <span class="Reserved">S</span>   <span class="Meta">.</span>   <span class="RuleName">2</span> #                           #
+#########   #   #########   #############
+#       # <span class="Meta">.</span> #   # <span class="Meta">.</span>   <span class="Meta">.</span> #     <span class="RuleName">3</span>         #
+#   #   #   #####   #   #############   #
+#   #   # <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="VariableName">+</span>   <span class="VariableName">*</span> # <span class="RuleName">4</span> #
+#   #   #   #   #################   #   #
+#   #   # <span class="Meta">.</span>   <span class="Meta">.</span> #               # <span class="RuleName">3</span> #   #
+#   #################   #####   #   #   #
+#         <span class="RuleName">2</span>         #   #       # <span class="Meta">.</span>   <span class="Meta">.</span> #
+#############   #   #####   #   #####   #
+#             <span class="RuleName">3</span> # <span class="VariableName">+</span>   <span class="RuleName">4</span>     #   # <span class="Meta">.</span>   <span class="Meta">.</span> #
+#   #############################   #####
+#                               # <span class="Meta">.</span>   <span class="Meta">.</span> #
+#############################   #####   #
+#                 <span class="VariableName">*</span>         #   # <span class="Meta">.</span>   <span class="RuleName">4</span> #
+#   #####################   #   #   #####
+#   # <span class="VariableName">*</span>                       <span class="VariableName">+</span> # <span class="Escape">E</span> #   #
+#   #############################   #   #
+#                                 <span class="RuleName">2</span>     #
+#########################################
+</pre>
+
+And of course we can play around with larger size:
+
+<pre class="highlight">#################################################################################
+# <span class="Reserved">S</span>       <span class="VariableName">*</span>     #                       #           #                       #   #
+#############   #   #################   #   #####   #   #################   #   #
+#   #           #           #               #           #       #           # <span class="VariableName">+</span> #
+#   #   #################   #   #############################   #   #########   #
+#       #                   #   # <span class="RuleName">4</span>                         #   #   #           #
+#   #############   #   #########   #####################   #   #   #########   #
+# <span class="RuleName">3</span>         #       #   #                   #               #       #         <span class="RuleName">4</span> #
+#########   #   #########   #################   #############   #####   #########
+#       #   #                   #               #           #   #   #     <span class="RuleName">4</span>     #
+#####   #   #####################   #############   #########   #   #   #####   #
+#       #             <span class="VariableName">*</span>             #           #   #         <span class="RuleName">3</span> #       #       #
+#   #   #################################   #   #   #   #################   #####
+#   #       #                               #       #           #       #       #
+#   #####   #####################   #########################   #   #   #####   #
+#   #       #           #       #       #                   #   #   #           #
+#   #   #####   #####   #   #   #####   #   #####   #########   #   #############
+#   #           #   #       #     <span class="Escape">E</span> #       #       # <span class="VariableName">*</span>         #               #
+#   #############   #############   #########   #####   #####################   #
+#           #               #       #       # <span class="RuleName">2</span> #       #                       #
+#########   #   #############   #####   #   #   #   #########   #################
+#           #         <span class="VariableName">+</span>                 # <span class="RuleName">3</span>     #   #       #             <span class="VariableName">*</span>     #
+#   #####   #################################   #   #   #   #   #############   #
+#   #       #                               #   #       #   #   #           #   #
+#   #########   #########################   #############   #####   #####   #   #
+#     <span class="VariableName">*</span>         #                           #           #           #   #       #
+#   #############   #########################   #####   #############   #####   #
+#   #               #                   #       #                 <span class="RuleName">2</span>         #   #
+#####   #####   #####   #############   #   #####   #########   #############   #
+#     <span class="RuleName">3</span> #       #       #           #       #       #         <span class="RuleName">4</span> #               #
+#   #############   #####   #####   #########   #####   #########   #############
+#             <span class="RuleName">4</span>     # <span class="RuleName">3</span>     #   #             <span class="RuleName">2</span> #   # <span class="VariableName">+</span>     #       #           #
+#####################   #####   #################   #####   #   #####   #####   #
+#                       #               #         <span class="RuleName">2</span>         #           #       #
+#   #################################   #   #############################   #####
+# <span class="RuleName">2</span>                       <span class="VariableName">+</span> #           #                           #       #   #
+#########################   #   #################################   #   #####   #
+#                           #                                       #   #       #
+#   #################################################################   #####   #
+#                                                                             <span class="VariableName">+</span> #
+#################################################################################
+Answer = <span class="RuleName">5</span><span class="RuleName">0</span>
+#################################################################################
+# <span class="Reserved">S</span>   <span class="Meta">.</span>   <span class="VariableName">*</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> #   #
+#############   #   #################   #   #####   #   #################   #   #
+#   # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> #         <span class="Meta">.</span>   <span class="Meta">.</span> #     <span class="Meta">.</span>   <span class="Meta">.</span> #       # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="VariableName">+</span> #
+#   #   #################   #   #############################   #   #########   #
+# <span class="Meta">.</span>   <span class="Meta">.</span> #         <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> #   # <span class="RuleName">4</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> #   # <span class="Meta">.</span> #           #
+#   #############   #   #########   #####################   #   #   #########   #
+# <span class="RuleName">3</span>   <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span> #   # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>         # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span> #         <span class="RuleName">4</span> #
+#########   #   #########   #################   #############   #####   #########
+#       # <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>     # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> #           # <span class="Meta">.</span> #   #     <span class="RuleName">4</span>     #
+#####   #   #####################   #############   #########   #   #   #####   #
+# <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="VariableName">*</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> #           #   # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="RuleName">3</span> #       #       #
+#   #   #################################   #   #   #   #################   #####
+# <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span> #                               #       # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> #       #       #
+#   #####   #####################   #########################   #   #   #####   #
+# <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span> #       #                   # <span class="Meta">.</span> #   #           #
+#   #   #####   #####   #   #   #####   #   #####   #########   #   #############
+# <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> #   # <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Escape">E</span> #       #       # <span class="VariableName">*</span>   <span class="Meta">.</span>   <span class="Meta">.</span> #               #
+#   #############   #############   #########   #####   #####################   #
+# <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> #               #       #       # <span class="RuleName">2</span> # <span class="Meta">.</span>   <span class="Meta">.</span> #                       #
+#########   #   #############   #####   #   #   #   #########   #################
+# <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> #         <span class="VariableName">+</span>                 # <span class="RuleName">3</span>     # <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span> #             <span class="VariableName">*</span>     #
+#   #####   #################################   #   #   #   #   #############   #
+# <span class="Meta">.</span> #       # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> #   # <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span> #   # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> #   #
+#   #########   #########################   #############   #####   #####   #   #
+# <span class="Meta">.</span>   <span class="VariableName">*</span>   <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> #   # <span class="Meta">.</span>   <span class="Meta">.</span> #
+#   #############   #########################   #####   #############   #####   #
+#   # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span>           <span class="RuleName">2</span>         # <span class="Meta">.</span> #
+#####   #####   #####   #############   #   #####   #########   #############   #
+# <span class="Meta">.</span>   <span class="RuleName">3</span> #       # <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span> #         <span class="RuleName">4</span> # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> #
+#   #############   #####   #####   #########   #####   #########   #############
+# <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="RuleName">4</span>   <span class="Meta">.</span> # <span class="RuleName">3</span>   <span class="Meta">.</span> #   # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="RuleName">2</span> #   # <span class="VariableName">+</span>     # <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> #
+#####################   #####   #################   #####   #   #####   #####   #
+# <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> #               #         <span class="RuleName">2</span>         # <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> # <span class="Meta">.</span>   <span class="Meta">.</span> #
+#   #################################   #   #############################   #####
+# <span class="RuleName">2</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="VariableName">+</span> #           #                           # <span class="Meta">.</span>   <span class="Meta">.</span> #   #
+#########################   #   #################################   #   #####   #
+# <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span> #                                       # <span class="Meta">.</span> #       #
+#   #################################################################   #####   #
+# <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>   <span class="Meta">.</span>       <span class="VariableName">+</span> #
+#################################################################################
+</pre>

commit dde5983d88ac9102f18f83b3a2c24ebc57f8b2f8
Author: Rickard Lindberg <rickard@rickardlindberg.me>
Date:   Mon Dec 15 22:05:08 2025 +0100

    Fix bug in sorting code

diff --git a/blog.py b/blog.py
index b10f4c0..61634cf 100755
--- a/blog.py
+++ b/blog.py
@@ -324,7 +324,7 @@ class Posts:
         ul = Tag("ul")
         for post in sorted(
             self.by_id.values(),
-            key=lambda post: post.date,
+            key=lambda post: post.date.date,
             reverse=True
         ):
             li = Tag("li")

2025-12-14 14:21 Rickard pushed to blog

commit fedefd512f79347a931b2f075a36f8d5df2b9fd8
Author: Rickard Lindberg <rickard@rickardlindberg.me>
Date:   Sun Dec 14 14:21:14 2025 +0100

    Add aoc tag

diff --git a/posts/2025/12/13/advent-of-code-2025/post.md b/posts/2025/12/13/advent-of-code-2025/post.md
index 4994d11..604e5b9 100644
--- a/posts/2025/12/13/advent-of-code-2025/post.md
+++ b/posts/2025/12/13/advent-of-code-2025/post.md
@@ -1,7 +1,7 @@
 ---
 date: 2025-12-14 14:20:00
 title: Advent of Code 2025
-tags: rlworkbench,c
+tags: rlworkbench,c,aoc
 ---
 
 <style type="text/css">

2025-12-14 14:20 Rickard pushed to blog

commit 9ecacb38906777388e05c6deeccdb477602c0288
Author: Rickard Lindberg <rickard@rickardlindberg.me>
Date:   Sun Dec 14 14:20:50 2025 +0100

    Advent of Code 2025

diff --git a/posts/2025/12/13/advent-of-code-2025/aoc20251-parser-only.meta b/posts/2025/12/13/advent-of-code-2025/aoc20251-parser-only.meta
new file mode 100644
index 0000000..0669e1a
--- /dev/null
+++ b/posts/2025/12/13/advent-of-code-2025/aoc20251-parser-only.meta
@@ -0,0 +1,14 @@
+main = instruction* !.;
+
+instruction = 
+    | left
+    | right
+    ;
+
+left[Reserved] = 'L' number '\n';
+
+right[RuleName] = 'R' number '\n';
+
+number = digit digit*;
+
+digit = '0'-'9';
diff --git a/posts/2025/12/13/advent-of-code-2025/aoc20251.meta b/posts/2025/12/13/advent-of-code-2025/aoc20251.meta
new file mode 100644
index 0000000..f843124
--- /dev/null
+++ b/posts/2025/12/13/advent-of-code-2025/aoc20251.meta
@@ -0,0 +1,54 @@
+main = instruction*:xs !. -> {
+    $dialSize
+    >dialSize { "100" }
+    "#include <stdio.h>\n"
+    "typedef struct {\n" >
+        "unsigned int positive_offset;\n"
+        "unsigned int partial;\n"
+        "unsigned int complete;\n"
+    < "} Turn;\n"
+    "static Turn turns[] = {\n" >
+        xs
+    < "};\n"
+    "static unsigned int number_of_turns = " xs.count ";\n"
+    "int main(void) {\n" >
+        "unsigned int dial_position = 50;\n"
+        "unsigned int times_ended_at_zero = 0;\n"
+        "unsigned int times_at_zero = 0;\n"
+        "unsigned int turn_index;\n"
+        "unsigned int partial_counter;\n"
+        "for(turn_index=0; turn_index<number_of_turns; turn_index++) {\n" >
+            "for(partial_counter=0; partial_counter<turns[turn_index].partial; partial_counter++) {\n" >
+                "dial_position += turns[turn_index].positive_offset;\n"
+                "dial_position %= " <dialSize ";\n"
+                "if (dial_position == 0) {\n" >
+                    "times_at_zero += 1;\n"
+                < "}\n"
+            < "}\n"
+            "if (dial_position == 0) {\n" >
+                "times_ended_at_zero += 1;\n"
+            < "}\n"
+            "times_at_zero += turns[turn_index].complete;\n"
+        < "}\n"
+        "printf(\"Part 1: %d\\n\", times_ended_at_zero);\n"
+        "printf(\"Part 2: %d\\n\", times_at_zero);\n"
+        "return 0;\n"
+    < "}\n"
+};
+
+instruction = 
+    | left:x -> { x }
+    | right:x -> { x }
+    ;
+
+left[Reserved] = 'L' number:x '\n' -> {
+    "{" <dialSize "-1, " x "%" <dialSize ", " x "/" <dialSize "},\n"
+};
+
+right[RuleName] = 'R' number:x '\n' -> {
+    "{1, " x "%" <dialSize ", " x "/" <dialSize "},\n"
+};
+
+number = digit digit*;
+
+digit = '0'-'9';
diff --git a/posts/2025/12/13/advent-of-code-2025/example.aoc20251 b/posts/2025/12/13/advent-of-code-2025/example.aoc20251
new file mode 100644
index 0000000..53287c7
--- /dev/null
+++ b/posts/2025/12/13/advent-of-code-2025/example.aoc20251
@@ -0,0 +1,10 @@
+L68
+L30
+R48
+L5
+R60
+L55
+L1
+L99
+R14
+L82
diff --git a/posts/2025/12/13/advent-of-code-2025/example_aoc20251.c b/posts/2025/12/13/advent-of-code-2025/example_aoc20251.c
new file mode 100644
index 0000000..f426d74
--- /dev/null
+++ b/posts/2025/12/13/advent-of-code-2025/example_aoc20251.c
@@ -0,0 +1,42 @@
+#include <stdio.h>
+typedef struct {
+    unsigned int positive_offset;
+    unsigned int partial;
+    unsigned int complete;
+} Turn;
+static Turn turns[] = {
+    {100-1, 68%100, 68/100},
+    {100-1, 30%100, 30/100},
+    {1, 48%100, 48/100},
+    {100-1, 5%100, 5/100},
+    {1, 60%100, 60/100},
+    {100-1, 55%100, 55/100},
+    {100-1, 1%100, 1/100},
+    {100-1, 99%100, 99/100},
+    {1, 14%100, 14/100},
+    {100-1, 82%100, 82/100},
+};
+static unsigned int number_of_turns = 10;
+int main(void) {
+    unsigned int dial_position = 50;
+    unsigned int times_ended_at_zero = 0;
+    unsigned int times_at_zero = 0;
+    unsigned int turn_index;
+    unsigned int partial_counter;
+    for(turn_index=0; turn_index<number_of_turns; turn_index++) {
+        for(partial_counter=0; partial_counter<turns[turn_index].partial; partial_counter++) {
+            dial_position += turns[turn_index].positive_offset;
+            dial_position %= 100;
+            if (dial_position == 0) {
+                times_at_zero += 1;
+            }
+        }
+        if (dial_position == 0) {
+            times_ended_at_zero += 1;
+        }
+        times_at_zero += turns[turn_index].complete;
+    }
+    printf("Part 1: %d\n", times_ended_at_zero);
+    printf("Part 2: %d\n", times_at_zero);
+    return 0;
+}
diff --git a/posts/2025/12/13/advent-of-code-2025/interesting.c b/posts/2025/12/13/advent-of-code-2025/interesting.c
new file mode 100644
index 0000000..51b48c5
--- /dev/null
+++ b/posts/2025/12/13/advent-of-code-2025/interesting.c
@@ -0,0 +1,13 @@
+static Turn turns[] = {
+    {100-1, 68%100, 68/100},
+    {100-1, 30%100, 30/100},
+    {1, 48%100, 48/100},
+    {100-1, 5%100, 5/100},
+    {1, 60%100, 60/100},
+    {100-1, 55%100, 55/100},
+    {100-1, 1%100, 1/100},
+    {100-1, 99%100, 99/100},
+    {1, 14%100, 14/100},
+    {100-1, 82%100, 82/100},
+};
+static unsigned int number_of_turns = 10;
diff --git a/posts/2025/12/13/advent-of-code-2025/post.md b/posts/2025/12/13/advent-of-code-2025/post.md
new file mode 100644
index 0000000..4994d11
--- /dev/null
+++ b/posts/2025/12/13/advent-of-code-2025/post.md
@@ -0,0 +1,666 @@
+---
+date: 2025-12-14 14:20:00
+title: Advent of Code 2025
+tags: rlworkbench,c
+---
+
+<style type="text/css">
+pre { padding: 10px; }
+pre.highlight                    { background: #002b36; }
+pre.highlight                    { color: #93a1a1; }
+pre.highlight span.Meta          { color: #d33682; }
+pre.highlight span.Reserved      { color: #859900; }
+pre.highlight span.String        { color: #2aa198; }
+pre.highlight span.CharString    { color: #ffffff; }
+pre.highlight span.Escape        { color: #dc322f; }
+pre.highlight span.RuleName      { color: #268bd2; }
+pre.highlight span.VariableName  { color: #b58900; }
+</style>
+
+**Warning: This blog post contains spoilers. If you don't want any insights
+into this years' puzzles, stop reading now.**
+
+I couldn't resist participating in [Advent of Code](https://adventofcode.com)
+this year either.
+
+Usually I challenge myself by solving the puzzles in some new kind of way.
+This year I decided to take a meta approach. What does that mean?
+
+In my [last
+newsletter](https://buttondown.com/rickardlindberg/archive/november-2025-can-rlworkbench-replace-vim/),
+I wrote about my new project, rlworkbench, where I try to build a [language
+workbench](https://en.wikipedia.org/wiki/Language_workbench). What is that?
+What am I trying to build?
+
+The way I think about it is that rlworkbench should be a text editor that is
+aware of the language of the text that is being edited. That awareness can give
+you syntax highlighting for example. But it can also give you more if it knows
+more about the language. For example, there might be an editor operation to
+expand the selection. If the cursor is inside a function, expanding the
+selection might select the whole function. Because the editor is aware of the
+language, it knows where the function starts and ends. Furthermore, defining
+the languages that rlworkbench knows about should be easy. And the norm should
+be to create many small domain specific languages. And when you define a
+language, it not only gives you editor support, but you can also define how
+that language should be compiled or translated.
+
+How does that relate to Advent of Code?
+
+Think of every day's puzzle input as its own language. The input is the
+program. Your job is to write a parser and code generator for that language.
+The parser provides editor support and the code generator compiles the puzzle
+input into something that can be executed. Because rlworkbench is written
+in C, and because I want to practice writing more C, I chose to make all code
+generators output C code.
+
+So the general shape of my solutions this year looked something like this:
+
+1. Write a parser for day X in the meta language of rlworkbench
+2. Write a code generator that transforms the input of day X into a C program
+3. Compile and run that C program
+4. Watch it print solutions for part 1 and part 2
+
+Since you usually don't edit the puzzle input, it is a bit contrived to see it
+as a language. But, hey, I wanted to experiment.
+
+Let's walk through day 1 in a bit of detail to show my process this year. Then
+I will continue with some highlights from each day.
+
+## Day 1
+
+The example input for [day 1](https://adventofcode.com/2025/day/1) looks like
+this:
+
+    L68
+    L30
+    R48
+    L5
+    R60
+    L55
+    L1
+    L99
+    R14
+    L82
+
+It is a sequence of instructions for how to rotate a dial.
+
+Here is a parser for this language, written in the meta language of
+rlworkbench:
+
+<pre class="highlight"><span class="RuleName">m</span><span class="RuleName">a</span><span class="RuleName">i</span><span class="RuleName">n</span> = <span class="RuleName">i</span><span class="RuleName">n</span><span class="RuleName">s</span><span class="RuleName">t</span><span class="RuleName">r</span><span class="RuleName">u</span><span class="RuleName">c</span><span class="RuleName">t</span><span class="RuleName">i</span><span class="RuleName">o</span><span class="RuleName">n</span><span class="Reserved">*</span> <span class="Reserved">!</span><span class="Reserved">.</span>;
+
+<span class="RuleName">i</span><span class="RuleName">n</span><span class="RuleName">s</span><span class="RuleName">t</span><span class="RuleName">r</span><span class="RuleName">u</span><span class="RuleName">c</span><span class="RuleName">t</span><span class="RuleName">i</span><span class="RuleName">o</span><span class="RuleName">n</span> =
+    <span class="Reserved">|</span> <span class="RuleName">l</span><span class="RuleName">e</span><span class="RuleName">f</span><span class="RuleName">t</span>
+    <span class="Reserved">|</span> <span class="RuleName">r</span><span class="RuleName">i</span><span class="RuleName">g</span><span class="RuleName">h</span><span class="RuleName">t</span>
+    ;
+
+<span class="RuleName">l</span><span class="RuleName">e</span><span class="RuleName">f</span><span class="RuleName">t</span>[<span class="Meta">R</span><span class="Meta">e</span><span class="Meta">s</span><span class="Meta">e</span><span class="Meta">r</span><span class="Meta">v</span><span class="Meta">e</span><span class="Meta">d</span>] = <span class="CharString">'</span><span class="CharString">L</span><span class="CharString">'</span> <span class="RuleName">n</span><span class="RuleName">u</span><span class="RuleName">m</span><span class="RuleName">b</span><span class="RuleName">e</span><span class="RuleName">r</span> <span class="CharString">'</span><span class="Escape">\</span><span class="Escape">n</span><span class="CharString">'</span>;
+
+<span class="RuleName">r</span><span class="RuleName">i</span><span class="RuleName">g</span><span class="RuleName">h</span><span class="RuleName">t</span>[<span class="Meta">R</span><span class="Meta">u</span><span class="Meta">l</span><span class="Meta">e</span><span class="Meta">N</span><span class="Meta">a</span><span class="Meta">m</span><span class="Meta">e</span>] = <span class="CharString">'</span><span class="CharString">R</span><span class="CharString">'</span> <span class="RuleName">n</span><span class="RuleName">u</span><span class="RuleName">m</span><span class="RuleName">b</span><span class="RuleName">e</span><span class="RuleName">r</span> <span class="CharString">'</span><span class="Escape">\</span><span class="Escape">n</span><span class="CharString">'</span>;
+
+<span class="RuleName">n</span><span class="RuleName">u</span><span class="RuleName">m</span><span class="RuleName">b</span><span class="RuleName">e</span><span class="RuleName">r</span> = <span class="RuleName">d</span><span class="RuleName">i</span><span class="RuleName">g</span><span class="RuleName">i</span><span class="RuleName">t</span> <span class="RuleName">d</span><span class="RuleName">i</span><span class="RuleName">g</span><span class="RuleName">i</span><span class="RuleName">t</span><span class="Reserved">*</span>;
+
+<span class="RuleName">d</span><span class="RuleName">i</span><span class="RuleName">g</span><span class="RuleName">i</span><span class="RuleName">t</span> = <span class="CharString">'</span><span class="CharString">0</span><span class="CharString">'</span>-<span class="CharString">'</span><span class="CharString">9</span><span class="CharString">'</span>;
+</pre>
+
+The meta language can describe other languages. Hence the word meta. (It is
+highly influenced by [META II](https://en.wikipedia.org/wiki/META_II).)
+
+The parsing begins at `main`. Here we say that the input is a sequence of
+`instruction` followed by the end of file. The end of file is detected by
+matching "not anything".
+
+Next we say that an `instruction` can either be `left` or `right` (checked in
+that order). They are matched by checking for the character `L`/`R` followed by
+a `number` and a newline. The `Reserved` and `RuleName` are names of highlight
+groups that should be used for the match.
+
+Then finally a `number` is one ore more `digit`. And a `digit` is any
+character in the range 0-9.
+
+Now that we have a parser for this language, we can open the input file in
+rlworkbench and it will highlight it like this:
+
+<pre class="highlight"><span class="Reserved">L</span><span class="Reserved">6</span><span class="Reserved">8</span><span class="Reserved">
+</span><span class="Reserved">L</span><span class="Reserved">3</span><span class="Reserved">0</span><span class="Reserved">
+</span><span class="RuleName">R</span><span class="RuleName">4</span><span class="RuleName">8</span><span class="RuleName">
+</span><span class="Reserved">L</span><span class="Reserved">5</span><span class="Reserved">
+</span><span class="RuleName">R</span><span class="RuleName">6</span><span class="RuleName">0</span><span class="RuleName">
+</span><span class="Reserved">L</span><span class="Reserved">5</span><span class="Reserved">5</span><span class="Reserved">
+</span><span class="Reserved">L</span><span class="Reserved">1</span><span class="Reserved">
+</span><span class="Reserved">L</span><span class="Reserved">9</span><span class="Reserved">9</span><span class="Reserved">
+</span><span class="RuleName">R</span><span class="RuleName">1</span><span class="RuleName">4</span><span class="RuleName">
+</span><span class="Reserved">L</span><span class="Reserved">8</span><span class="Reserved">2</span><span class="Reserved">
+</span></pre>
+
+Pretty cool. The highlighting can help you gain insight into the data. For
+example, you could quite quickly see the distribution of left and right turns.
+
+How can we make this run? Let's augment the parser with code generation
+instructions:
+
+<pre class="highlight"><span class="RuleName">m</span><span class="RuleName">a</span><span class="RuleName">i</span><span class="RuleName">n</span> = <span class="RuleName">i</span><span class="RuleName">n</span><span class="RuleName">s</span><span class="RuleName">t</span><span class="RuleName">r</span><span class="RuleName">u</span><span class="RuleName">c</span><span class="RuleName">t</span><span class="RuleName">i</span><span class="RuleName">o</span><span class="RuleName">n</span><span class="Reserved">*</span><span class="Reserved">:</span><span class="VariableName">x</span><span class="VariableName">s</span> <span class="Reserved">!</span><span class="Reserved">.</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> {
+    $dialSize
+    &gt;dialSize { <span class="String">&quot;</span><span class="String">1</span><span class="String">0</span><span class="String">0</span><span class="String">&quot;</span> }
+    <span class="String">&quot;</span><span class="String">#</span><span class="String">i</span><span class="String">n</span><span class="String">c</span><span class="String">l</span><span class="String">u</span><span class="String">d</span><span class="String">e</span><span class="String"> </span><span class="String">&lt;</span><span class="String">s</span><span class="String">t</span><span class="String">d</span><span class="String">i</span><span class="String">o</span><span class="String">.</span><span class="String">h</span><span class="String">&gt;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+    <span class="String">&quot;</span><span class="String">t</span><span class="String">y</span><span class="String">p</span><span class="String">e</span><span class="String">d</span><span class="String">e</span><span class="String">f</span><span class="String"> </span><span class="String">s</span><span class="String">t</span><span class="String">r</span><span class="String">u</span><span class="String">c</span><span class="String">t</span><span class="String"> </span><span class="String">{</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span> &gt;
+        <span class="String">&quot;</span><span class="String">u</span><span class="String">n</span><span class="String">s</span><span class="String">i</span><span class="String">g</span><span class="String">n</span><span class="String">e</span><span class="String">d</span><span class="String"> </span><span class="String">i</span><span class="String">n</span><span class="String">t</span><span class="String"> </span><span class="String">p</span><span class="String">o</span><span class="String">s</span><span class="String">i</span><span class="String">t</span><span class="String">i</span><span class="String">v</span><span class="String">e</span><span class="String">_</span><span class="String">o</span><span class="String">f</span><span class="String">f</span><span class="String">s</span><span class="String">e</span><span class="String">t</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+        <span class="String">&quot;</span><span class="String">u</span><span class="String">n</span><span class="String">s</span><span class="String">i</span><span class="String">g</span><span class="String">n</span><span class="String">e</span><span class="String">d</span><span class="String"> </span><span class="String">i</span><span class="String">n</span><span class="String">t</span><span class="String"> </span><span class="String">p</span><span class="String">a</span><span class="String">r</span><span class="String">t</span><span class="String">i</span><span class="String">a</span><span class="String">l</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+        <span class="String">&quot;</span><span class="String">u</span><span class="String">n</span><span class="String">s</span><span class="String">i</span><span class="String">g</span><span class="String">n</span><span class="String">e</span><span class="String">d</span><span class="String"> </span><span class="String">i</span><span class="String">n</span><span class="String">t</span><span class="String"> </span><span class="String">c</span><span class="String">o</span><span class="String">m</span><span class="String">p</span><span class="String">l</span><span class="String">e</span><span class="String">t</span><span class="String">e</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+    &lt; <span class="String">&quot;</span><span class="String">}</span><span class="String"> </span><span class="String">T</span><span class="String">u</span><span class="String">r</span><span class="String">n</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+    <span class="String">&quot;</span><span class="String">s</span><span class="String">t</span><span class="String">a</span><span class="String">t</span><span class="String">i</span><span class="String">c</span><span class="String"> </span><span class="String">T</span><span class="String">u</span><span class="String">r</span><span class="String">n</span><span class="String"> </span><span class="String">t</span><span class="String">u</span><span class="String">r</span><span class="String">n</span><span class="String">s</span><span class="String">[</span><span class="String">]</span><span class="String"> </span><span class="String">=</span><span class="String"> </span><span class="String">{</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span> &gt;
+        <span class="VariableName">x</span><span class="VariableName">s</span>
+    &lt; <span class="String">&quot;</span><span class="String">}</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+    <span class="String">&quot;</span><span class="String">s</span><span class="String">t</span><span class="String">a</span><span class="String">t</span><span class="String">i</span><span class="String">c</span><span class="String"> </span><span class="String">u</span><span class="String">n</span><span class="String">s</span><span class="String">i</span><span class="String">g</span><span class="String">n</span><span class="String">e</span><span class="String">d</span><span class="String"> </span><span class="String">i</span><span class="String">n</span><span class="String">t</span><span class="String"> </span><span class="String">n</span><span class="String">u</span><span class="String">m</span><span class="String">b</span><span class="String">e</span><span class="String">r</span><span class="String">_</span><span class="String">o</span><span class="String">f</span><span class="String">_</span><span class="String">t</span><span class="String">u</span><span class="String">r</span><span class="String">n</span><span class="String">s</span><span class="String"> </span><span class="String">=</span><span class="String"> </span><span class="String">&quot;</span> <span class="VariableName">x</span><span class="VariableName">s</span>.count <span class="String">&quot;</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+    <span class="String">&quot;</span><span class="String">i</span><span class="String">n</span><span class="String">t</span><span class="String"> </span><span class="String">m</span><span class="String">a</span><span class="String">i</span><span class="String">n</span><span class="String">(</span><span class="String">v</span><span class="String">o</span><span class="String">i</span><span class="String">d</span><span class="String">)</span><span class="String"> </span><span class="String">{</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span> &gt;
+        <span class="String">&quot;</span><span class="String">u</span><span class="String">n</span><span class="String">s</span><span class="String">i</span><span class="String">g</span><span class="String">n</span><span class="String">e</span><span class="String">d</span><span class="String"> </span><span class="String">i</span><span class="String">n</span><span class="String">t</span><span class="String"> </span><span class="String">d</span><span class="String">i</span><span class="String">a</span><span class="String">l</span><span class="String">_</span><span class="String">p</span><span class="String">o</span><span class="String">s</span><span class="String">i</span><span class="String">t</span><span class="String">i</span><span class="String">o</span><span class="String">n</span><span class="String"> </span><span class="String">=</span><span class="String"> </span><span class="String">5</span><span class="String">0</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+        <span class="String">&quot;</span><span class="String">u</span><span class="String">n</span><span class="String">s</span><span class="String">i</span><span class="String">g</span><span class="String">n</span><span class="String">e</span><span class="String">d</span><span class="String"> </span><span class="String">i</span><span class="String">n</span><span class="String">t</span><span class="String"> </span><span class="String">t</span><span class="String">i</span><span class="String">m</span><span class="String">e</span><span class="String">s</span><span class="String">_</span><span class="String">e</span><span class="String">n</span><span class="String">d</span><span class="String">e</span><span class="String">d</span><span class="String">_</span><span class="String">a</span><span class="String">t</span><span class="String">_</span><span class="String">z</span><span class="String">e</span><span class="String">r</span><span class="String">o</span><span class="String"> </span><span class="String">=</span><span class="String"> </span><span class="String">0</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+        <span class="String">&quot;</span><span class="String">u</span><span class="String">n</span><span class="String">s</span><span class="String">i</span><span class="String">g</span><span class="String">n</span><span class="String">e</span><span class="String">d</span><span class="String"> </span><span class="String">i</span><span class="String">n</span><span class="String">t</span><span class="String"> </span><span class="String">t</span><span class="String">i</span><span class="String">m</span><span class="String">e</span><span class="String">s</span><span class="String">_</span><span class="String">a</span><span class="String">t</span><span class="String">_</span><span class="String">z</span><span class="String">e</span><span class="String">r</span><span class="String">o</span><span class="String"> </span><span class="String">=</span><span class="String"> </span><span class="String">0</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+        <span class="String">&quot;</span><span class="String">u</span><span class="String">n</span><span class="String">s</span><span class="String">i</span><span class="String">g</span><span class="String">n</span><span class="String">e</span><span class="String">d</span><span class="String"> </span><span class="String">i</span><span class="String">n</span><span class="String">t</span><span class="String"> </span><span class="String">t</span><span class="String">u</span><span class="String">r</span><span class="String">n</span><span class="String">_</span><span class="String">i</span><span class="String">n</span><span class="String">d</span><span class="String">e</span><span class="String">x</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+        <span class="String">&quot;</span><span class="String">u</span><span class="String">n</span><span class="String">s</span><span class="String">i</span><span class="String">g</span><span class="String">n</span><span class="String">e</span><span class="String">d</span><span class="String"> </span><span class="String">i</span><span class="String">n</span><span class="String">t</span><span class="String"> </span><span class="String">p</span><span class="String">a</span><span class="String">r</span><span class="String">t</span><span class="String">i</span><span class="String">a</span><span class="String">l</span><span class="String">_</span><span class="String">c</span><span class="String">o</span><span class="String">u</span><span class="String">n</span><span class="String">t</span><span class="String">e</span><span class="String">r</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+        <span class="String">&quot;</span><span class="String">f</span><span class="String">o</span><span class="String">r</span><span class="String">(</span><span class="String">t</span><span class="String">u</span><span class="String">r</span><span class="String">n</span><span class="String">_</span><span class="String">i</span><span class="String">n</span><span class="String">d</span><span class="String">e</span><span class="String">x</span><span class="String">=</span><span class="String">0</span><span class="String">;</span><span class="String"> </span><span class="String">t</span><span class="String">u</span><span class="String">r</span><span class="String">n</span><span class="String">_</span><span class="String">i</span><span class="String">n</span><span class="String">d</span><span class="String">e</span><span class="String">x</span><span class="String">&lt;</span><span class="String">n</span><span class="String">u</span><span class="String">m</span><span class="String">b</span><span class="String">e</span><span class="String">r</span><span class="String">_</span><span class="String">o</span><span class="String">f</span><span class="String">_</span><span class="String">t</span><span class="String">u</span><span class="String">r</span><span class="String">n</span><span class="String">s</span><span class="String">;</span><span class="String"> </span><span class="String">t</span><span class="String">u</span><span class="String">r</span><span class="String">n</span><span class="String">_</span><span class="String">i</span><span class="String">n</span><span class="String">d</span><span class="String">e</span><span class="String">x</span><span class="String">+</span><span class="String">+</span><span class="String">)</span><span class="String"> </span><span class="String">{</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span> &gt;
+            <span class="String">&quot;</span><span class="String">f</span><span class="String">o</span><span class="String">r</span><span class="String">(</span><span class="String">p</span><span class="String">a</span><span class="String">r</span><span class="String">t</span><span class="String">i</span><span class="String">a</span><span class="String">l</span><span class="String">_</span><span class="String">c</span><span class="String">o</span><span class="String">u</span><span class="String">n</span><span class="String">t</span><span class="String">e</span><span class="String">r</span><span class="String">=</span><span class="String">0</span><span class="String">;</span><span class="String"> </span><span class="String">p</span><span class="String">a</span><span class="String">r</span><span class="String">t</span><span class="String">i</span><span class="String">a</span><span class="String">l</span><span class="String">_</span><span class="String">c</span><span class="String">o</span><span class="String">u</span><span class="String">n</span><span class="String">t</span><span class="String">e</span><span class="String">r</span><span class="String">&lt;</span><span class="String">t</span><span class="String">u</span><span class="String">r</span><span class="String">n</span><span class="String">s</span><span class="String">[</span><span class="String">t</span><span class="String">u</span><span class="String">r</span><span class="String">n</span><span class="String">_</span><span class="String">i</span><span class="String">n</span><span class="String">d</span><span class="String">e</span><span class="String">x</span><span class="String">]</span><span class="String">.</span><span class="String">p</span><span class="String">a</span><span class="String">r</span><span class="String">t</span><span class="String">i</span><span class="String">a</span><span class="String">l</span><span class="String">;</span><span class="String"> </span><span class="String">p</span><span class="String">a</span><span class="String">r</span><span class="String">t</span><span class="String">i</span><span class="String">a</span><span class="String">l</span><span class="String">_</span><span class="String">c</span><span class="String">o</span><span class="String">u</span><span class="String">n</span><span class="String">t</span><span class="String">e</span><span class="String">r</span><span class="String">+</span><span class="String">+</span><span class="String">)</span><span class="String"> </span><span class="String">{</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span> &gt;
+                <span class="String">&quot;</span><span class="String">d</span><span class="String">i</span><span class="String">a</span><span class="String">l</span><span class="String">_</span><span class="String">p</span><span class="String">o</span><span class="String">s</span><span class="String">i</span><span class="String">t</span><span class="String">i</span><span class="String">o</span><span class="String">n</span><span class="String"> </span><span class="String">+</span><span class="String">=</span><span class="String"> </span><span class="String">t</span><span class="String">u</span><span class="String">r</span><span class="String">n</span><span class="String">s</span><span class="String">[</span><span class="String">t</span><span class="String">u</span><span class="String">r</span><span class="String">n</span><span class="String">_</span><span class="String">i</span><span class="String">n</span><span class="String">d</span><span class="String">e</span><span class="String">x</span><span class="String">]</span><span class="String">.</span><span class="String">p</span><span class="String">o</span><span class="String">s</span><span class="String">i</span><span class="String">t</span><span class="String">i</span><span class="String">v</span><span class="String">e</span><span class="String">_</span><span class="String">o</span><span class="String">f</span><span class="String">f</span><span class="String">s</span><span class="String">e</span><span class="String">t</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+                <span class="String">&quot;</span><span class="String">d</span><span class="String">i</span><span class="String">a</span><span class="String">l</span><span class="String">_</span><span class="String">p</span><span class="String">o</span><span class="String">s</span><span class="String">i</span><span class="String">t</span><span class="String">i</span><span class="String">o</span><span class="String">n</span><span class="String"> </span><span class="String">%</span><span class="String">=</span><span class="String"> </span><span class="String">&quot;</span> &lt;dialSize <span class="String">&quot;</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+                <span class="String">&quot;</span><span class="String">i</span><span class="String">f</span><span class="String"> </span><span class="String">(</span><span class="String">d</span><span class="String">i</span><span class="String">a</span><span class="String">l</span><span class="String">_</span><span class="String">p</span><span class="String">o</span><span class="String">s</span><span class="String">i</span><span class="String">t</span><span class="String">i</span><span class="String">o</span><span class="String">n</span><span class="String"> </span><span class="String">=</span><span class="String">=</span><span class="String"> </span><span class="String">0</span><span class="String">)</span><span class="String"> </span><span class="String">{</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span> &gt;
+                    <span class="String">&quot;</span><span class="String">t</span><span class="String">i</span><span class="String">m</span><span class="String">e</span><span class="String">s</span><span class="String">_</span><span class="String">a</span><span class="String">t</span><span class="String">_</span><span class="String">z</span><span class="String">e</span><span class="String">r</span><span class="String">o</span><span class="String"> </span><span class="String">+</span><span class="String">=</span><span class="String"> </span><span class="String">1</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+                &lt; <span class="String">&quot;</span><span class="String">}</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+            &lt; <span class="String">&quot;</span><span class="String">}</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+            <span class="String">&quot;</span><span class="String">i</span><span class="String">f</span><span class="String"> </span><span class="String">(</span><span class="String">d</span><span class="String">i</span><span class="String">a</span><span class="String">l</span><span class="String">_</span><span class="String">p</span><span class="String">o</span><span class="String">s</span><span class="String">i</span><span class="String">t</span><span class="String">i</span><span class="String">o</span><span class="String">n</span><span class="String"> </span><span class="String">=</span><span class="String">=</span><span class="String"> </span><span class="String">0</span><span class="String">)</span><span class="String"> </span><span class="String">{</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span> &gt;
+                <span class="String">&quot;</span><span class="String">t</span><span class="String">i</span><span class="String">m</span><span class="String">e</span><span class="String">s</span><span class="String">_</span><span class="String">e</span><span class="String">n</span><span class="String">d</span><span class="String">e</span><span class="String">d</span><span class="String">_</span><span class="String">a</span><span class="String">t</span><span class="String">_</span><span class="String">z</span><span class="String">e</span><span class="String">r</span><span class="String">o</span><span class="String"> </span><span class="String">+</span><span class="String">=</span><span class="String"> </span><span class="String">1</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+            &lt; <span class="String">&quot;</span><span class="String">}</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+            <span class="String">&quot;</span><span class="String">t</span><span class="String">i</span><span class="String">m</span><span class="String">e</span><span class="String">s</span><span class="String">_</span><span class="String">a</span><span class="String">t</span><span class="String">_</span><span class="String">z</span><span class="String">e</span><span class="String">r</span><span class="String">o</span><span class="String"> </span><span class="String">+</span><span class="String">=</span><span class="String"> </span><span class="String">t</span><span class="String">u</span><span class="String">r</span><span class="String">n</span><span class="String">s</span><span class="String">[</span><span class="String">t</span><span class="String">u</span><span class="String">r</span><span class="String">n</span><span class="String">_</span><span class="String">i</span><span class="String">n</span><span class="String">d</span><span class="String">e</span><span class="String">x</span><span class="String">]</span><span class="String">.</span><span class="String">c</span><span class="String">o</span><span class="String">m</span><span class="String">p</span><span class="String">l</span><span class="String">e</span><span class="String">t</span><span class="String">e</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+        &lt; <span class="String">&quot;</span><span class="String">}</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+        <span class="String">&quot;</span><span class="String">p</span><span class="String">r</span><span class="String">i</span><span class="String">n</span><span class="String">t</span><span class="String">f</span><span class="String">(</span><span class="Escape">\</span><span class="Escape">&quot;</span><span class="String">P</span><span class="String">a</span><span class="String">r</span><span class="String">t</span><span class="String"> </span><span class="String">1</span><span class="String">:</span><span class="String"> </span><span class="String">%</span><span class="String">d</span><span class="Escape">\</span><span class="Escape">\</span><span class="String">n</span><span class="Escape">\</span><span class="Escape">&quot;</span><span class="String">,</span><span class="String"> </span><span class="String">t</span><span class="String">i</span><span class="String">m</span><span class="String">e</span><span class="String">s</span><span class="String">_</span><span class="String">e</span><span class="String">n</span><span class="String">d</span><span class="String">e</span><span class="String">d</span><span class="String">_</span><span class="String">a</span><span class="String">t</span><span class="String">_</span><span class="String">z</span><span class="String">e</span><span class="String">r</span><span class="String">o</span><span class="String">)</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+        <span class="String">&quot;</span><span class="String">p</span><span class="String">r</span><span class="String">i</span><span class="String">n</span><span class="String">t</span><span class="String">f</span><span class="String">(</span><span class="Escape">\</span><span class="Escape">&quot;</span><span class="String">P</span><span class="String">a</span><span class="String">r</span><span class="String">t</span><span class="String"> </span><span class="String">2</span><span class="String">:</span><span class="String"> </span><span class="String">%</span><span class="String">d</span><span class="Escape">\</span><span class="Escape">\</span><span class="String">n</span><span class="Escape">\</span><span class="Escape">&quot;</span><span class="String">,</span><span class="String"> </span><span class="String">t</span><span class="String">i</span><span class="String">m</span><span class="String">e</span><span class="String">s</span><span class="String">_</span><span class="String">a</span><span class="String">t</span><span class="String">_</span><span class="String">z</span><span class="String">e</span><span class="String">r</span><span class="String">o</span><span class="String">)</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+        <span class="String">&quot;</span><span class="String">r</span><span class="String">e</span><span class="String">t</span><span class="String">u</span><span class="String">r</span><span class="String">n</span><span class="String"> </span><span class="String">0</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+    &lt; <span class="String">&quot;</span><span class="String">}</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+};
+
+<span class="RuleName">i</span><span class="RuleName">n</span><span class="RuleName">s</span><span class="RuleName">t</span><span class="RuleName">r</span><span class="RuleName">u</span><span class="RuleName">c</span><span class="RuleName">t</span><span class="RuleName">i</span><span class="RuleName">o</span><span class="RuleName">n</span> =
+    <span class="Reserved">|</span> <span class="RuleName">l</span><span class="RuleName">e</span><span class="RuleName">f</span><span class="RuleName">t</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> }
+    <span class="Reserved">|</span> <span class="RuleName">r</span><span class="RuleName">i</span><span class="RuleName">g</span><span class="RuleName">h</span><span class="RuleName">t</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> }
+    ;
+
+<span class="RuleName">l</span><span class="RuleName">e</span><span class="RuleName">f</span><span class="RuleName">t</span>[<span class="Meta">R</span><span class="Meta">e</span><span class="Meta">s</span><span class="Meta">e</span><span class="Meta">r</span><span class="Meta">v</span><span class="Meta">e</span><span class="Meta">d</span>] = <span class="CharString">'</span><span class="CharString">L</span><span class="CharString">'</span> <span class="RuleName">n</span><span class="RuleName">u</span><span class="RuleName">m</span><span class="RuleName">b</span><span class="RuleName">e</span><span class="RuleName">r</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="CharString">'</span><span class="Escape">\</span><span class="Escape">n</span><span class="CharString">'</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> {
+    <span class="String">&quot;</span><span class="String">{</span><span class="String">&quot;</span> &lt;dialSize <span class="String">&quot;</span><span class="String">-</span><span class="String">1</span><span class="String">,</span><span class="String"> </span><span class="String">&quot;</span> <span class="VariableName">x</span> <span class="String">&quot;</span><span class="String">%</span><span class="String">&quot;</span> &lt;dialSize <span class="String">&quot;</span><span class="String">,</span><span class="String"> </span><span class="String">&quot;</span> <span class="VariableName">x</span> <span class="String">&quot;</span><span class="String">/</span><span class="String">&quot;</span> &lt;dialSize <span class="String">&quot;</span><span class="String">}</span><span class="String">,</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+};
+
+<span class="RuleName">r</span><span class="RuleName">i</span><span class="RuleName">g</span><span class="RuleName">h</span><span class="RuleName">t</span>[<span class="Meta">R</span><span class="Meta">u</span><span class="Meta">l</span><span class="Meta">e</span><span class="Meta">N</span><span class="Meta">a</span><span class="Meta">m</span><span class="Meta">e</span>] = <span class="CharString">'</span><span class="CharString">R</span><span class="CharString">'</span> <span class="RuleName">n</span><span class="RuleName">u</span><span class="RuleName">m</span><span class="RuleName">b</span><span class="RuleName">e</span><span class="RuleName">r</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="CharString">'</span><span class="Escape">\</span><span class="Escape">n</span><span class="CharString">'</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> {
+    <span class="String">&quot;</span><span class="String">{</span><span class="String">1</span><span class="String">,</span><span class="String"> </span><span class="String">&quot;</span> <span class="VariableName">x</span> <span class="String">&quot;</span><span class="String">%</span><span class="String">&quot;</span> &lt;dialSize <span class="String">&quot;</span><span class="String">,</span><span class="String"> </span><span class="String">&quot;</span> <span class="VariableName">x</span> <span class="String">&quot;</span><span class="String">/</span><span class="String">&quot;</span> &lt;dialSize <span class="String">&quot;</span><span class="String">}</span><span class="String">,</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+};
+
+<span class="RuleName">n</span><span class="RuleName">u</span><span class="RuleName">m</span><span class="RuleName">b</span><span class="RuleName">e</span><span class="RuleName">r</span> = <span class="RuleName">d</span><span class="RuleName">i</span><span class="RuleName">g</span><span class="RuleName">i</span><span class="RuleName">t</span> <span class="RuleName">d</span><span class="RuleName">i</span><span class="RuleName">g</span><span class="RuleName">i</span><span class="RuleName">t</span><span class="Reserved">*</span>;
+
+<span class="RuleName">d</span><span class="RuleName">i</span><span class="RuleName">g</span><span class="RuleName">i</span><span class="RuleName">t</span> = <span class="CharString">'</span><span class="CharString">0</span><span class="CharString">'</span>-<span class="CharString">'</span><span class="CharString">9</span><span class="CharString">'</span>;
+</pre>
+
+In the meta language, we can add semantic actions to rules with the ` -> { ...
+}` syntax. It specifies what should be generated when this rule is matched. We
+can bind sub matches to variables using the `<expression>:<name>` syntax.
+
+When we generate code for the example, we get this C program:
+
+<pre class="highlight"><span class="CharString">#</span><span class="CharString">i</span><span class="CharString">n</span><span class="CharString">c</span><span class="CharString">l</span><span class="CharString">u</span><span class="CharString">d</span><span class="CharString">e</span><span class="CharString"> </span><span class="CharString">&lt;</span><span class="CharString">s</span><span class="CharString">t</span><span class="CharString">d</span><span class="CharString">i</span><span class="CharString">o</span><span class="CharString">.</span><span class="CharString">h</span><span class="CharString">&gt;</span><span class="CharString">
+</span><span class="VariableName">t</span><span class="VariableName">y</span><span class="VariableName">p</span><span class="VariableName">e</span><span class="VariableName">d</span><span class="VariableName">e</span><span class="VariableName">f</span> <span class="VariableName">s</span><span class="VariableName">t</span><span class="VariableName">r</span><span class="VariableName">u</span><span class="VariableName">c</span><span class="VariableName">t</span> {
+    <span class="VariableName">u</span><span class="VariableName">n</span><span class="VariableName">s</span><span class="VariableName">i</span><span class="VariableName">g</span><span class="VariableName">n</span><span class="VariableName">e</span><span class="VariableName">d</span> <span class="VariableName">i</span><span class="VariableName">n</span><span class="VariableName">t</span> positive_offset;
+    <span class="VariableName">u</span><span class="VariableName">n</span><span class="VariableName">s</span><span class="VariableName">i</span><span class="VariableName">g</span><span class="VariableName">n</span><span class="VariableName">e</span><span class="VariableName">d</span> <span class="VariableName">i</span><span class="VariableName">n</span><span class="VariableName">t</span> partial;
+    <span class="VariableName">u</span><span class="VariableName">n</span><span class="VariableName">s</span><span class="VariableName">i</span><span class="VariableName">g</span><span class="VariableName">n</span><span class="VariableName">e</span><span class="VariableName">d</span> <span class="VariableName">i</span><span class="VariableName">n</span><span class="VariableName">t</span> complete;
+} Turn;
+<span class="VariableName">s</span><span class="VariableName">t</span><span class="VariableName">a</span><span class="VariableName">t</span><span class="VariableName">i</span><span class="VariableName">c</span> Turn turns[] = {
+    {<span class="String">1</span><span class="String">0</span><span class="String">0</span>-<span class="String">1</span>, <span class="String">6</span><span class="String">8</span>%<span class="String">1</span><span class="String">0</span><span class="String">0</span>, <span class="String">6</span><span class="String">8</span>/<span class="String">1</span><span class="String">0</span><span class="String">0</span>},
+    {<span class="String">1</span><span class="String">0</span><span class="String">0</span>-<span class="String">1</span>, <span class="String">3</span><span class="String">0</span>%<span class="String">1</span><span class="String">0</span><span class="String">0</span>, <span class="String">3</span><span class="String">0</span>/<span class="String">1</span><span class="String">0</span><span class="String">0</span>},
+    {<span class="String">1</span>, <span class="String">4</span><span class="String">8</span>%<span class="String">1</span><span class="String">0</span><span class="String">0</span>, <span class="String">4</span><span class="String">8</span>/<span class="String">1</span><span class="String">0</span><span class="String">0</span>},
+    {<span class="String">1</span><span class="String">0</span><span class="String">0</span>-<span class="String">1</span>, <span class="String">5</span>%<span class="String">1</span><span class="String">0</span><span class="String">0</span>, <span class="String">5</span>/<span class="String">1</span><span class="String">0</span><span class="String">0</span>},
+    {<span class="String">1</span>, <span class="String">6</span><span class="String">0</span>%<span class="String">1</span><span class="String">0</span><span class="String">0</span>, <span class="String">6</span><span class="String">0</span>/<span class="String">1</span><span class="String">0</span><span class="String">0</span>},
+    {<span class="String">1</span><span class="String">0</span><span class="String">0</span>-<span class="String">1</span>, <span class="String">5</span><span class="String">5</span>%<span class="String">1</span><span class="String">0</span><span class="String">0</span>, <span class="String">5</span><span class="String">5</span>/<span class="String">1</span><span class="String">0</span><span class="String">0</span>},
+    {<span class="String">1</span><span class="String">0</span><span class="String">0</span>-<span class="String">1</span>, <span class="String">1</span>%<span class="String">1</span><span class="String">0</span><span class="String">0</span>, <span class="String">1</span>/<span class="String">1</span><span class="String">0</span><span class="String">0</span>},
+    {<span class="String">1</span><span class="String">0</span><span class="String">0</span>-<span class="String">1</span>, <span class="String">9</span><span class="String">9</span>%<span class="String">1</span><span class="String">0</span><span class="String">0</span>, <span class="String">9</span><span class="String">9</span>/<span class="String">1</span><span class="String">0</span><span class="String">0</span>},
+    {<span class="String">1</span>, <span class="String">1</span><span class="String">4</span>%<span class="String">1</span><span class="String">0</span><span class="String">0</span>, <span class="String">1</span><span class="String">4</span>/<span class="String">1</span><span class="String">0</span><span class="String">0</span>},
+    {<span class="String">1</span><span class="String">0</span><span class="String">0</span>-<span class="String">1</span>, <span class="String">8</span><span class="String">2</span>%<span class="String">1</span><span class="String">0</span><span class="String">0</span>, <span class="String">8</span><span class="String">2</span>/<span class="String">1</span><span class="String">0</span><span class="String">0</span>},
+};
+<span class="VariableName">s</span><span class="VariableName">t</span><span class="VariableName">a</span><span class="VariableName">t</span><span class="VariableName">i</span><span class="VariableName">c</span> <span class="VariableName">u</span><span class="VariableName">n</span><span class="VariableName">s</span><span class="VariableName">i</span><span class="VariableName">g</span><span class="VariableName">n</span><span class="VariableName">e</span><span class="VariableName">d</span> <span class="VariableName">i</span><span class="VariableName">n</span><span class="VariableName">t</span> number_of_turns = <span class="String">1</span><span class="String">0</span>;
+<span class="VariableName">i</span><span class="VariableName">n</span><span class="VariableName">t</span> main(<span class="VariableName">v</span><span class="VariableName">o</span><span class="VariableName">i</span><span class="VariableName">d</span>) {
+    <span class="VariableName">u</span><span class="VariableName">n</span><span class="VariableName">s</span><span class="VariableName">i</span><span class="VariableName">g</span><span class="VariableName">n</span><span class="VariableName">e</span><span class="VariableName">d</span> <span class="VariableName">i</span><span class="VariableName">n</span><span class="VariableName">t</span> dial_position = <span class="String">5</span><span class="String">0</span>;
+    <span class="VariableName">u</span><span class="VariableName">n</span><span class="VariableName">s</span><span class="VariableName">i</span><span class="VariableName">g</span><span class="VariableName">n</span><span class="VariableName">e</span><span class="VariableName">d</span> <span class="VariableName">i</span><span class="VariableName">n</span><span class="VariableName">t</span> times_ended_at_zero = <span class="String">0</span>;
+    <span class="VariableName">u</span><span class="VariableName">n</span><span class="VariableName">s</span><span class="VariableName">i</span><span class="VariableName">g</span><span class="VariableName">n</span><span class="VariableName">e</span><span class="VariableName">d</span> <span class="VariableName">i</span><span class="VariableName">n</span><span class="VariableName">t</span> times_at_zero = <span class="String">0</span>;
+    <span class="VariableName">u</span><span class="VariableName">n</span><span class="VariableName">s</span><span class="VariableName">i</span><span class="VariableName">g</span><span class="VariableName">n</span><span class="VariableName">e</span><span class="VariableName">d</span> <span class="VariableName">i</span><span class="VariableName">n</span><span class="VariableName">t</span> turn_index;
+    <span class="VariableName">u</span><span class="VariableName">n</span><span class="VariableName">s</span><span class="VariableName">i</span><span class="VariableName">g</span><span class="VariableName">n</span><span class="VariableName">e</span><span class="VariableName">d</span> <span class="VariableName">i</span><span class="VariableName">n</span><span class="VariableName">t</span> partial_counter;
+    <span class="Reserved">f</span><span class="Reserved">o</span><span class="Reserved">r</span>(turn_index=<span class="String">0</span>; turn_index&lt;number_of_turns; turn_index++) {
+        <span class="Reserved">f</span><span class="Reserved">o</span><span class="Reserved">r</span>(partial_counter=<span class="String">0</span>; partial_counter&lt;turns[turn_index].partial; partial_counter++) {
+            dial_position += turns[turn_index].positive_offset;
+            dial_position %= <span class="String">1</span><span class="String">0</span><span class="String">0</span>;
+            <span class="Reserved">i</span><span class="Reserved">f</span> (dial_position == <span class="String">0</span>) {
+                times_at_zero += <span class="String">1</span>;
+            }
+        }
+        <span class="Reserved">i</span><span class="Reserved">f</span> (dial_position == <span class="String">0</span>) {
+            times_ended_at_zero += <span class="String">1</span>;
+        }
+        times_at_zero += turns[turn_index].complete;
+    }
+    printf(<span class="String">&quot;</span><span class="String">P</span><span class="String">a</span><span class="String">r</span><span class="String">t</span><span class="String"> </span><span class="String">1</span><span class="String">:</span><span class="String"> </span><span class="String">%</span><span class="String">d</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>, times_ended_at_zero);
+    printf(<span class="String">&quot;</span><span class="String">P</span><span class="String">a</span><span class="String">r</span><span class="String">t</span><span class="String"> </span><span class="String">2</span><span class="String">:</span><span class="String"> </span><span class="String">%</span><span class="String">d</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>, times_at_zero);
+    <span class="Reserved">r</span><span class="Reserved">e</span><span class="Reserved">t</span><span class="Reserved">u</span><span class="Reserved">r</span><span class="Reserved">n</span> <span class="String">0</span>;
+}
+</pre>
+
+So the majority of the code generation is outputting static C code. The most
+"dynamic" part is this:
+
+<pre class="highlight"><span class="VariableName">s</span><span class="VariableName">t</span><span class="VariableName">a</span><span class="VariableName">t</span><span class="VariableName">i</span><span class="VariableName">c</span> Turn turns[] = {
+    {<span class="String">1</span><span class="String">0</span><span class="String">0</span>-<span class="String">1</span>, <span class="String">6</span><span class="String">8</span>%<span class="String">1</span><span class="String">0</span><span class="String">0</span>, <span class="String">6</span><span class="String">8</span>/<span class="String">1</span><span class="String">0</span><span class="String">0</span>},
+    {<span class="String">1</span><span class="String">0</span><span class="String">0</span>-<span class="String">1</span>, <span class="String">3</span><span class="String">0</span>%<span class="String">1</span><span class="String">0</span><span class="String">0</span>, <span class="String">3</span><span class="String">0</span>/<span class="String">1</span><span class="String">0</span><span class="String">0</span>},
+    {<span class="String">1</span>, <span class="String">4</span><span class="String">8</span>%<span class="String">1</span><span class="String">0</span><span class="String">0</span>, <span class="String">4</span><span class="String">8</span>/<span class="String">1</span><span class="String">0</span><span class="String">0</span>},
+    {<span class="String">1</span><span class="String">0</span><span class="String">0</span>-<span class="String">1</span>, <span class="String">5</span>%<span class="String">1</span><span class="String">0</span><span class="String">0</span>, <span class="String">5</span>/<span class="String">1</span><span class="String">0</span><span class="String">0</span>},
+    {<span class="String">1</span>, <span class="String">6</span><span class="String">0</span>%<span class="String">1</span><span class="String">0</span><span class="String">0</span>, <span class="String">6</span><span class="String">0</span>/<span class="String">1</span><span class="String">0</span><span class="String">0</span>},
+    {<span class="String">1</span><span class="String">0</span><span class="String">0</span>-<span class="String">1</span>, <span class="String">5</span><span class="String">5</span>%<span class="String">1</span><span class="String">0</span><span class="String">0</span>, <span class="String">5</span><span class="String">5</span>/<span class="String">1</span><span class="String">0</span><span class="String">0</span>},
+    {<span class="String">1</span><span class="String">0</span><span class="String">0</span>-<span class="String">1</span>, <span class="String">1</span>%<span class="String">1</span><span class="String">0</span><span class="String">0</span>, <span class="String">1</span>/<span class="String">1</span><span class="String">0</span><span class="String">0</span>},
+    {<span class="String">1</span><span class="String">0</span><span class="String">0</span>-<span class="String">1</span>, <span class="String">9</span><span class="String">9</span>%<span class="String">1</span><span class="String">0</span><span class="String">0</span>, <span class="String">9</span><span class="String">9</span>/<span class="String">1</span><span class="String">0</span><span class="String">0</span>},
+    {<span class="String">1</span>, <span class="String">1</span><span class="String">4</span>%<span class="String">1</span><span class="String">0</span><span class="String">0</span>, <span class="String">1</span><span class="String">4</span>/<span class="String">1</span><span class="String">0</span><span class="String">0</span>},
+    {<span class="String">1</span><span class="String">0</span><span class="String">0</span>-<span class="String">1</span>, <span class="String">8</span><span class="String">2</span>%<span class="String">1</span><span class="String">0</span><span class="String">0</span>, <span class="String">8</span><span class="String">2</span>/<span class="String">1</span><span class="String">0</span><span class="String">0</span>},
+};
+<span class="VariableName">s</span><span class="VariableName">t</span><span class="VariableName">a</span><span class="VariableName">t</span><span class="VariableName">i</span><span class="VariableName">c</span> <span class="VariableName">u</span><span class="VariableName">n</span><span class="VariableName">s</span><span class="VariableName">i</span><span class="VariableName">g</span><span class="VariableName">n</span><span class="VariableName">e</span><span class="VariableName">d</span> <span class="VariableName">i</span><span class="VariableName">n</span><span class="VariableName">t</span> number_of_turns = <span class="String">1</span><span class="String">0</span>;
+</pre>
+
+The code generator transforms the input into a data structure in C that is easy
+to work with.  We could have generated just this part and then written the rest
+of the C code outside the meta language. It wouldn't exactly work in this case
+because the `dialSize` is used as a variable in the meta language. But we could
+have generated a constant in C with this value. But for the purposes of this
+year's Advent of Code puzzles, I chose to write all C code in the meta
+language. The meta language is implemented in itself and it generates more
+complicated C code than this example. So writing C code in the meta language
+code generation part is an actual use case and if it's not easy to do, we
+should make it easier.  After all, we are in complete control of how the meta
+language works.
+
+I actually struggled to solve day 1. Not because of the new approach with meta
+and not because of C which is a new language for me. The main struggle I had
+was that I didn't want to do the inner loop at first. I thought it would be too
+wasteful. And then I couldn't get all arithmetic right. I actually looked up
+other solutions for part 2. Then I decided to just implement the inner loop and
+it worked fine.
+
+From today's puzzle, I also learned that the `%` operator works differently in
+C and Python.
+
+In C:
+
+     7 % 5 => 2
+    -7 % 5 => -2
+
+In Python:
+
+     7 % 5 => 2
+    -7 % 5 => 3
+
+Furthermore I learned that the behavior in C89 could differ between
+implementations if negative operators are used. That's why I wanted to use
+unsigned numbers in my implementation. Because those I could reason about.
+
+## Day 2
+
+I got to practice string manipulation code in C. Like this for example. Nice!
+
+<pre class="highlight"><span class="VariableName">i</span><span class="VariableName">n</span><span class="VariableName">t</span> eq(<span class="VariableName">c</span><span class="VariableName">h</span><span class="VariableName">a</span><span class="VariableName">r</span>* one, <span class="VariableName">c</span><span class="VariableName">h</span><span class="VariableName">a</span><span class="VariableName">r</span>* two, size_t len) {
+    <span class="Reserved">w</span><span class="Reserved">h</span><span class="Reserved">i</span><span class="Reserved">l</span><span class="Reserved">e</span> (len &gt; <span class="String">0</span>) {
+        <span class="Reserved">i</span><span class="Reserved">f</span> (*one != *two) {
+            <span class="Reserved">r</span><span class="Reserved">e</span><span class="Reserved">t</span><span class="Reserved">u</span><span class="Reserved">r</span><span class="Reserved">n</span> <span class="String">0</span>;
+        };
+        one++;
+        two++;
+        len--;
+    }
+    <span class="Reserved">r</span><span class="Reserved">e</span><span class="Reserved">t</span><span class="Reserved">u</span><span class="Reserved">r</span><span class="Reserved">n</span> <span class="String">1</span>;
+}
+</pre>
+
+## Day 3
+
+This was probably one of the more fun days for me because I was able to solve
+the puzzle almost entirely in the meta language. Here is the solution for part
+1:
+
+<pre class="highlight"><span class="RuleName">m</span><span class="RuleName">a</span><span class="RuleName">i</span><span class="RuleName">n</span> = <span class="RuleName">b</span><span class="RuleName">a</span><span class="RuleName">n</span><span class="RuleName">k</span><span class="RuleName">2</span><span class="Reserved">*</span><span class="Reserved">:</span><span class="VariableName">x</span><span class="VariableName">s</span> <span class="Reserved">!</span><span class="Reserved">.</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> {
+    <span class="String">&quot;</span><span class="String">#</span><span class="String">i</span><span class="String">n</span><span class="String">c</span><span class="String">l</span><span class="String">u</span><span class="String">d</span><span class="String">e</span><span class="String"> </span><span class="String">&lt;</span><span class="String">s</span><span class="String">t</span><span class="String">d</span><span class="String">i</span><span class="String">o</span><span class="String">.</span><span class="String">h</span><span class="String">&gt;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+    <span class="String">&quot;</span><span class="String">i</span><span class="String">n</span><span class="String">t</span><span class="String"> </span><span class="String">m</span><span class="String">a</span><span class="String">i</span><span class="String">n</span><span class="String">(</span><span class="String">v</span><span class="String">o</span><span class="String">i</span><span class="String">d</span><span class="String">)</span><span class="String"> </span><span class="String">{</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span> &gt;
+        <span class="String">&quot;</span><span class="String">p</span><span class="String">r</span><span class="String">i</span><span class="String">n</span><span class="String">t</span><span class="String">f</span><span class="String">(</span><span class="Escape">\</span><span class="Escape">&quot;</span><span class="String">P</span><span class="String">a</span><span class="String">r</span><span class="String">t</span><span class="String"> </span><span class="String">1</span><span class="String">:</span><span class="String"> </span><span class="String">%</span><span class="String">l</span><span class="String">d</span><span class="Escape">\</span><span class="Escape">\</span><span class="String">n</span><span class="Escape">\</span><span class="Escape">&quot;</span><span class="String">,</span><span class="String"> </span><span class="String">(</span><span class="String">l</span><span class="String">o</span><span class="String">n</span><span class="String">g</span><span class="String"> </span><span class="String">i</span><span class="String">n</span><span class="String">t</span><span class="String">)</span><span class="String">(</span><span class="String">0</span><span class="String">&quot;</span> <span class="VariableName">x</span><span class="VariableName">s</span> <span class="String">&quot;</span><span class="String">)</span><span class="String">)</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+        <span class="String">&quot;</span><span class="String">r</span><span class="String">e</span><span class="String">t</span><span class="String">u</span><span class="String">r</span><span class="String">n</span><span class="String"> </span><span class="String">0</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+    &lt; <span class="String">&quot;</span><span class="String">}</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+};
+
+<span class="RuleName">b</span><span class="RuleName">a</span><span class="RuleName">n</span><span class="RuleName">k</span><span class="RuleName">2</span> = <span class="RuleName">j</span><span class="RuleName">o</span><span class="RuleName">l</span><span class="RuleName">t</span><span class="RuleName">a</span><span class="RuleName">g</span><span class="RuleName">e</span><span class="RuleName">2</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="RuleName">n</span><span class="RuleName">u</span><span class="RuleName">m</span><span class="RuleName">b</span><span class="RuleName">e</span><span class="RuleName">r</span><span class="Reserved">*</span> <span class="CharString">'</span><span class="Escape">\</span><span class="Escape">n</span><span class="CharString">'</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="String">&quot;</span><span class="String"> </span><span class="String">+</span><span class="String"> </span><span class="String">&quot;</span> <span class="VariableName">x</span> };
+
+<span class="RuleName">j</span><span class="RuleName">o</span><span class="RuleName">l</span><span class="RuleName">t</span><span class="RuleName">a</span><span class="RuleName">g</span><span class="RuleName">e</span><span class="RuleName">2</span> =
+    <span class="Reserved">|</span> <span class="RuleName">n</span><span class="RuleName">i</span><span class="RuleName">n</span><span class="RuleName">e</span><span class="Reserved">:</span><span class="VariableName">x</span>  <span class="RuleName">j</span><span class="RuleName">o</span><span class="RuleName">l</span><span class="RuleName">t</span><span class="RuleName">a</span><span class="RuleName">g</span><span class="RuleName">e</span><span class="RuleName">1</span><span class="Reserved">:</span><span class="VariableName">y</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> <span class="VariableName">y</span> }
+    <span class="Reserved">|</span> <span class="RuleName">e</span><span class="RuleName">i</span><span class="RuleName">g</span><span class="RuleName">h</span><span class="RuleName">t</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="RuleName">j</span><span class="RuleName">o</span><span class="RuleName">l</span><span class="RuleName">t</span><span class="RuleName">a</span><span class="RuleName">g</span><span class="RuleName">e</span><span class="RuleName">1</span><span class="Reserved">:</span><span class="VariableName">y</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> <span class="VariableName">y</span> }
+    <span class="Reserved">|</span> <span class="RuleName">s</span><span class="RuleName">e</span><span class="RuleName">v</span><span class="RuleName">e</span><span class="RuleName">n</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="RuleName">j</span><span class="RuleName">o</span><span class="RuleName">l</span><span class="RuleName">t</span><span class="RuleName">a</span><span class="RuleName">g</span><span class="RuleName">e</span><span class="RuleName">1</span><span class="Reserved">:</span><span class="VariableName">y</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> <span class="VariableName">y</span> }
+    <span class="Reserved">|</span> <span class="RuleName">s</span><span class="RuleName">i</span><span class="RuleName">x</span><span class="Reserved">:</span><span class="VariableName">x</span>   <span class="RuleName">j</span><span class="RuleName">o</span><span class="RuleName">l</span><span class="RuleName">t</span><span class="RuleName">a</span><span class="RuleName">g</span><span class="RuleName">e</span><span class="RuleName">1</span><span class="Reserved">:</span><span class="VariableName">y</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> <span class="VariableName">y</span> }
+    <span class="Reserved">|</span> <span class="RuleName">f</span><span class="RuleName">i</span><span class="RuleName">v</span><span class="RuleName">e</span><span class="Reserved">:</span><span class="VariableName">x</span>  <span class="RuleName">j</span><span class="RuleName">o</span><span class="RuleName">l</span><span class="RuleName">t</span><span class="RuleName">a</span><span class="RuleName">g</span><span class="RuleName">e</span><span class="RuleName">1</span><span class="Reserved">:</span><span class="VariableName">y</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> <span class="VariableName">y</span> }
+    <span class="Reserved">|</span> <span class="RuleName">f</span><span class="RuleName">o</span><span class="RuleName">u</span><span class="RuleName">r</span><span class="Reserved">:</span><span class="VariableName">x</span>  <span class="RuleName">j</span><span class="RuleName">o</span><span class="RuleName">l</span><span class="RuleName">t</span><span class="RuleName">a</span><span class="RuleName">g</span><span class="RuleName">e</span><span class="RuleName">1</span><span class="Reserved">:</span><span class="VariableName">y</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> <span class="VariableName">y</span> }
+    <span class="Reserved">|</span> <span class="RuleName">t</span><span class="RuleName">h</span><span class="RuleName">r</span><span class="RuleName">e</span><span class="RuleName">e</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="RuleName">j</span><span class="RuleName">o</span><span class="RuleName">l</span><span class="RuleName">t</span><span class="RuleName">a</span><span class="RuleName">g</span><span class="RuleName">e</span><span class="RuleName">1</span><span class="Reserved">:</span><span class="VariableName">y</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> <span class="VariableName">y</span> }
+    <span class="Reserved">|</span> <span class="RuleName">t</span><span class="RuleName">w</span><span class="RuleName">o</span><span class="Reserved">:</span><span class="VariableName">x</span>   <span class="RuleName">j</span><span class="RuleName">o</span><span class="RuleName">l</span><span class="RuleName">t</span><span class="RuleName">a</span><span class="RuleName">g</span><span class="RuleName">e</span><span class="RuleName">1</span><span class="Reserved">:</span><span class="VariableName">y</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> <span class="VariableName">y</span> }
+    <span class="Reserved">|</span> <span class="RuleName">o</span><span class="RuleName">n</span><span class="RuleName">e</span><span class="Reserved">:</span><span class="VariableName">x</span>   <span class="RuleName">j</span><span class="RuleName">o</span><span class="RuleName">l</span><span class="RuleName">t</span><span class="RuleName">a</span><span class="RuleName">g</span><span class="RuleName">e</span><span class="RuleName">1</span><span class="Reserved">:</span><span class="VariableName">y</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> <span class="VariableName">y</span> }
+    ;
+
+<span class="RuleName">j</span><span class="RuleName">o</span><span class="RuleName">l</span><span class="RuleName">t</span><span class="RuleName">a</span><span class="RuleName">g</span><span class="RuleName">e</span><span class="RuleName">1</span> =
+    <span class="Reserved">|</span> <span class="RuleName">n</span><span class="RuleName">i</span><span class="RuleName">n</span><span class="RuleName">e</span><span class="Reserved">:</span><span class="VariableName">x</span>  <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> }
+    <span class="Reserved">|</span> <span class="RuleName">e</span><span class="RuleName">i</span><span class="RuleName">g</span><span class="RuleName">h</span><span class="RuleName">t</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> }
+    <span class="Reserved">|</span> <span class="RuleName">s</span><span class="RuleName">e</span><span class="RuleName">v</span><span class="RuleName">e</span><span class="RuleName">n</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> }
+    <span class="Reserved">|</span> <span class="RuleName">s</span><span class="RuleName">i</span><span class="RuleName">x</span><span class="Reserved">:</span><span class="VariableName">x</span>   <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> }
+    <span class="Reserved">|</span> <span class="RuleName">f</span><span class="RuleName">i</span><span class="RuleName">v</span><span class="RuleName">e</span><span class="Reserved">:</span><span class="VariableName">x</span>  <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> }
+    <span class="Reserved">|</span> <span class="RuleName">f</span><span class="RuleName">o</span><span class="RuleName">u</span><span class="RuleName">r</span><span class="Reserved">:</span><span class="VariableName">x</span>  <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> }
+    <span class="Reserved">|</span> <span class="RuleName">t</span><span class="RuleName">h</span><span class="RuleName">r</span><span class="RuleName">e</span><span class="RuleName">e</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> }
+    <span class="Reserved">|</span> <span class="RuleName">t</span><span class="RuleName">w</span><span class="RuleName">o</span><span class="Reserved">:</span><span class="VariableName">x</span>   <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> }
+    <span class="Reserved">|</span> <span class="RuleName">o</span><span class="RuleName">n</span><span class="RuleName">e</span><span class="Reserved">:</span><span class="VariableName">x</span>   <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> }
+    ;
+
+<span class="RuleName">n</span><span class="RuleName">i</span><span class="RuleName">n</span><span class="RuleName">e</span>  = <span class="Reserved">&amp;</span><span class="CharString">'</span><span class="CharString">9</span><span class="CharString">'</span> <span class="RuleName">h</span><span class="RuleName">i</span><span class="RuleName">t</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> } <span class="Reserved">|</span> <span class="RuleName">n</span><span class="RuleName">u</span><span class="RuleName">m</span><span class="RuleName">b</span><span class="RuleName">e</span><span class="RuleName">r</span> <span class="RuleName">n</span><span class="RuleName">i</span><span class="RuleName">n</span><span class="RuleName">e</span><span class="Reserved">:</span><span class="VariableName">x</span>  <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> };
+<span class="RuleName">e</span><span class="RuleName">i</span><span class="RuleName">g</span><span class="RuleName">h</span><span class="RuleName">t</span> = <span class="Reserved">&amp;</span><span class="CharString">'</span><span class="CharString">8</span><span class="CharString">'</span> <span class="RuleName">h</span><span class="RuleName">i</span><span class="RuleName">t</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> } <span class="Reserved">|</span> <span class="RuleName">n</span><span class="RuleName">u</span><span class="RuleName">m</span><span class="RuleName">b</span><span class="RuleName">e</span><span class="RuleName">r</span> <span class="RuleName">e</span><span class="RuleName">i</span><span class="RuleName">g</span><span class="RuleName">h</span><span class="RuleName">t</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> };
+<span class="RuleName">s</span><span class="RuleName">e</span><span class="RuleName">v</span><span class="RuleName">e</span><span class="RuleName">n</span> = <span class="Reserved">&amp;</span><span class="CharString">'</span><span class="CharString">7</span><span class="CharString">'</span> <span class="RuleName">h</span><span class="RuleName">i</span><span class="RuleName">t</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> } <span class="Reserved">|</span> <span class="RuleName">n</span><span class="RuleName">u</span><span class="RuleName">m</span><span class="RuleName">b</span><span class="RuleName">e</span><span class="RuleName">r</span> <span class="RuleName">s</span><span class="RuleName">e</span><span class="RuleName">v</span><span class="RuleName">e</span><span class="RuleName">n</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> };
+<span class="RuleName">s</span><span class="RuleName">i</span><span class="RuleName">x</span>   = <span class="Reserved">&amp;</span><span class="CharString">'</span><span class="CharString">6</span><span class="CharString">'</span> <span class="RuleName">h</span><span class="RuleName">i</span><span class="RuleName">t</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> } <span class="Reserved">|</span> <span class="RuleName">n</span><span class="RuleName">u</span><span class="RuleName">m</span><span class="RuleName">b</span><span class="RuleName">e</span><span class="RuleName">r</span> <span class="RuleName">s</span><span class="RuleName">i</span><span class="RuleName">x</span><span class="Reserved">:</span><span class="VariableName">x</span>   <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> };
+<span class="RuleName">f</span><span class="RuleName">i</span><span class="RuleName">v</span><span class="RuleName">e</span>  = <span class="Reserved">&amp;</span><span class="CharString">'</span><span class="CharString">5</span><span class="CharString">'</span> <span class="RuleName">h</span><span class="RuleName">i</span><span class="RuleName">t</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> } <span class="Reserved">|</span> <span class="RuleName">n</span><span class="RuleName">u</span><span class="RuleName">m</span><span class="RuleName">b</span><span class="RuleName">e</span><span class="RuleName">r</span> <span class="RuleName">f</span><span class="RuleName">i</span><span class="RuleName">v</span><span class="RuleName">e</span><span class="Reserved">:</span><span class="VariableName">x</span>  <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> };
+<span class="RuleName">f</span><span class="RuleName">o</span><span class="RuleName">u</span><span class="RuleName">r</span>  = <span class="Reserved">&amp;</span><span class="CharString">'</span><span class="CharString">4</span><span class="CharString">'</span> <span class="RuleName">h</span><span class="RuleName">i</span><span class="RuleName">t</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> } <span class="Reserved">|</span> <span class="RuleName">n</span><span class="RuleName">u</span><span class="RuleName">m</span><span class="RuleName">b</span><span class="RuleName">e</span><span class="RuleName">r</span> <span class="RuleName">f</span><span class="RuleName">o</span><span class="RuleName">u</span><span class="RuleName">r</span><span class="Reserved">:</span><span class="VariableName">x</span>  <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> };
+<span class="RuleName">t</span><span class="RuleName">h</span><span class="RuleName">r</span><span class="RuleName">e</span><span class="RuleName">e</span> = <span class="Reserved">&amp;</span><span class="CharString">'</span><span class="CharString">3</span><span class="CharString">'</span> <span class="RuleName">h</span><span class="RuleName">i</span><span class="RuleName">t</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> } <span class="Reserved">|</span> <span class="RuleName">n</span><span class="RuleName">u</span><span class="RuleName">m</span><span class="RuleName">b</span><span class="RuleName">e</span><span class="RuleName">r</span> <span class="RuleName">t</span><span class="RuleName">h</span><span class="RuleName">r</span><span class="RuleName">e</span><span class="RuleName">e</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> };
+<span class="RuleName">t</span><span class="RuleName">w</span><span class="RuleName">o</span>   = <span class="Reserved">&amp;</span><span class="CharString">'</span><span class="CharString">2</span><span class="CharString">'</span> <span class="RuleName">h</span><span class="RuleName">i</span><span class="RuleName">t</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> } <span class="Reserved">|</span> <span class="RuleName">n</span><span class="RuleName">u</span><span class="RuleName">m</span><span class="RuleName">b</span><span class="RuleName">e</span><span class="RuleName">r</span> <span class="RuleName">t</span><span class="RuleName">w</span><span class="RuleName">o</span><span class="Reserved">:</span><span class="VariableName">x</span>   <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> };
+<span class="RuleName">o</span><span class="RuleName">n</span><span class="RuleName">e</span>   = <span class="Reserved">&amp;</span><span class="CharString">'</span><span class="CharString">1</span><span class="CharString">'</span> <span class="RuleName">h</span><span class="RuleName">i</span><span class="RuleName">t</span><span class="Reserved">:</span><span class="VariableName">x</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> } <span class="Reserved">|</span> <span class="RuleName">n</span><span class="RuleName">u</span><span class="RuleName">m</span><span class="RuleName">b</span><span class="RuleName">e</span><span class="RuleName">r</span> <span class="RuleName">o</span><span class="RuleName">n</span><span class="RuleName">e</span><span class="Reserved">:</span><span class="VariableName">x</span>   <span class="Reserved">-</span><span class="Reserved">&gt;</span> { <span class="VariableName">x</span> };
+
+<span class="RuleName">h</span><span class="RuleName">i</span><span class="RuleName">t</span>[<span class="Meta">E</span><span class="Meta">s</span><span class="Meta">c</span><span class="Meta">a</span><span class="Meta">p</span><span class="Meta">e</span>] = <span class="RuleName">n</span><span class="RuleName">u</span><span class="RuleName">m</span><span class="RuleName">b</span><span class="RuleName">e</span><span class="RuleName">r</span>;
+
+<span class="RuleName">n</span><span class="RuleName">u</span><span class="RuleName">m</span><span class="RuleName">b</span><span class="RuleName">e</span><span class="RuleName">r</span> = <span class="CharString">'</span><span class="CharString">1</span><span class="CharString">'</span><span class="Reserved">|</span><span class="CharString">'</span><span class="CharString">2</span><span class="CharString">'</span><span class="Reserved">|</span><span class="CharString">'</span><span class="CharString">3</span><span class="CharString">'</span><span class="Reserved">|</span><span class="CharString">'</span><span class="CharString">4</span><span class="CharString">'</span><span class="Reserved">|</span><span class="CharString">'</span><span class="CharString">5</span><span class="CharString">'</span><span class="Reserved">|</span><span class="CharString">'</span><span class="CharString">6</span><span class="CharString">'</span><span class="Reserved">|</span><span class="CharString">'</span><span class="CharString">7</span><span class="CharString">'</span><span class="Reserved">|</span><span class="CharString">'</span><span class="CharString">8</span><span class="CharString">'</span><span class="Reserved">|</span><span class="CharString">'</span><span class="CharString">9</span><span class="CharString">'</span>;
+</pre>
+
+And the cool thing is, that this also highlights the answer for each line:
+
+<pre class="highlight"><span class="Escape">9</span><span class="Escape">8</span>7654321111111
+<span class="Escape">8</span>1111111111111<span class="Escape">9</span>
+2342342342342<span class="Escape">7</span><span class="Escape">8</span>
+818181<span class="Escape">9</span>1111<span class="Escape">2</span>111
+</pre>
+
+The generated C code just performs the addition:
+
+<pre class="highlight"><span class="CharString">#</span><span class="CharString">i</span><span class="CharString">n</span><span class="CharString">c</span><span class="CharString">l</span><span class="CharString">u</span><span class="CharString">d</span><span class="CharString">e</span><span class="CharString"> </span><span class="CharString">&lt;</span><span class="CharString">s</span><span class="CharString">t</span><span class="CharString">d</span><span class="CharString">i</span><span class="CharString">o</span><span class="CharString">.</span><span class="CharString">h</span><span class="CharString">&gt;</span><span class="CharString">
+</span><span class="VariableName">i</span><span class="VariableName">n</span><span class="VariableName">t</span> main(<span class="VariableName">v</span><span class="VariableName">o</span><span class="VariableName">i</span><span class="VariableName">d</span>) {
+    printf(<span class="String">&quot;</span><span class="String">P</span><span class="String">a</span><span class="String">r</span><span class="String">t</span><span class="String"> </span><span class="String">1</span><span class="String">:</span><span class="String"> </span><span class="String">%</span><span class="String">l</span><span class="String">d</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>, (<span class="VariableName">l</span><span class="VariableName">o</span><span class="VariableName">n</span><span class="VariableName">g</span> <span class="VariableName">i</span><span class="VariableName">n</span><span class="VariableName">t</span>)(<span class="String">0</span> + <span class="String">9</span><span class="String">8</span> + <span class="String">8</span><span class="String">9</span> + <span class="String">7</span><span class="String">8</span> + <span class="String">9</span><span class="String">2</span>));
+    <span class="Reserved">r</span><span class="Reserved">e</span><span class="Reserved">t</span><span class="Reserved">u</span><span class="Reserved">r</span><span class="Reserved">n</span> <span class="String">0</span>;
+}
+</pre>
+
+I was able to solve part 2 in the same way, but it required me to create
+`joltage12` to `joltage1` because you can not parameterize the recursion depth
+in meta. But here is what it looks like when run on the example:
+
+<pre class="highlight"><span class="Escape">9</span><span class="Escape">8</span><span class="Escape">7</span><span class="Escape">6</span><span class="Escape">5</span><span class="Escape">4</span><span class="Escape">3</span><span class="Escape">2</span><span class="Escape">1</span><span class="Escape">1</span><span class="Escape">1</span><span class="Escape">1</span>111
+<span class="Escape">8</span><span class="Escape">1</span><span class="Escape">1</span><span class="Escape">1</span><span class="Escape">1</span><span class="Escape">1</span><span class="Escape">1</span><span class="Escape">1</span><span class="Escape">1</span><span class="Escape">1</span><span class="Escape">1</span>111<span class="Escape">9</span>
+23<span class="Escape">4</span>2<span class="Escape">3</span><span class="Escape">4</span><span class="Escape">2</span><span class="Escape">3</span><span class="Escape">4</span><span class="Escape">2</span><span class="Escape">3</span><span class="Escape">4</span><span class="Escape">2</span><span class="Escape">7</span><span class="Escape">8</span>
+<span class="Escape">8</span>1<span class="Escape">8</span>1<span class="Escape">8</span>1<span class="Escape">9</span><span class="Escape">1</span><span class="Escape">1</span><span class="Escape">1</span><span class="Escape">1</span><span class="Escape">2</span><span class="Escape">1</span><span class="Escape">1</span><span class="Escape">1</span>
+</pre>
+
+Also note how numbers are parsed:
+
+<pre class="highlight"><span class="RuleName">n</span><span class="RuleName">u</span><span class="RuleName">m</span><span class="RuleName">b</span><span class="RuleName">e</span><span class="RuleName">r</span> = <span class="CharString">'</span><span class="CharString">1</span><span class="CharString">'</span><span class="Reserved">|</span><span class="CharString">'</span><span class="CharString">2</span><span class="CharString">'</span><span class="Reserved">|</span><span class="CharString">'</span><span class="CharString">3</span><span class="CharString">'</span><span class="Reserved">|</span><span class="CharString">'</span><span class="CharString">4</span><span class="CharString">'</span><span class="Reserved">|</span><span class="CharString">'</span><span class="CharString">5</span><span class="CharString">'</span><span class="Reserved">|</span><span class="CharString">'</span><span class="CharString">6</span><span class="CharString">'</span><span class="Reserved">|</span><span class="CharString">'</span><span class="CharString">7</span><span class="CharString">'</span><span class="Reserved">|</span><span class="CharString">'</span><span class="CharString">8</span><span class="CharString">'</span><span class="Reserved">|</span><span class="CharString">'</span><span class="CharString">9</span><span class="CharString">'</span>;
+</pre>
+
+This was the only way to do it in the meta language before. But I added support
+for character ranges. So the preferred way to write this now is this:
+
+<pre class="highlight"><span class="RuleName">n</span><span class="RuleName">u</span><span class="RuleName">m</span><span class="RuleName">b</span><span class="RuleName">e</span><span class="RuleName">r</span> = <span class="CharString">'</span><span class="CharString">1</span><span class="CharString">'</span>-<span class="CharString">'</span><span class="CharString">9</span><span class="CharString">'</span>;
+</pre>
+
+It is faster and it reads better. So one idea I had with solving Advent of Code
+using rlworkbench was that I can improve it with feedback from real usage. Here
+is one example.
+
+## Day 4
+
+This day I got to practice parsing grids i meta and practice how to represent
+them in C for easy access. Here is part of the parsing code:
+
+<pre class="highlight"><span class="RuleName">g</span><span class="RuleName">r</span><span class="RuleName">i</span><span class="RuleName">d</span> = <span class="RuleName">r</span><span class="RuleName">o</span><span class="RuleName">w</span><span class="Reserved">*</span><span class="Reserved">:</span><span class="VariableName">x</span><span class="VariableName">s</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> {
+    $rowCount
+    $colCount
+    <span class="String">&quot;</span><span class="String">i</span><span class="String">n</span><span class="String">t</span><span class="String"> </span><span class="String">p</span><span class="String">a</span><span class="String">p</span><span class="String">e</span><span class="String">r</span><span class="String">_</span><span class="String">r</span><span class="String">o</span><span class="String">l</span><span class="String">l</span><span class="String">s</span><span class="String">[</span><span class="String">&quot;</span> &lt;rowCount <span class="String">&quot;</span><span class="String">]</span><span class="String">[</span><span class="String">&quot;</span> &lt;colCount <span class="String">&quot;</span><span class="String">]</span><span class="String"> </span><span class="String">=</span><span class="String"> </span><span class="String">{</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span> &gt;
+        <span class="VariableName">x</span><span class="VariableName">s</span>
+    &lt; <span class="String">&quot;</span><span class="String">}</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+    <span class="String">&quot;</span><span class="String">i</span><span class="String">n</span><span class="String">t</span><span class="String"> </span><span class="String">c</span><span class="String">a</span><span class="String">n</span><span class="String">_</span><span class="String">b</span><span class="String">e</span><span class="String">_</span><span class="String">r</span><span class="String">e</span><span class="String">m</span><span class="String">o</span><span class="String">v</span><span class="String">e</span><span class="String">d</span><span class="String">[</span><span class="String">&quot;</span> &lt;rowCount <span class="String">&quot;</span><span class="String">]</span><span class="String">[</span><span class="String">&quot;</span> &lt;colCount <span class="String">&quot;</span><span class="String">]</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+    &gt;rowCount { W[1] }
+    &gt;colCount { W[2] }
+};
+
+<span class="RuleName">r</span><span class="RuleName">o</span><span class="RuleName">w</span> = <span class="RuleName">c</span><span class="RuleName">e</span><span class="RuleName">l</span><span class="RuleName">l</span><span class="Reserved">*</span><span class="Reserved">:</span><span class="VariableName">x</span><span class="VariableName">s</span> <span class="CharString">'</span><span class="Escape">\</span><span class="Escape">n</span><span class="CharString">'</span> <span class="Reserved">-</span><span class="Reserved">&gt;</span> {
+    #inc(W[1] 1)
+    #max(W[2] <span class="VariableName">x</span><span class="VariableName">s</span>.len)
+    <span class="String">&quot;</span><span class="String">{</span><span class="String">&quot;</span> <span class="VariableName">x</span><span class="VariableName">s</span> <span class="String">&quot;</span><span class="String">}</span><span class="String">,</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">&quot;</span>
+};
+</pre>
+
+And here is what it generates:
+
+<pre class="highlight"><span class="VariableName">i</span><span class="VariableName">n</span><span class="VariableName">t</span> paper_rolls[<span class="String">1</span><span class="String">0</span>][<span class="String">1</span><span class="String">0</span>] = {
+    {<span class="String">0</span>, <span class="String">0</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">0</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">0</span>, },
+    {<span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">0</span>, <span class="String">1</span>, <span class="String">0</span>, <span class="String">1</span>, <span class="String">0</span>, <span class="String">1</span>, <span class="String">1</span>, },
+    {<span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">0</span>, <span class="String">1</span>, <span class="String">0</span>, <span class="String">1</span>, <span class="String">1</span>, },
+    {<span class="String">1</span>, <span class="String">0</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">0</span>, <span class="String">0</span>, <span class="String">1</span>, <span class="String">0</span>, },
+    {<span class="String">1</span>, <span class="String">1</span>, <span class="String">0</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">0</span>, <span class="String">1</span>, <span class="String">1</span>, },
+    {<span class="String">0</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">0</span>, <span class="String">1</span>, },
+    {<span class="String">0</span>, <span class="String">1</span>, <span class="String">0</span>, <span class="String">1</span>, <span class="String">0</span>, <span class="String">1</span>, <span class="String">0</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, },
+    {<span class="String">1</span>, <span class="String">0</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">0</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, },
+    {<span class="String">0</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">0</span>, },
+    {<span class="String">1</span>, <span class="String">0</span>, <span class="String">1</span>, <span class="String">0</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">1</span>, <span class="String">0</span>, <span class="String">1</span>, <span class="String">0</span>, },
+};
+<span class="VariableName">i</span><span class="VariableName">n</span><span class="VariableName">t</span> can_be_removed[<span class="String">1</span><span class="String">0</span>][<span class="String">1</span><span class="String">0</span>];
+</pre>
+
+I think the meta language would benefit from some better mechanism to keep
+track of rows and columns. The `W[x]` mechanism is a hacky way to somewhat work
+with counters. But it is not very nice. I though about adding implicit counters
+for the star-operator. Maybe this is an example to revisit later to try to
+improve meta.
+
+I also learned that local variables in C are not automatically initialized to
+0. I got some random behavior because of it. Yey C! Furthermore it seems that
+[the compiler can not always fully detect
+it](https://stackoverflow.com/questions/74672374/gcc-not-warning-of-uninitialized-local-variable).
+
+## Day 5
+
+This puzzle included some fun with ranges. Instead of thinking of every number
+in a range, compute with ranges instead. I think there was a similar puzzle
+last year. It was satisfying to figure out.
+
+## Day 6
+
+This puzzle was not a very good fit for meta. Or at least part 2 wasn't.
+Meta works well only if you can parse character by character. Not column wise.
+I ended up writing another meta program to rotate the input text. That is,
+turning this:
+
+    123 328  51 64
+     45 64  387 23
+      6 98  215 314
+    *   +   *   +
+
+Into this:
+
+    *  1
+      42
+     653
+
+    +963
+     842
+       8
+
+    *23
+     185
+     571
+
+    +326
+    134
+    4
+
+Which I could then parse for part 2. But the whole thing became very
+complicated.
+
+## Day 7
+
+In this puzzle I accidentally used an `integer` instead of a `long`. The
+program worked fine on the example but produced garbage for the real input.
+Luckily I found out why quite quickly. I'm used to bignums in Python which
+never overflow. So I gained some more C experience the hard way.
+
+## Day 8
+
+Brute force worked fine. Maybe thanks to the speed of C? Is there a more clever
+way?
+
+I watched [Advent of Code 2025 Day 8 Jonathan
+Paulson](https://www.youtube.com/watch?v=Gd4-LOBfA88) and learned that union
+find is probably an algorithm to look up for this.
+
+I also avoided doing sorting in C here. The problem was that I needed to get
+the three largest things in an array. I solved it by finding the largest through
+linear search, and then setting that value to 0. Then I could do that three
+time to get the three largest things at the expense of "removing" them from the
+array. This was fine for this solution. But investigating more elegant solutions
+to this in C is something that I might want to do. There is `qsort` in the
+standard library. But what if modifying the array is not desirable? Copy the
+whole array and then sort? Another thing I though about was to write a function
+that found the largest thing that is smaller than X. In each iteration I could
+pass the previous value. But I would have to do something special for the
+initial case.
+
+## Day 9
+
+I used the [Point in
+polygon](https://en.wikipedia.org/wiki/Point_in_polygon) that I learned about
+last year. It shows that you get better at Advent of Code when you do more
+advent of code. Surprise!
+
+I got the correct result for part 2, but took it took ~6 minutes. Can I
+improve?
+
+I searched YouTube and found that coordinate compression might be something to
+look into.
+
+## Day 10
+
+Today's puzzle was a little more complex to parse. So it was fun to use meta.
+
+The actual algorithm took a long time for me to code. Partly because I
+struggled with arrays in C. I learned that they are copied when copying structs
+(not treated as pointers). More resources on this that I found useful:
+
+* [Are Array Members Deeply Copied?](https://www.geeksforgeeks.org/c/are-array-members-deeply-copied/)
+* [Assign one struct to another in C](https://stackoverflow.com/questions/2302351/assign-one-struct-to-another-in-c)
+* [I'm getting "Invalid Initializer", what am I doing wrong?](https://stackoverflow.com/questions/11043313/im-getting-invalid-initializer-what-am-i-doing-wrong)
+
+I implemented a pop function by returning the first element and moving all
+elements in the array left:
+
+<pre class="highlight">LightsState pop_lights_state(LightsStates* fringe) {
+    LightsState state;
+    <span class="VariableName">i</span><span class="VariableName">n</span><span class="VariableName">t</span> i;
+    assert(fringe-&gt;used &gt; <span class="String">0</span>);
+    state = fringe-&gt;states[<span class="String">0</span>];
+    fringe-&gt;used--;
+    <span class="Reserved">f</span><span class="Reserved">o</span><span class="Reserved">r</span> (i=<span class="String">0</span>; i&lt;fringe-&gt;used; i++) {
+        fringe-&gt;states[i] = fringe-&gt;states[i+<span class="String">1</span>];
+    }
+    <span class="Reserved">r</span><span class="Reserved">e</span><span class="Reserved">t</span><span class="Reserved">u</span><span class="Reserved">r</span><span class="Reserved">n</span> state;
+}
+</pre>
+
+In Python these sort of functions are just available. So it was fun to practice
+implementing them with more primitive data types.
+
+I didn't manage to solve part 2 of today's puzzle. When my attempt just took
+forever, I assumed that you had to do something more clever. Most likely
+involving more math and solving some kind of equation. That was not for me. Not
+this year at least.
+
+## Day 11
+
+I had solved a similar problem in previous years. So I found the solution to
+this one quite straight forward. But once again I struggled to implement it in
+C.  Being at this lower level is so much less convenient. But some things are
+actually easier here. So this was good practice.
+
+## Day 12
+
+I was so excited about today.
+
+I started by writing a highlighter for boards:
+
+<pre class="highlight"><span class="RuleName">m</span><span class="RuleName">a</span><span class="RuleName">i</span><span class="RuleName">n</span> = <span class="RuleName">c</span><span class="RuleName">h</span><span class="RuleName">a</span><span class="RuleName">r</span><span class="Reserved">*</span> <span class="Reserved">!</span><span class="Reserved">.</span>;
+
+<span class="RuleName">c</span><span class="RuleName">h</span><span class="RuleName">a</span><span class="RuleName">r</span> =
+    <span class="Reserved">|</span> <span class="RuleName">h</span><span class="RuleName">a</span><span class="RuleName">s</span><span class="RuleName">h</span>
+    <span class="Reserved">|</span> <span class="RuleName">p</span><span class="RuleName">i</span><span class="RuleName">e</span><span class="RuleName">c</span><span class="RuleName">e</span><span class="RuleName">O</span><span class="RuleName">n</span><span class="RuleName">e</span>
+    <span class="Reserved">|</span> <span class="RuleName">p</span><span class="RuleName">i</span><span class="RuleName">e</span><span class="RuleName">c</span><span class="RuleName">e</span><span class="RuleName">T</span><span class="RuleName">w</span><span class="RuleName">o</span>
+    <span class="Reserved">|</span> <span class="RuleName">p</span><span class="RuleName">i</span><span class="RuleName">e</span><span class="RuleName">c</span><span class="RuleName">e</span><span class="RuleName">T</span><span class="RuleName">h</span><span class="RuleName">r</span><span class="RuleName">e</span><span class="RuleName">e</span>
+    <span class="Reserved">|</span> <span class="RuleName">p</span><span class="RuleName">i</span><span class="RuleName">e</span><span class="RuleName">c</span><span class="RuleName">e</span><span class="RuleName">F</span><span class="RuleName">o</span><span class="RuleName">u</span><span class="RuleName">r</span>
+    <span class="Reserved">|</span> <span class="RuleName">p</span><span class="RuleName">i</span><span class="RuleName">e</span><span class="RuleName">c</span><span class="RuleName">e</span><span class="RuleName">F</span><span class="RuleName">i</span><span class="RuleName">v</span><span class="RuleName">e</span>
+    <span class="Reserved">|</span> <span class="RuleName">p</span><span class="RuleName">i</span><span class="RuleName">e</span><span class="RuleName">c</span><span class="RuleName">e</span><span class="RuleName">S</span><span class="RuleName">i</span><span class="RuleName">x</span>
+    <span class="Reserved">|</span> <span class="Reserved">.</span>
+    ;
+
+<span class="RuleName">h</span><span class="RuleName">a</span><span class="RuleName">s</span><span class="RuleName">h</span>[<span class="Meta">M</span><span class="Meta">e</span><span class="Meta">t</span><span class="Meta">a</span>] = <span class="CharString">'</span><span class="CharString">#</span><span class="CharString">'</span>;
+
+<span class="RuleName">p</span><span class="RuleName">i</span><span class="RuleName">e</span><span class="RuleName">c</span><span class="RuleName">e</span><span class="RuleName">O</span><span class="RuleName">n</span><span class="RuleName">e</span>[<span class="Meta">R</span><span class="Meta">e</span><span class="Meta">s</span><span class="Meta">e</span><span class="Meta">r</span><span class="Meta">v</span><span class="Meta">e</span><span class="Meta">d</span>]     = <span class="CharString">'</span><span class="CharString">A</span><span class="CharString">'</span> <span class="Reserved">|</span> <span class="CharString">'</span><span class="CharString">0</span><span class="CharString">'</span>;
+<span class="RuleName">p</span><span class="RuleName">i</span><span class="RuleName">e</span><span class="RuleName">c</span><span class="RuleName">e</span><span class="RuleName">T</span><span class="RuleName">w</span><span class="RuleName">o</span>[<span class="Meta">S</span><span class="Meta">t</span><span class="Meta">r</span><span class="Meta">i</span><span class="Meta">n</span><span class="Meta">g</span>]       = <span class="CharString">'</span><span class="CharString">B</span><span class="CharString">'</span> <span class="Reserved">|</span> <span class="CharString">'</span><span class="CharString">1</span><span class="CharString">'</span>;
+<span class="RuleName">p</span><span class="RuleName">i</span><span class="RuleName">e</span><span class="RuleName">c</span><span class="RuleName">e</span><span class="RuleName">T</span><span class="RuleName">h</span><span class="RuleName">r</span><span class="RuleName">e</span><span class="RuleName">e</span>[<span class="Meta">C</span><span class="Meta">h</span><span class="Meta">a</span><span class="Meta">r</span><span class="Meta">S</span><span class="Meta">t</span><span class="Meta">r</span><span class="Meta">i</span><span class="Meta">n</span><span class="Meta">g</span>] = <span class="CharString">'</span><span class="CharString">C</span><span class="CharString">'</span> <span class="Reserved">|</span> <span class="CharString">'</span><span class="CharString">2</span><span class="CharString">'</span>;
+<span class="RuleName">p</span><span class="RuleName">i</span><span class="RuleName">e</span><span class="RuleName">c</span><span class="RuleName">e</span><span class="RuleName">F</span><span class="RuleName">o</span><span class="RuleName">u</span><span class="RuleName">r</span>[<span class="Meta">E</span><span class="Meta">s</span><span class="Meta">c</span><span class="Meta">a</span><span class="Meta">p</span><span class="Meta">e</span>]      = <span class="CharString">'</span><span class="CharString">D</span><span class="CharString">'</span> <span class="Reserved">|</span> <span class="CharString">'</span><span class="CharString">3</span><span class="CharString">'</span>;
+<span class="RuleName">p</span><span class="RuleName">i</span><span class="RuleName">e</span><span class="RuleName">c</span><span class="RuleName">e</span><span class="RuleName">F</span><span class="RuleName">i</span><span class="RuleName">v</span><span class="RuleName">e</span>[<span class="Meta">R</span><span class="Meta">u</span><span class="Meta">l</span><span class="Meta">e</span><span class="Meta">N</span><span class="Meta">a</span><span class="Meta">m</span><span class="Meta">e</span>]    = <span class="CharString">'</span><span class="CharString">E</span><span class="CharString">'</span> <span class="Reserved">|</span> <span class="CharString">'</span><span class="CharString">4</span><span class="CharString">'</span>;
+<span class="RuleName">p</span><span class="RuleName">i</span><span class="RuleName">e</span><span class="RuleName">c</span><span class="RuleName">e</span><span class="RuleName">S</span><span class="RuleName">i</span><span class="RuleName">x</span>[<span class="Meta">V</span><span class="Meta">a</span><span class="Meta">r</span><span class="Meta">i</span><span class="Meta">a</span><span class="Meta">b</span><span class="Meta">l</span><span class="Meta">e</span><span class="Meta">N</span><span class="Meta">a</span><span class="Meta">m</span><span class="Meta">e</span>] = <span class="CharString">'</span><span class="CharString">F</span><span class="CharString">'</span> <span class="Reserved">|</span> <span class="CharString">'</span><span class="CharString">5</span><span class="CharString">'</span>;
+</pre>
+
+My idea was that I would be able to more easily debug how my algorithm placed
+blocks on the grid. And it kind of worked. After a lot of coding on the
+algorithm (which again was difficult for me in C) I had something that produced
+states like this:
+
+<pre class="highlight"><span class="Reserved">0</span><span class="Reserved">0</span><span class="Reserved">0</span><span class="Reserved">0</span><span class="Reserved">0</span><span class="Reserved">0</span>..<span class="String">1</span><span class="CharString">2</span>..<span class="CharString">2</span>..<span class="CharString">2</span>..<span class="Escape">3</span><span class="Escape">3</span><span class="Escape">3</span><span class="Escape">3</span><span class="Escape">3</span><span class="Escape">3</span><span class="Escape">3</span><span class="Escape">3</span><span class="Escape">3</span><span class="RuleName">4</span>.<span class="RuleName">4</span><span class="RuleName">4</span>.<span class="RuleName">4</span>..<span class="VariableName">5</span>....
+..<span class="Reserved">0</span>..<span class="Reserved">0</span>.<span class="String">1</span><span class="String">1</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="Escape">3</span><span class="Escape">3</span>.<span class="Escape">3</span><span class="Escape">3</span>.<span class="Escape">3</span><span class="Escape">3</span>.<span class="RuleName">4</span><span class="RuleName">4</span><span class="RuleName">4</span><span class="RuleName">4</span><span class="RuleName">4</span><span class="RuleName">4</span>.<span class="VariableName">5</span><span class="VariableName">5</span>....
+<span class="Reserved">0</span><span class="Reserved">0</span><span class="Reserved">0</span><span class="Reserved">0</span><span class="Reserved">0</span><span class="Reserved">0</span><span class="String">1</span><span class="String">1</span><span class="String">1</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span>.<span class="Escape">3</span><span class="Escape">3</span>.<span class="Escape">3</span><span class="Escape">3</span>.<span class="Escape">3</span><span class="Escape">3</span><span class="RuleName">4</span>.<span class="RuleName">4</span><span class="RuleName">4</span>.<span class="RuleName">4</span><span class="VariableName">5</span><span class="VariableName">5</span><span class="VariableName">5</span>....
+<span class="Reserved">0</span><span class="Reserved">0</span><span class="Reserved">0</span><span class="Reserved">0</span><span class="Reserved">0</span><span class="Reserved">0</span>.<span class="String">1</span><span class="String">1</span><span class="CharString">2</span>..<span class="CharString">2</span>..<span class="CharString">2</span>..<span class="Escape">3</span><span class="Escape">3</span><span class="Escape">3</span><span class="Escape">3</span><span class="Escape">3</span><span class="Escape">3</span><span class="Escape">3</span><span class="Escape">3</span><span class="Escape">3</span><span class="RuleName">4</span>.<span class="RuleName">4</span><span class="RuleName">4</span>.<span class="RuleName">4</span>..<span class="VariableName">5</span>....
+..<span class="Reserved">0</span>..<span class="Reserved">0</span><span class="String">1</span><span class="String">1</span><span class="String">1</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="Escape">3</span><span class="Escape">3</span>.<span class="Escape">3</span><span class="Escape">3</span>.<span class="Escape">3</span><span class="Escape">3</span>.<span class="RuleName">4</span><span class="RuleName">4</span><span class="RuleName">4</span><span class="RuleName">4</span><span class="RuleName">4</span><span class="RuleName">4</span>.<span class="VariableName">5</span><span class="VariableName">5</span>....
+<span class="Reserved">0</span><span class="Reserved">0</span><span class="Reserved">0</span><span class="Reserved">0</span><span class="Reserved">0</span><span class="Reserved">0</span>.<span class="String">1</span><span class="String">1</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span>.<span class="Escape">3</span><span class="Escape">3</span>.<span class="Escape">3</span><span class="Escape">3</span>.<span class="Escape">3</span><span class="Escape">3</span><span class="RuleName">4</span>.<span class="RuleName">4</span><span class="RuleName">4</span>.<span class="RuleName">4</span><span class="VariableName">5</span><span class="VariableName">5</span><span class="VariableName">5</span>....
+<span class="Reserved">0</span><span class="Reserved">0</span><span class="Reserved">0</span><span class="Reserved">0</span><span class="Reserved">0</span><span class="Reserved">0</span><span class="String">1</span><span class="String">1</span><span class="String">1</span><span class="CharString">2</span>..<span class="CharString">2</span>..<span class="CharString">2</span>..<span class="Escape">3</span><span class="Escape">3</span><span class="Escape">3</span><span class="Escape">3</span><span class="Escape">3</span><span class="Escape">3</span><span class="Escape">3</span><span class="Escape">3</span><span class="Escape">3</span><span class="RuleName">4</span>.<span class="RuleName">4</span><span class="RuleName">4</span>.<span class="RuleName">4</span>..<span class="VariableName">5</span>....
+..<span class="Reserved">0</span>..<span class="Reserved">0</span>.<span class="String">1</span><span class="String">1</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="CharString">2</span><span class="Escape">3</span><span class="Escape">3</span>.<span class="Escape">3</span><span class="Escape">3</span>.<span class="Escape">3</span><span class="Escape">3</span>.<span class="RuleName">4</span><span class="RuleName">4</span><span class="RuleName">4</span><span class="RuleName">4</span><span class="RuleName">4</span><span class="RuleName">4</span>.<span class="VariableName">5</span><span class="VariableName">5</span>....
+</pre>
+
+So far, so good. But my search seemed to take forever. I wanted to introduce
+caching to see if it would help. But after ~5 hours of struggling with C, I
+couldn't do it. I actually switched to Python. Implemented roughly the same
+that I had in C and was able to add caching. I think at least. But it still
+took forever.
+
+That's when I decided to quit. This was it for me this year.
+
+I looked up solutions for day 12 on the Internet and found that searching (as I
+was attempting) was probably not the right way to go. Although, I found one
+solution that was similar to what I tried to do: [ShuvraneelMitra |
+Advent-of-Code-2025-CPP | Day
+12](https://github.com/ShuvraneelMitra/Advent-of-Code-2025-CPP/blob/main/Day%2012/Day12_P1.cpp).
+
+I don't have a good intuition for when a computation is going to take too long.
+I tried to do something clever in day 1 to avoid unnecessary work. And I tried
+to brute force day 12. So that's maybe something that I should practice more
+next year. Analyse the problem and think about if a solution would be feasible.
+And if not, think of other ways to attack the problem.
+
+## Summary
+
+This year was fun.
+
+I got to improve rlworkbench and meta with input from real world usage.
+
+I got to practice writing more C code and learned some things the hard way.
+
+I got ideas for algorithms to look up (maybe for next year) and new areas of C
+to explore.
+
+But now I'm done. I'm glad it is over. Now I can get back to all the things I
+neglected during the last 12 days.

2025-12-01 07:44 Rickard pushed to blog

commit 498672bc0dd8178cd18a5e4b40691f68063b888b
Author: Rickard Lindberg <rickard@rickardlindberg.me>
Date:   Mon Dec 1 07:44:36 2025 +0100

    Minor fixes.

diff --git a/posts/2025/11/02/newsletter-november/post.md b/posts/2025/11/02/newsletter-november/post.md
index 74a803d..b81d59d 100644
--- a/posts/2025/11/02/newsletter-november/post.md
+++ b/posts/2025/11/02/newsletter-november/post.md
@@ -285,8 +285,8 @@ month that I found interesting.
 ## TODO
 
 Here are my ideas for next programming tasks. In every newsletter, I write
-about what I did and what next steps I'm most interested in pursuing. So here
-is the list going into next month.
+about what I did and what next steps I'm most interested in working on next
+month.
 
 * [rlworkbench](https://projects.rickardlindberg.me/rlworkbench.html)
   * Start using rlworkbench instead of Vim as my default text editor
@@ -309,7 +309,6 @@ is the list going into next month.
           gcc -o out/make out/make.c
           out/make
       * How to make make.c platform independent?
-        * Watched [Handmade Hero Day 011 - The Basics of Platform API Design](https://www.youtube.com/watch?v=_4vnV2Eng7M)
         * Build Windows platform layer in wine?
           * i686-w64-mingw32-gcc -Wfatal-errors -Werror -o $2 $1
           * It adds .exe extension

commit 1b519cc11b95ee6afad53224af9b5aa6a7c8d35b
Author: Rickard Lindberg <rickard@rickardlindberg.me>
Date:   Mon Dec 1 07:41:23 2025 +0100

    Newsletter november 2025.

diff --git a/posts/2025/11/02/newsletter-november/post.md b/posts/2025/11/02/newsletter-november/post.md
new file mode 100644
index 0000000..74a803d
--- /dev/null
+++ b/posts/2025/11/02/newsletter-november/post.md
@@ -0,0 +1,383 @@
+---
+date: 2025-12-01 08:00:00
+title: Newsletter November 2025: Can rlworkbench replace Vim?
+tags: newsletter,c,rlworkbench
+---
+
+This month I have continued learning about performance aware programming.
+First of all, I've progressed in the course [Computer,
+Enhance!](https://www.computerenhance.com/) I've done more homework and learned
+more about how CPUs work. Then I have worked on my new project
+[rlworkbench](https://projects.rickardlindberg.me/rlworkbench.html). It is
+written in C or have C code generated from higher level descriptions.  That
+means that I've been programming much more closely to the level of the CPU than
+I'm used to in Python and I've been able to experiment with performance aware
+concepts.
+
+## Adventures in C
+
+* I made rlworkbench compile without warnings (`-Wall`) and be C89 compatible
+  (`-std=c89 -pedantic`). My idea right now is that you should only need a C
+  compiler to build rlworkbench. Any C compiler and no other tools whatsoever.
+  The more portable the C code is, the more compilers should be able to build
+  it. I therefore figure that targeting C89 and having as strict compiler flags
+  as possible is a good thing.
+
+* I learned that calling `fflush` after every character when printing to
+  `stdout` made the program about twice as slow as using no flush (which I
+  think flushes after every line). I was measuring with `time` and I figured
+  something was off when the sys time was proportionally high.
+
+* I modified the meta program to print how much memory it consumed for the
+  parsing and code generation phases. Having mostly programmed in Python and
+  other high-level languages, I've never really thought about memory. But now,
+  when working in C, I can print exactly how many bytes of memory my program
+  uses. And memory access patterns is a big part of getting good performance
+  (I've read).
+
+* I experimented with different data structures to see how memory and
+  performance was affected. I think I don't have a good enough mental model at
+  the moment to make good decisions. I need to do more work on "Computer
+  Enhance!" But it has been fun to be able to experiment.
+
+* I decided to build rlworkbench using the unity build technique. Mainly
+  because it is simple. No fancy make system is needed. I found the article
+  [Working with Jumbo/Unity Builds (Single Translation
+  Unit)](https://austinmorlan.com/posts/unity_jumbo_build/) quite nice.
+
+## rlworkbench
+
+rlworkbench is my new project where I try to build a [language
+workbench](https://en.wikipedia.org/wiki/Language_workbench). What is that?
+What am I trying to build?
+
+The way I think about it is that rlworkbench should be a text editor that is
+aware of the language of the text that is being edited. That awareness can give
+you syntax highlighting for example. But it can also give you more if it knows
+more about the language. For example, there might be an editor operation to
+expand the selection. If the cursor is inside a function, expanding the
+selection might select the whole function. Because the editor is aware of the
+language, it knows where the function starts and ends. Furthermore, defining
+the languages that rlworkbench knows about should be easy. And the norm should
+be the create many small domain specific languages. And when you define a
+language, it not only gives you editor support, but you can also define how
+that language should be compiled or translated.
+
+So that is kind of what I have in mind right now.
+
+I figured a first step towards the editor would be to just output a syntax
+highlighted file to the terminal. That would be one half of the problem. The
+other half of the problem would be to display that in a custom editor that also
+allows you to edit the text.
+
+The meta program already had support to parse the meta language. I made some
+modification so that you could specify what parts should be highlighted and
+how. In this process I also extracted embedded C code in meta to separate C
+files for easier re-use in rlworkbench as well. I also added basic lexing
+highlighting support for C.
+
+Here is the program that I first came up with:
+
+    $ ./out/highlight meta <src/examples/table/table.meta
+
+This highlight program is actually quite small and relies mostly on the meta
+stuff:
+
+    #include "languages.c"
+
+    MetaParseFunction get_parse_function(int argc, char** argv) {
+        if (argc >= 2) {
+            if (strcmp(argv[1], "c") == 0) {
+                return c_rule_main;
+            } else if (strcmp(argv[1], "meta") == 0) {
+                return meta_rule_main;
+            } else {
+                fprintf(stderr, "ERROR: unknown language %s\n", argv[1]);
+            }
+        } else {
+            fprintf(stderr, "ERROR: no language specified\n");
+        }
+        exit(1);
+    }
+
+    int main(int argc, char** argv) {
+        Arena arena = arena_create(2<<25);
+        MetaParseState* parse_state = meta_parse_state_from_stdin(&arena);
+        MetaAction action = get_parse_function(argc, argv)(parse_state);
+        int i;
+        if (!action.valid) {
+            fprintf(stderr, "ERROR: parse error [pos=%d] [size=%d]", parse_state->pos, parse_state->input_buffer->size);
+            exit(1);
+        }
+        for (i=0; i<parse_state->input_buffer->size; i++) {
+            switch (parse_state->highlight[i]) {
+                case MetaHighlight_RuleName:
+                    printf("\033[34m");
+                    break;
+                case MetaHighlight_VariableName:
+                    printf("\033[33m");
+                    break;
+                case MetaHighlight_String:
+                    printf("\033[36m");
+                    break;
+                case MetaHighlight_CharString:
+                    printf("\033[37m");
+                    break;
+                case MetaHighlight_Escape:
+                    printf("\033[31m");
+                    break;
+                case MetaHighlight_Meta:
+                    printf("\033[35m");
+                    break;
+                case MetaHighlight_Reserved:
+                    printf("\033[32m");
+                    break;
+                case MetaHighlight_Unset:
+                case MetaHighlight_None:
+                    break;
+            }
+            putc(parse_state->input_buffer->buffer[i], stdout);
+            printf("\033[0m");
+        }
+        return 0;
+    }
+
+I was very exited to get this working. I could get excellent highlighting
+support for the meta language, and basic highlighting support for C. And it is
+quite easy to add new languages.
+
+Then I moved on to the next phase which was to implement an actual editor so
+that the highlighted text could be displayed there instead of in the terminal
+and allow you to actually modify the text (which would then be parsed and
+highlighted again).
+
+I decided to initially target [SDL](https://www.libsdl.org/) as my first
+platform. Similarly to how Casey built a [Windows Platform
+Layer](https://www.youtube.com/playlist?list=PLEMXAbCVnmY4ZDrwfTpTdQeFe5iWtKxyb)
+in Handmade Hero, I built a platform layer for SDL (which works on many
+platforms). I might want to write more of what SDL does myself to have more
+control and do more of the handmade approach. But for now, I want faster
+results, and I think the architecture of the platform layer still makes it
+possible to do switch out later.
+
+The architecture currently looks like this:
+
+The `main` function is defined by the platform. The platform calls the
+following functions in the application:
+
+    WorkbenchAppInit workbench_init(int argc, char** argv);
+    void workbench_key_down(Workbench* state, char key);
+    void workbench_render(Workbench* state, int w, int h, unsigned int elapsed_ms);
+
+The application calls the following functions in the platform layer:
+
+    void platform_clear(HighlightBackground highlight);
+    void platform_draw_char(char* c, int* x, int* y, Highlight highlight, HighlightBackground background);
+
+Once the application is initialized it gets key down events repeatedly and is
+asked to render itself. And the only rendering that the application can do is
+clear the screen and draw a character at a given position. That is the
+interface.
+
+All the functionality for highlighting and the editor is now implemented in
+around 2k lines of code:
+
+        3 src/dotall.meta
+       12 src/experiments/strings.c
+       18 src/arg.c
+       19 src/experiments/bitmanipulation.c
+       22 src/generic.meta
+       22 src/language.c
+       24 src/examples/table/table.meta
+       26 src/experiments/sizes.c
+       28 src/list.c
+       34 src/experiments/fork.c
+       43 src/io.c
+       44 src/arena.c
+       58 src/highlight.c
+       61 src/stringbuilder.c
+       68 src/c.meta
+       96 src/string.c
+      146 src/meta.c
+      180 src/examples/computerenhance_decoder/computerenhance_decoder.meta
+      249 src/workbench_sdl.c
+      403 src/workbench.c
+      553 src/meta/meta.meta
+     2109 total
+
+The state of the editor is that you can actually open a file, do some basic
+editing while the highlighter updates, and then write the file to disk.
+Reaching this point was so satisfying. I can now see myself replacing Vim with
+this editor. But first I need to implement so that the Enter key inserts a
+newline. (I told you the editing capabilities were basic.) Not being able to
+insert a newline is a bit limiting. Even though I don't think you technically
+need newlines in a C program.
+
+One of the most satisfying parts of doing the work above was when I implemented
+caching if character glyphs. It was something that I learned from Casey talking
+about [Refterm](https://www.youtube.com/watch?v=pgoetgxecw8) and that I had on
+my TODO list to try out. The satisfying part was that it was quite simple to
+implement and it reduced rendering times from something like 30ms to 1ms. (I
+don't remember the exact numbers, but the wins were huge.) I can now scroll
+through a text file and the screen updates in a few milliseconds. Here is the
+implementation of the cache get:
+
+    SDL_Texture* platform_sdl_char_textures_get(char *c, Highlight color) {
+        SDL_Texture** slot = &charTextures[*c % PLATFORM_SDL_CHAR_CACHE_SIZE][color];
+        if (*slot == NULL) {
+            SDL_Surface *text = NULL;
+            SDL_Texture *texture = NULL;
+            SDL_Color sdl_color;
+            sdl_color.r = HIGHLIGHT_COLORS[color].r;
+            sdl_color.g = HIGHLIGHT_COLORS[color].g;
+            sdl_color.b = HIGHLIGHT_COLORS[color].b;
+            sdl_color.a = SDL_ALPHA_OPAQUE;
+            text = TTF_RenderText_Blended(font, c, 1, sdl_color);
+            if (text) {
+                texture = SDL_CreateTextureFromSurface(renderer, text);
+                SDL_DestroySurface(text);
+            }
+            *slot = texture;
+        }
+        return *slot;
+    }
+
+It uses SDL and its sattelite library SDL_ttf to render a character onto a
+texture.  I allocate enough memory to fit all ASCII characters and all
+supported colors of it. In the future I probably want to support utf8 as well.
+And then I probably won't be able to fit all in memory? So I need to check if
+the current texture is for the right character. But ASCII works fine for now,
+and I think I want to prioritize other features.
+
+## Inspirational resources
+
+In addition to the things already mentioned, here are things I consumed this
+month that I found interesting.
+
+* [Table-Driven Code
+  Generation](https://www.rfleury.com/p/table-driven-code-generation) describes
+  a similar approach as I'm trying to enable with rlworkbench. You treat C as
+  the target platform and build many custom languages on top of it.
+
+* In [Unwind Episode 2: Allen
+  Webster](https://handmade.network/podcast/ep/14a5407e-5f73-4c59-a422-44c4ece6a1bf)
+  they talk about how you would like to be able to describe a model of
+  something in your program, and from that model you can generate code for
+  different scenarios. For example, if you model your program CLI arguments,
+  you can generate both a parser and a documentation page from the same model.
+  They also talk about that text is not an optimal way to store programs. I
+  find this interesting, but for now, I lean on the side that for a tool to be
+  practically useful, it must work with text, but if the text is enhanced with
+  knowledge of the structure, it can get some of the benefits anyway. They also
+  talk about flexibility in a programming language. They said that C's high
+  level is too low and that Haskell's low level is to high. And when
+  programming, you might need a quite wide spectrum. I find that idea
+  interesting and hope to explore it with rlworkbench. Inside your project, you
+  can create high-level languages that compile down to C for example. When you
+  need the C level, it is there. But maybe only 40% of your codebase need that
+  low level. Allen also wrote a text editor called
+  [4coder](https://4coder.net/).
+
+* [Tips for C Programming](https://www.youtube.com/watch?v=9UIIMBqq1D4) had
+  some useful tips for how to enjoy C. Arenas was probably the big thing for me
+  that I already learned about last month.
+
+## TODO
+
+Here are my ideas for next programming tasks. In every newsletter, I write
+about what I did and what next steps I'm most interested in pursuing. So here
+is the list going into next month.
+
+* [rlworkbench](https://projects.rickardlindberg.me/rlworkbench.html)
+  * Start using rlworkbench instead of Vim as my default text editor
+    * Implement the features that I'm missing
+  * Structure
+    * Generate highlight.c from high level description
+    * Generate language.c from list of available languages
+  * Platform layer
+    * Use `SDL_HINT_MAIN_CALLBACK_RATE=waitevent` and animate cursor differently
+  * Test framework
+    * Convert experiments to tests
+  * Make it bootstrapable with only a C compiler (any C compiler)
+    * Experiment: fork+exec to run process (Which header? Which linker?)
+      * https://github.com/tsoding/nob.h/blob/main/nob.h#L1136-L1226
+    * https://dependablec.org/
+    * https://github.com/tsoding/nob.h (idea for a build system)
+    * Notes:
+          gcc -o out/meta src/meta/meta.c
+          out/meta <src/make/make.build >out/make.c
+          gcc -o out/make out/make.c
+          out/make
+      * How to make make.c platform independent?
+        * Watched [Handmade Hero Day 011 - The Basics of Platform API Design](https://www.youtube.com/watch?v=_4vnV2Eng7M)
+        * Build Windows platform layer in wine?
+          * i686-w64-mingw32-gcc -Wfatal-errors -Werror -o $2 $1
+          * It adds .exe extension
+  * Editor
+    * Handle cursor at end
+    * Support for undo/redo
+    * Only insert "printable" characters
+    * Fun "character explode" animation when saving
+  * Highlighting
+    * More generic names for MetaHighligt enum members
+    * Base highlight on top-level items and only re-parse the top-level section that changed (that is how [10x Editor](https://10xeditor.com/) works according to [If you're serious about programming, listen to Stewart Lynch](https://www.youtube.com/watch?v=1sdjQ7uTziw))
+  * Rendering
+    * Make glyph cache support utf-8
+      * Got idea for implementation from hash map that Steward talked about in [If you're serious about programming, listen to Stewart Lynch](https://www.youtube.com/watch?v=1sdjQ7uTziw)
+        * Learned more about hash maps from [HashMaps & Dictionaries, Explained Simply](https://www.youtube.com/watch?v=y11XNXi9dgs)
+  * Meta language/compiler
+    * Allow parsing only (no skip overhead of actions when not used)
+    * Generalize unique to work on any expression (to replace unseen)?
+    * Pass Buffer as value instead of allocating on heap?
+    * Flags for more compact data structure for Chunk?
+    * Detect infinite loop -> OOM ((rule*)*)
+    * Optimize 'or' based on first character
+      ```
+      keyword = 'foo' | 'bar' | 'baz' | 'return' | other
+      ->
+      switch (first_char) {
+          case 'f':
+              keyword = 'foo' | other
+          case 'b':
+              keyword = 'bar' | 'baz' | other
+          case 'r':
+              keyword = 'return' | other
+      }
+      ```
+      * How to make this transform?
+  * Ideas
+    * Editor show a tree view of your folder/files in one view
+      * You switch to another file by just navigating to a different location
+        in this giant document
+      * The document can collapse subsections to make the structure clear
+    * Immediate mode UI?
+    * Handmade style
+    * Program in a style where you can choose the language (abstraction level) at choice, and always have to possibility to go low level when needed
+      * Code re-use is bad for performance. It does what you want, but not in the optimal way for this problem
+        * Allow layers of abstractions to be shaved off if the problem is more easily solved at a lower level
+    * How do I do c projects?
+      RLC?
+      No build system. Only C compiler.
+      First compile rlmeta2.c
+      Then rlc.rlmeta2 -> RLC.c -> RLC
+      Then main.rlc -> main.c -> main
+      RLC should have high level syntax for low level stuff. Like nothing?
+* [Computer, Enhance!](https://www.computerenhance.com/)
+  * Continue course and do more homework
+* Learning C
+  * What happens if a link to a library that is not used? Static vs dynamic?
+  * Can gcc warn about functions that are not called?
+  * int main(...) vs exit(...)?
+    * https://stackoverflow.com/questions/46903180/syscall-implementation-of-exit
+* Publish project landing pages for my most relevant projects
+* [New blog](https://blog.rickardlindberg.me/)
+  * Migrate all my blog posts to my it
+  * Make it available as a downloadable PDF
+* [rlselect2](https://projects.rickardlindberg.me/rlselect2.html)
+  * Implement unique in C
+  * Increase performance by doing less (Casey C vs Python example)
+    * Don't do what the user has not asked for
+      * Yield lines to display
+      * Don't read the whole file, only as far as needed
+* Inspiration
+  * https://github.com/nicbarker/river

2025-11-02 17:13 Rickard pushed to blog

commit 8a6fd343f30a8a46adca571e86a89a6e24cd3ce0
Author: Rickard Lindberg <rickard@rickardlindberg.me>
Date:   Sun Nov 2 17:13:14 2025 +0100

    Get rid of si in youtube url

diff --git a/posts/2025/10/27/newsletter-october/post.md b/posts/2025/10/27/newsletter-october/post.md
index b4ea93d..a84c318 100644
--- a/posts/2025/10/27/newsletter-october/post.md
+++ b/posts/2025/10/27/newsletter-october/post.md
@@ -87,7 +87,7 @@ Allocator](https://www.rfleury.com/p/untangling-lifetimes-the-arena-allocator).
 He also covers the topic in the video [Enter The Arena: Simplifying Memory
 Management (2023)](https://youtu.be/TZ5a3gCCZYo). And in [Everyone is doing
 memory management wrong. feat. Ryan Fleury | S2
-E02](https://youtu.be/UeJPyuVxL-o?si=ePSrtw0td6cPOt1h&t=2162) (at around 36:02)
+E02](https://youtu.be/UeJPyuVxL-o?t=2162) (at around 36:02)
 Ryan talks about how he learned about arenas from Casey's [Handmade
 Hero](https://guide.handmadehero.org/).
 

2025-11-02 17:01 Rickard pushed to blog

commit 964b135abba8d285721781a7ae3b6881a9ff05d4
Author: Rickard Lindberg <rickard@rickardlindberg.me>
Date:   Sun Nov 2 17:00:58 2025 +0100

    Add tag

diff --git a/posts/2025/10/27/newsletter-october/post.md b/posts/2025/10/27/newsletter-october/post.md
index d263432..b4ea93d 100644
--- a/posts/2025/10/27/newsletter-october/post.md
+++ b/posts/2025/10/27/newsletter-october/post.md
@@ -1,7 +1,7 @@
 ---
 date: 2025-11-02 16:49:00
 title: Newsletter October 2025: Computer Enhance!
-tags: newsletter,rlmeta,rlworkbench
+tags: newsletter,rlmeta,rlselect,rlworkbench
 ---
 
 This month I discovered Casey Muratori. This opened up a whole new world of

2025-11-02 17:00 Rickard pushed to blog

commit b3754b48d882d335cd4319a9cd26b29a8c339318
Author: Rickard Lindberg <rickard@rickardlindberg.me>
Date:   Sun Nov 2 17:00:25 2025 +0100

    Add tags

diff --git a/posts/2025/10/27/newsletter-october/post.md b/posts/2025/10/27/newsletter-october/post.md
index 07b96b4..d263432 100644
--- a/posts/2025/10/27/newsletter-october/post.md
+++ b/posts/2025/10/27/newsletter-october/post.md
@@ -1,7 +1,7 @@
 ---
 date: 2025-11-02 16:49:00
 title: Newsletter October 2025: Computer Enhance!
-tags: newsletter
+tags: newsletter,rlmeta,rlworkbench
 ---
 
 This month I discovered Casey Muratori. This opened up a whole new world of

2025-11-02 16:58 Rickard pushed to blog

commit 90963811c42ac54860b445d85fffb088673ce698
Author: Rickard Lindberg <rickard@rickardlindberg.me>
Date:   Sun Nov 2 16:58:42 2025 +0100

    Newsletter october 2025

diff --git a/posts/2025/10/27/newsletter-october/post.md b/posts/2025/10/27/newsletter-october/post.md
new file mode 100644
index 0000000..07b96b4
--- /dev/null
+++ b/posts/2025/10/27/newsletter-october/post.md
@@ -0,0 +1,233 @@
+---
+date: 2025-11-02 16:49:00
+title: Newsletter October 2025: Computer Enhance!
+tags: newsletter
+---
+
+This month I discovered Casey Muratori. This opened up a whole new world of
+programming to me, and I have been consuming many hours of Youtube videos from
+this new world and also started new programming projects to explore these
+ideas. It feels like I have unlocked the next level of programming. So who is
+Casey? And what have I been doing? Let's see.
+
+Casey cares about performance. He has a bunch of educational resources where he
+talks about how to become aware of performance and how to improve performance.
+A few of the first things I came across from him are the following:
+
+* [Refterm Lecture Part 1 - Philosophies of
+  Optimization](https://www.youtube.com/watch?v=pgoetgxecw8)
+
+* [Software Performance: Avoiding Slow Code, Myths & Sane Approaches – Casey
+  Muratori | The Marco Show](https://www.youtube.com/watch?v=apREl0KmTdQ)
+
+* [Simple Code, High Performance](https://www.youtube.com/watch?v=Ge3aKEmZcqY)
+
+* [The Thirty Million Line
+  Problem](https://www.youtube.com/watch?v=kZRE7HIO3vk)
+
+* [Solving Java’s 1 Billion Row Challenge (Ep. 1) | With
+  @caseymuratori](https://www.youtube.com/watch?v=n-YK3B4_xPA)
+
+After becoming a little more aware of performance, I got an idea for how to
+improve the performance of
+[rlselect](https://rickardlindberg.me/projects/rlselect/). I started
+implementing [rlselect2](https://projects.rickardlindberg.me/rlselect2.html)
+with a focus on new ideas for better performance. Not that rlselect desperately
+needs better performance, but I wanted to learn. So maybe next time I write
+something, I don't default to bad performance.
+
+Casey also has a subscription-based course called
+[Computer, Enhance!](https://www.computerenhance.com/) which I also enrolled
+in. You learn about how computers (CPUs) work and how to get the most out of
+them. Casey explains things very well, so I look forward to working my way
+through his course.
+
+The first homework in the course is to write an instruction decoder for 8086
+instructions. That is, you should parse machine code and disassemble it into
+assembly instructions.
+
+Then I got sidetracked. Sidetracked with
+[rlmeta2](https://projects.rickardlindberg.me/rlmeta2.html), which is a new
+implementation of [rlmeta](https://rickardlindberg.me/projects/rlmeta/). What
+is rlmeta?
+
+> RLMeta is a programming language in which you write grammars. Grammars have
+> rules that specify how to match objects from an input stream and specify what
+> should happen when objects are matched. It can be used to write lexers,
+> parsers, tree transformers, code generators, and similar tools.
+
+Why did I start a second implementation? Maybe because I had new ideas for how
+to get better performance. Maybe because I like the architecture of rlmeta and
+wanted to try and bootstrap it again.
+
+The first step was to implement rlmeta2 i Python. I was able to do that in a
+weekend. Then, because of my new ideas about performance, I wanted to implement
+it in C instead. I spent much time thinking about how to implement some of
+Python's concepts in C for the runtime support that rlmeta2 needs.
+
+Then I watched the Wookash podcast [Casey Muratori on Legendary Handmade
+Hero!](https://youtu.be/AhOZ4E-fyLY) where Casey mentioned [Better Software
+Conference](https://bettersoftwareconference.com/). The conference features
+speakers that seem to share Casey's philosophy about performance and the
+handmade spirit.
+
+I watched the talk [Vjekoslav Krajačić – File Pilot: Inside the Engine – BSC
+2025](https://youtu.be/bUOOaXf9qIM). In it, he talks about arenas. Arenas is
+a memory allocation strategy that can be used in C that feels like garbage
+collection.
+
+That was a clue for me in my work on implementing rlmeta2 in C. Python has
+automatic memory management and garbage collection. So I've never really
+thought about memory.  But rlmeta2 needs to allocate memory dynamically. How do
+you do that in C in a good way?
+
+I found a blog post on the subject by Ryan Fleury (also a speaker at BSC):
+[Untangling Lifetimes: The Arena
+Allocator](https://www.rfleury.com/p/untangling-lifetimes-the-arena-allocator).
+He also covers the topic in the video [Enter The Arena: Simplifying Memory
+Management (2023)](https://youtu.be/TZ5a3gCCZYo). And in [Everyone is doing
+memory management wrong. feat. Ryan Fleury | S2
+E02](https://youtu.be/UeJPyuVxL-o?si=ePSrtw0td6cPOt1h&t=2162) (at around 36:02)
+Ryan talks about how he learned about arenas from Casey's [Handmade
+Hero](https://guide.handmadehero.org/).
+
+Another topic that came up in this (to me) new world was data-oriented design
+and writing programs that make effective use of the CPUs caches. One talk about
+that that I watched was [CppCon 2014: Mike Acton "Data-Oriented Design and
+C++"](https://www.youtube.com/watch?v=rX0ItVEVjHc). By making assumptions about
+your data, you can write more efficient programs.
+
+So my head has been spinning with high frequency on these ideas. Learning more
+low level programming. Learning how high level concepts map to low level
+concepts. Sometimes working on a high abstraction level is nice. But sometimes
+all layers of abstractions get in the way. Certainly for performance. But
+sometimes a problem might actually be harder to solve with more abstractions.
+So I am excited to learn more about low level concepts to be able to write
+better software.
+
+At the end of the month I had actually made some real good progress on my new
+projects. I managed to write the instruction decoder for the first homework
+assignment in rlmeta2.  Here is what it looks like:
+
+    main = decodeInstruction*:xs !. -> {
+        "bits 16\n"
+        "\n"
+        xs
+    };
+
+    decodeInstruction =
+        | opFromByte:opcode peekRegByte:source rmByte:destination -> {
+            opcode " " destination ", " source "\n"
+        }
+        | opFromWide:opcode peekRegWide:source rmWide:destination -> {
+            opcode " " destination ", " source "\n"
+        }
+        ;
+
+    peekRegByte =
+        | &0b_xx_000_xxx -> { "al" }
+        | &0b_xx_001_xxx -> { "cl" }
+        | &0b_xx_010_xxx -> { "dl" }
+        | &0b_xx_011_xxx -> { "bl" }
+        | &0b_xx_100_xxx -> { "ah" }
+        | &0b_xx_101_xxx -> { "ch" }
+        | &0b_xx_110_xxx -> { "dh" }
+        | &0b_xx_111_xxx -> { "bh" }
+        ;
+
+    peekRegWide =
+        | &0b_xx_000_xxx -> { "ax" }
+        | &0b_xx_001_xxx -> { "cx" }
+        | &0b_xx_010_xxx -> { "dx" }
+        | &0b_xx_011_xxx -> { "bx" }
+        | &0b_xx_100_xxx -> { "sp" }
+        | &0b_xx_101_xxx -> { "bp" }
+        | &0b_xx_110_xxx -> { "si" }
+        | &0b_xx_111_xxx -> { "di" }
+        ;
+
+    rmByte =
+        | 0b_xx_xxx_000 -> { "al" }
+        | 0b_xx_xxx_001 -> { "cl" }
+        | 0b_xx_xxx_010 -> { "dl" }
+        | 0b_xx_xxx_011 -> { "bl" }
+        | 0b_xx_xxx_100 -> { "ah" }
+        | 0b_xx_xxx_101 -> { "ch" }
+        | 0b_xx_xxx_110 -> { "dh" }
+        | 0b_xx_xxx_111 -> { "bh" }
+        ;
+
+    rmWide =
+        | 0b_xx_xxx_000 -> { "ax" }
+        | 0b_xx_xxx_001 -> { "cx" }
+        | 0b_xx_xxx_010 -> { "dx" }
+        | 0b_xx_xxx_011 -> { "bx" }
+        | 0b_xx_xxx_100 -> { "sp" }
+        | 0b_xx_xxx_101 -> { "bp" }
+        | 0b_xx_xxx_110 -> { "si" }
+        | 0b_xx_xxx_111 -> { "di" }
+        ;
+
+    opFromByte = &0b_xxxxxx_0_0 opcode:x -> { x };
+    opFromWide = &0b_xxxxxx_0_1 opcode:x -> { x };
+
+    opcode =
+        | 0b_100010_d_w -> { "mov" }
+        ;
+
+This program gets compiled to a C program by the meta compiler (a version of
+rlmeta2 implemented in C) which can then be compiled using a C compiler:
+
+    $ ./meta <decoder.meta >decoder.c
+    $ gcc -o decoder decoder.c
+
+This program is a decoder for 8086 machine instructions, and when run on the
+machine code example
+
+    $ xxd machine_code_example
+    00000000: 89d9 88e5 89da 89de 89fb 88c8 88ed 89c3  ................
+    00000010: 89f3 89fc 89c5                           ......
+
+it spits out this:
+
+    $ ./decoder <machine_code_example
+    bits 16
+
+    mov cx, bx
+    mov ch, ah
+    mov dx, bx
+    mov si, bx
+    mov bx, di
+    mov al, cl
+    mov ch, ch
+    mov bx, ax
+    mov bx, si
+    mov sp, di
+    mov bp, ax
+
+## TODO
+
+This is an experiment to make public a `TODO` list with my current programming
+interests. In every newsletter, I will report what I did and what next steps
+I'm most interested in pursuing. So here is the list going into next month.
+
+* Do homework 2 of Computer Enhance using rlmeta2
+* Work on rlworkbench (an experimental [language workbench](https://en.wikipedia.org/wiki/Language_workbench) based on rlmeta2)
+    * Improve meta
+        * Make it compile without warnings
+    * Make it bootstrapable with only a C compiler (any C compiler)
+        * https://dependablec.org/
+        * https://github.com/tsoding/nob.h (idea for a build system)
+    * Ideas
+        * Cache glyphs
+        * Immediate mode UI?
+        * Handmade style
+* New blog
+    * Migrate all my blog posts to my it
+    * Make it available as a downloadable PDF
+
+References:
+
+* rlmeta2: https://projects.rickardlindberg.me/rlmeta2.html
+* rlworkbench: https://projects.rickardlindberg.me/rlworkbench.html
+* new blog: https://blog.rickardlindberg.me/

2025-11-02 10:34 Rickard pushed to blog

commit ed9844f78fea186aed92460d7f947c60328341bb
Author: Rickard Lindberg <rickard@rickardlindberg.me>
Date:   Sun Nov 2 10:34:34 2025 +0100

    Revise

diff --git a/posts/2025/10/19/newsletter-september/post.md b/posts/2025/10/19/newsletter-september/post.md
index 526db37..a5f56b3 100644
--- a/posts/2025/10/19/newsletter-september/post.md
+++ b/posts/2025/10/19/newsletter-september/post.md
@@ -18,11 +18,11 @@ Instead they can target a higher-level platform.
 
 I remember reading about [Heroku](https://en.wikipedia.org/wiki/Heroku) many
 years ago. With it, people were able to deploy their Ruby on Rails (and perhaps
-other frameworks) applications without any knowledge of web servers or
-infrastructure. Heroku raised the abstraction and made it possible for more
-people to put things in production. Of course that comes at a cost of less
-flexibility. In some situations that is not worth it. But in other situations
-it makes things so much easier.
+other) applications without any knowledge of web servers or infrastructure.
+Heroku raised the abstraction and made it possible for more people to put
+things in production. Of course that comes at a cost of less flexibility. In
+some situations that is not worth it. But in other situations it makes things
+so much easier.
 
 The Heroku approach seemed to have gone out of style for a while. But now it
 seems to be popular again under the name of *Platform Engineering*. I look

commit 71e69fb1a3ecba5c577769633d10c076685b0579
Author: Rickard Lindberg <rickard@rickardlindberg.me>
Date:   Sun Nov 2 10:31:35 2025 +0100

    Newsletter september 2025.

diff --git a/posts/2025/10/19/newsletter-september/post.md b/posts/2025/10/19/newsletter-september/post.md
new file mode 100644
index 0000000..526db37
--- /dev/null
+++ b/posts/2025/10/19/newsletter-september/post.md
@@ -0,0 +1,29 @@
+---
+date: 2025-11-02 10:30:00
+title: Newsletter September 2025: Platform Engineering
+tags: newsletter
+---
+
+This month I discovered the term *Platform Engineering*. In particular, I
+watched [this video
+series](https://www.youtube.com/playlist?list=PLwLLcwQlnXBy0sfJHkZvomeH7EO4QU67h)
+from the *Modern Software Engineering* channel. I also found the article [What
+is platform
+engineering?](https://learn.microsoft.com/en-us/platform-engineering/what-is-platform-engineering)
+from Microsoft to provide a good description.
+
+I like the concept of platform engineering because it allows teams to take full
+responsibility for their software while not having to be operations experts.
+Instead they can target a higher-level platform.
+
+I remember reading about [Heroku](https://en.wikipedia.org/wiki/Heroku) many
+years ago. With it, people were able to deploy their Ruby on Rails (and perhaps
+other frameworks) applications without any knowledge of web servers or
+infrastructure. Heroku raised the abstraction and made it possible for more
+people to put things in production. Of course that comes at a cost of less
+flexibility. In some situations that is not worth it. But in other situations
+it makes things so much easier.
+
+The Heroku approach seemed to have gone out of style for a while. But now it
+seems to be popular again under the name of *Platform Engineering*. I look
+forward to following development in this space.

2025-09-06 13:23 Rickard pushed to blog

commit 95478c832e363d835ab891b3e41132b9d0379ded
Author: Rickard Lindberg <rickard@rickardlindberg.me>
Date:   Sat Sep 6 12:02:28 2025 +0200

    Newsletter August 2025

diff --git a/blog.py b/blog.py
index 8dd47b9..b10f4c0 100755
--- a/blog.py
+++ b/blog.py
@@ -514,6 +514,11 @@ class Post:
     def write(self, root, bibs, posts):
         output_dir = os.path.join(root, self.html_root())
         os.makedirs(output_dir, exist_ok=True)
+        for png in glob.glob(os.path.join(os.path.dirname(self.path), "*.png")):
+            shutil.copy(
+                src=png,
+                dst=os.path.join(output_dir, os.path.basename(png))
+            )
         with open(os.path.join(output_dir, self.html_name()), "w") as f:
             f.write(self.html_content(bibs, posts))
 
diff --git a/posts/2025/09/04/newsletter-august/garmin-overview.png b/posts/2025/09/04/newsletter-august/garmin-overview.png
new file mode 100644
index 0000000..2fe7f68
Binary files /dev/null and b/posts/2025/09/04/newsletter-august/garmin-overview.png differ
diff --git a/posts/2025/09/04/newsletter-august/garmin-run.png b/posts/2025/09/04/newsletter-august/garmin-run.png
new file mode 100644
index 0000000..2b39d43
Binary files /dev/null and b/posts/2025/09/04/newsletter-august/garmin-run.png differ
diff --git a/posts/2025/09/04/newsletter-august/garmin-strava.png b/posts/2025/09/04/newsletter-august/garmin-strava.png
new file mode 100644
index 0000000..9e729bd
Binary files /dev/null and b/posts/2025/09/04/newsletter-august/garmin-strava.png differ
diff --git a/posts/2025/09/04/newsletter-august/garmin-watch.png b/posts/2025/09/04/newsletter-august/garmin-watch.png
new file mode 100644
index 0000000..2e49eba
Binary files /dev/null and b/posts/2025/09/04/newsletter-august/garmin-watch.png differ
diff --git a/posts/2025/09/04/newsletter-august/post.md b/posts/2025/09/04/newsletter-august/post.md
new file mode 100644
index 0000000..a4e3220
--- /dev/null
+++ b/posts/2025/09/04/newsletter-august/post.md
@@ -0,0 +1,106 @@
+---
+date: 2025-09-06 13:14:00
+title: Newsletter August 2025: More Programming
+tags: newsletter,timeline
+---
+
+This month I've been programming on two hobby projects. I have made progress on
+both as well as enjoyed the craft of programming.
+
+## Garmin
+
+I record my runs with a Garmin watch and heart rate monitor.
+
+![Picture of my Garmin watch.](garmin-watch.png)
+
+I analyze the data they gather in the Garmin Connect and Strava apps.
+
+![Screenshots of Garmin Connect and Strava.](garmin-strava.png)
+
+This month I wanted to analyze if I have become faster over time given the same
+effort. For example, I wanted to know if my average pace at an effort of 135
+BPM in heart rate had increased or not.
+
+I looked at using Garmin Connect and Strava for this, but couldn't find a way
+to do it. I pay for Strava, but use the free version of Garmin Connect. I
+found that Garmin had recently launched a paid subscription called Garmin
+Connect+ that should, among other things, allow you to do more custom graphs.
+
+But I was not keen on paying for something that maybe supports what I want. And
+what about when I want to extract some other data from my runs, and Garmin
+doesn't support it? Why is it so difficult to analyze data that I own in a way
+that I want?
+
+That's when the familiar though of "How hard can it be to do myself?" hit me
+and I started researching. I tried to connect my Garmin watch to my computer.
+It showed up as a USB device. I looked through the files and found a folder
+with all my activities. There they were. These are the sources I would need to
+analyze my runs. In a file format called FIT.
+
+I started researching how to process FIT files. Eventually I found that Garmin
+has a Python SDK [garmin-fit-sdk](https://pypi.org/project/garmin-fit-sdk/).
+Nice!
+
+Once I figured out how to process the files (the most uncertain part of this
+project) it was just a matter of drawing some graphs I though. And it was, but
+as usual it takes more time than anticipated. But this time, not too long. So I
+managed to build something that serves my needs. Here is the main screen:
+
+![Screenshots of my Garmin app showing an overview of my
+runs.](garmin-overview.png)
+
+The top part shows an overview of all my runs.  My Garmin watch has limited
+memory, so only the most recent activities are stored. But because I have used
+the Garmin Connect app for a while, I had uploaded my activities there and was
+able to download them again and import into my application.
+
+The bottom part is that custom graph that I wanted. I think I can see a trend
+towards faster average paces. Nice! I can click on a specific run here and a
+different graph will open:
+
+![Screenshots of my Garmin app showing a specific run.](garmin-run.png)
+
+It shows the standard pace and heart rate graphs for a specific run.
+
+I have now stopped paying for Strava, and I think I will also leave their
+platform soon. For me, it has become more of a distraction than something that
+provides value.
+
+## Timeline
+
+This month I also did some more work on
+[Timeline](https://projects.rickardlindberg.me/timeline/). The new workflow
+that [my own code hosting
+platform](post:2025/05/02/newsletter-april-projects/post.md) provides with the
+addition of [building the Windows exe in
+Wine](post:2025/07/07/newsletter-july/post.md) is just wonderful. I make a
+change to the code, commit it, and push it. The push triggers a build of the
+project website and binaries. If the build succeeds, everything is published
+and the push commands finishes with a success code. I can share the new version
+instantly. If the build fails, nothing gets published and I have to fix the
+error found in the output of the push command.
+
+This month a request came in on the mailing list asking if event texts could be
+drawn outside the event box instead of inside. Here is what the tutorial
+timeline looks like today:
+
+![Screenshots of tutorial timeline with text drawn inside the event
+box.](timeline-text-inside.png)
+
+I thought this was an interesting problem to work on, so I had a look.
+Implementing this feature required extensive changes in the logic of how a
+timeline is drawn.  I spent quite a bit of time trying to understand the
+drawing code which I hadn't touched in years. I made many refactorings that I
+think made the code better in addition to supporting the new feature. Here is
+how it turned out:
+
+![Screenshots of tutorial timeline with text drawn outside the event
+box.](timeline-text-outside.png)
+
+In some timelines, this rendering works better, and there is now a setting in
+Timeline that allows you to choose which one you want.
+
+This work felt rewarding for many reasons. It was an example of a well
+functioning feedback loop involving a user. The feedback loop was shorter
+because of technical improvements in the code hosting platform. And I got do a
+fun programming task.
diff --git a/posts/2025/09/04/newsletter-august/timeline-text-inside.png b/posts/2025/09/04/newsletter-august/timeline-text-inside.png
new file mode 100644
index 0000000..93ec4ba
Binary files /dev/null and b/posts/2025/09/04/newsletter-august/timeline-text-inside.png differ
diff --git a/posts/2025/09/04/newsletter-august/timeline-text-outside.png b/posts/2025/09/04/newsletter-august/timeline-text-outside.png
new file mode 100644
index 0000000..9e41e48
Binary files /dev/null and b/posts/2025/09/04/newsletter-august/timeline-text-outside.png differ