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">></span> {
+ $dialSize
+ >dialSize { <span class="String">"</span><span class="String">1</span><span class="String">0</span><span class="String">0</span><span class="String">"</span> }
+ <span class="String">"</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"><</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">></span><span class="Escape">\</span><span class="Escape">n</span><span class="String">"</span>
+ <span class="String">"</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">"</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">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">"</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">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">"</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">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">"</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">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">"</span>
+ <span class="String">"</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">"</span> >
+ <span class="VariableName">x</span><span class="VariableName">s</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">"</span>
+ <span class="String">"</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">"</span> <span class="VariableName">x</span><span class="VariableName">s</span>.count <span class="String">"</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">"</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">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">"</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">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">"</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">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">"</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">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">"</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">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">"</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">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">"</span>
+ <span class="String">"</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"><</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">"</span> >
+ <span class="String">"</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"><</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">"</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">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">"</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">"</span> <dialSize <span class="String">"</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">"</span>
+ <span class="String">"</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">"</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"> </span><span class="String">1</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</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">"</span>
+ < <span class="String">"</span><span class="String">}</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">"</span>
+ <span class="String">"</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">"</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"> </span><span class="String">1</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</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">"</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"> </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">"</span>
+ < <span class="String">"</span><span class="String">}</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">"</span>
+ <span class="String">"</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">"</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">"</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">"</span>
+ <span class="String">"</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">"</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">"</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">"</span>
+ <span class="String">"</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">"</span>
+ < <span class="String">"</span><span class="String">}</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">"</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">></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">></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">></span> {
+ <span class="String">"</span><span class="String">{</span><span class="String">"</span> <dialSize <span class="String">"</span><span class="String">-</span><span class="String">1</span><span class="String">,</span><span class="String"> </span><span class="String">"</span> <span class="VariableName">x</span> <span class="String">"</span><span class="String">%</span><span class="String">"</span> <dialSize <span class="String">"</span><span class="String">,</span><span class="String"> </span><span class="String">"</span> <span class="VariableName">x</span> <span class="String">"</span><span class="String">/</span><span class="String">"</span> <dialSize <span class="String">"</span><span class="String">}</span><span class="String">,</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">"</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">></span> {
+ <span class="String">"</span><span class="String">{</span><span class="String">1</span><span class="String">,</span><span class="String"> </span><span class="String">"</span> <span class="VariableName">x</span> <span class="String">"</span><span class="String">%</span><span class="String">"</span> <dialSize <span class="String">"</span><span class="String">,</span><span class="String"> </span><span class="String">"</span> <span class="VariableName">x</span> <span class="String">"</span><span class="String">/</span><span class="String">"</span> <dialSize <span class="String">"</span><span class="String">}</span><span class="String">,</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">"</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"><</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">></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<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<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">"</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">"</span>, times_ended_at_zero);
+ printf(<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"> </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">"</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 > <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">></span> {
+ <span class="String">"</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"><</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">></span><span class="Escape">\</span><span class="Escape">n</span><span class="String">"</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">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">"</span> >
+ <span class="String">"</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">"</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">"</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">"</span> <span class="VariableName">x</span><span class="VariableName">s</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">"</span>
+ <span class="String">"</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">"</span>
+ < <span class="String">"</span><span class="String">}</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">"</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">></span> { <span class="String">"</span><span class="String"> </span><span class="String">+</span><span class="String"> </span><span class="String">"</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">></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">></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">></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">></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">></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">></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">></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">></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">></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">></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">></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">></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">></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">></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">></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">></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">></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">></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">&</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">></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">></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">&</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">></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">></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">&</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">></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">></span> { <span class="VariableName">x</span> };
+<span class="RuleName">s</span><span class="RuleName">i</span><span class="RuleName">x</span> = <span class="Reserved">&</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">></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">></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">&</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">></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">></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">&</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">></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">></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">&</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">></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">></span> { <span class="VariableName">x</span> };
+<span class="RuleName">t</span><span class="RuleName">w</span><span class="RuleName">o</span> = <span class="Reserved">&</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">></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">></span> { <span class="VariableName">x</span> };
+<span class="RuleName">o</span><span class="RuleName">n</span><span class="RuleName">e</span> = <span class="Reserved">&</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">></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">></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"><</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">></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">"</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">"</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">></span> {
+ $rowCount
+ $colCount
+ <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">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">"</span> <rowCount <span class="String">"</span><span class="String">]</span><span class="String">[</span><span class="String">"</span> <colCount <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">"</span> >
+ <span class="VariableName">x</span><span class="VariableName">s</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">"</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">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">"</span> <rowCount <span class="String">"</span><span class="String">]</span><span class="String">[</span><span class="String">"</span> <colCount <span class="String">"</span><span class="String">]</span><span class="String">;</span><span class="Escape">\</span><span class="Escape">n</span><span class="String">"</span>
+ >rowCount { W[1] }
+ >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">></span> {
+ #inc(W[1] 1)
+ #max(W[2] <span class="VariableName">x</span><span class="VariableName">s</span>.len)
+ <span class="String">"</span><span class="String">{</span><span class="String">"</span> <span class="VariableName">x</span><span class="VariableName">s</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">"</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->used > <span class="String">0</span>);
+ state = fringe->states[<span class="String">0</span>];
+ fringe->used--;
+ <span class="Reserved">f</span><span class="Reserved">o</span><span class="Reserved">r</span> (i=<span class="String">0</span>; i<fringe->used; i++) {
+ fringe->states[i] = fringe->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.
+
+
+
+I analyze the data they gather in the Garmin Connect and Strava apps.
+
+
+
+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:
+
+
+
+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:
+
+
+
+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:
+
+
+
+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:
+
+
+
+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