<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Abdul Rahman Sibahi</title>
    <subtitle>Musings</subtitle>
    <link rel="self" type="application/atom+xml" href="https://ar-ms.me/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://ar-ms.me/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-04-01T00:00:00+00:00</updated>
    <id>https://ar-ms.me/atom.xml</id>
    <entry xml:lang="en">
        <title>Adding WASM Plugins to Your App</title>
        <published>2026-04-01T00:00:00+00:00</published>
        <updated>2026-04-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/thoughts/adding-wasm-plugins-to-your-app/"/>
        <id>https://ar-ms.me/thoughts/adding-wasm-plugins-to-your-app/</id>
        
        <content type="html" xml:base="https://ar-ms.me/thoughts/adding-wasm-plugins-to-your-app/">&lt;p&gt;In the past few days I have making a number of small improvements to this website.
For example, I used my &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;kashida&quot;&gt;&lt;code&gt;kashida&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; rust crate, compiled to WASM, to properly justify the Arabic poetry in my &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;nashd-suri-jadid&#x2F;&quot;&gt;previous&lt;&#x2F;a&gt; &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;nashid-suri&#x2F;&quot;&gt;two articles&lt;&#x2F;a&gt;, with a small JS shim.&lt;&#x2F;p&gt;
&lt;p&gt;When I went to share these articles on social media, I realized I needed &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Open_Graph_protocol&quot;&gt;OpenGraph&lt;&#x2F;a&gt; thingies to make the link more palatable looking.
Adding &lt;code&gt;og:site_name&lt;&#x2F;code&gt; and &lt;code&gt;og:title&lt;&#x2F;code&gt; is simple enough, but what to do about images?
For the time being, I decided to use, for all the website, &lt;a href=&quot;&#x2F;flag.jpg&quot;&gt;this image&lt;&#x2F;a&gt; of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;July_2025_Damascus_airstrikes&quot;&gt;torn Syrian flag&lt;&#x2F;a&gt;.
Not the most relevant photo most of the time, to be honest.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zola.discourse.group&#x2F;t&#x2F;wasm-extensions&#x2F;2921&#x2F;3&quot;&gt;On the Zola forums&lt;&#x2F;a&gt;, I made a proposal for wasm plugins.
There is no approval yet, but I decided to try my hand at it anyway.
Worst case scenario nothing gets upstreamed and I end up with a nice article out of it.&lt;&#x2F;p&gt;
&lt;p&gt;To be clear, I am writing this article as I am thinking about the problem and experimenting with it.
If it feels and reads like an unorganized stream of thoughts, that is because it is.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;passing-data&quot;&gt;Passing Data&lt;&#x2F;h2&gt;
&lt;p&gt;The first, and most important, problem you face, I think, is the problem of passing arbitrary data (that go beyond a simple integers and floats) between Host and Plugin.
The problem of wiring WASM functions to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;keats.github.io&#x2F;tera&#x2F;docs&#x2F;&quot;&gt;Tera&lt;&#x2F;a&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-tera-1&quot;&gt;&lt;a href=&quot;#fn-tera&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; functions is something I will worry about later.&lt;&#x2F;p&gt;
&lt;p&gt;The Plugin does not have access to Host memory, so to send data, the Host needs to allocate the bytes in the Plugin&#x27;s memory.
However, the Host has no idea how the Plugin manages its memory, and does not know which sections are used and which are not.&lt;&#x2F;p&gt;
&lt;p&gt;So you need to define a calling convention, an ABI.
How about that.
Luckily I am not the first person to think of using WASM for plugins.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;frameworks-components&quot;&gt;Frameworks? Components?&lt;&#x2F;h3&gt;
&lt;p&gt;There is plenty of plugin frameworks that one can simply just .. use.
The one that always bubbles up in search results is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;extism.org&quot;&gt;Extism&lt;&#x2F;a&gt;.
It does handle a lot more than &quot;passing a stream of bytes&quot; like, say, giving shape to these bytes.
But it still feels like a lot of ceremony for what is essentially a simple problem.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;component-model.bytecodealliance.org&quot;&gt;Component Model&lt;&#x2F;a&gt; is also something that comes up a lot in research, and it is also, I believe, a lot of ceremony for no real benefit.
The plugins don&#x27;t even need normal WASI.
Not to mention that the Component Model is still in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;webassembly.org&#x2F;features&#x2F;&quot;&gt;proposal status&lt;&#x2F;a&gt; for WebAssembly features.
Outside of Rust, Wasmtime, and maybe Mozilla (admittedly some of the biggest players) nobody else seems to care.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;typst&quot;&gt;Typst&lt;&#x2F;h3&gt;
&lt;p&gt;Typst has solved this problem without too much ceremony.
It has a very small and minimal &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;typst.app&#x2F;docs&#x2F;reference&#x2F;foundations&#x2F;plugin&#x2F;&quot;&gt;plugin protocol&lt;&#x2F;a&gt;.
It requires &lt;em&gt;some&lt;&#x2F;em&gt; ceremony from the plugin authors, but it is no more ceremony than loading the Extism SDK, for example.&lt;&#x2F;p&gt;
&lt;p&gt;The main restriction is that all the data is transferred in terms of &lt;code&gt;&amp;amp;[u8]&lt;&#x2F;code&gt;, a slice of bytes, and the parsing needs to be done inside the Plugin.
The return value is also always a &lt;code&gt;&amp;amp;[u8]&lt;&#x2F;code&gt; that is copied to the framework (which then one uses Typst std library to parse into shape.)&lt;&#x2F;p&gt;
&lt;p&gt;The main trick is this: exported functions take &lt;em&gt;lengths&lt;&#x2F;em&gt; of input (which, remember, are all slices of bytes).
The Plugin allocates a giant buffer enough for all the input, and calls the imported function &lt;code&gt;write_args_to_buffer&lt;&#x2F;code&gt;, splits and parses the buffer as needed, then, when done, puts all the results in another buffer, and passes its length and pointer to &lt;code&gt;send_result_to_host&lt;&#x2F;code&gt;, and Bob&#x27;s your uncle.
This is all neatly &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;typst-community&#x2F;wasm-minimal-protocol&quot;&gt;wrapped in a rust crate&lt;&#x2F;a&gt;, which is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git.sr.ht&#x2F;~asibahi&#x2F;kashida&#x2F;tree&#x2F;main&#x2F;item&#x2F;examples&#x2F;typst-plugin&quot;&gt;really simple to use&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If all else fails, I will just replicate this same protocol and fork &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;typst-community&#x2F;wasm-minimal-protocol&quot;&gt;&lt;code&gt;wasm-minimal-protocol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; to accommodate any changes I need.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;harfbuzz-and-rustybuzz&quot;&gt;HarfBuzz and RustyBuzz&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;harfbuzz&#x2F;rustybuzz&#x2F;pull&#x2F;122&quot;&gt;I did the WASM plugin implementation for &lt;code&gt;rustybuzz&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, with lots of help and helpful feedback from everyone.
It has been 2 years, though, so my memory is fuzzy.&lt;&#x2F;p&gt;
&lt;p&gt;The main constraint there is that I was implementing an existing API already implemented in HarfBuzz, which uses &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;bytecodealliance&#x2F;wasm-micro-runtime&quot;&gt;WAMR&lt;&#x2F;a&gt; as runtime.
&lt;code&gt;rustybuzz&lt;&#x2F;code&gt;, by suggestion of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;laurmaedje&quot;&gt;laurmaedje&lt;&#x2F;a&gt;, one of the lead Typst developers, uses &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;wasmi&quot;&gt;&lt;code&gt;wasmi&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, which has the side benefit of being compilable to wasm itself, and copies the much more popular Wasmtime api.&lt;&#x2F;p&gt;
&lt;p&gt;I could not for the life of me figure out how the HarfBuzz API solves this problem.
As far as I can tell, it was just some WAMR trick or magic.
Does not help that C++ is a black box to me.&lt;&#x2F;p&gt;
&lt;p&gt;The way I solved this in &lt;code&gt;rustybuzz&lt;&#x2F;code&gt; is a bit dirty.
To make sure that the memory is unused by the Plugin, I simply .. grew the memory by an additional page (or as many pages as needed), and then copied my data to that location, and gave the pointer back to the Plugin.&lt;&#x2F;p&gt;
&lt;p&gt;It is dirty and cheesy, to be honest.
Don&#x27;t do this.
I won&#x27;t do this.
But hey .. it worked!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;alloc&quot;&gt;&lt;code&gt;alloc&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The way I am going with this, at least at first, is to require the Plugin to export an &lt;code&gt;alloc&lt;&#x2F;code&gt; function.
It should take size as input, and return a pointer to the allocated slice, to which the Host copies what they need, and pass the pointer (and size)&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-cstring-1&quot;&gt;&lt;a href=&quot;#fn-cstring&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; back to the Plugin, somehow.&lt;&#x2F;p&gt;
&lt;p&gt;A simple example of said &lt;code&gt;alloc&lt;&#x2F;code&gt; function in Rust would be the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;use&lt;&#x2F;span&gt;&lt;span&gt; std&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	alloc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Layout&lt;&#x2F;span&gt;&lt;span&gt;, alloc &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;as&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; allocate, handle_alloc_error},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;NonNull&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-storage z-type&quot;&gt;pub extern&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;C&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span&gt; alloc(size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u32&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;NonNull&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; layout&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Layout&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from_size_align(size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;, std&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;mem&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;align_of&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;())&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; unsafe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; { allocate(layout) };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;NonNull&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(ptr)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap_or_else(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;||&lt;&#x2F;span&gt;&lt;span&gt; handle_alloc_error(layout))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Seems simple enough, probably not the most robust implementation, but it is a start.
There is no need for &lt;code&gt;free&lt;&#x2F;code&gt; or &lt;code&gt;dealloc&lt;&#x2F;code&gt;, as the Plugin owns the memory now.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;my-first-plugin-concatenating-strings&quot;&gt;My first plugin: Concatenating Strings&lt;&#x2F;h2&gt;
&lt;p&gt;With that decision out of the way, hopefully, one can focus on more important matters like actually creating plugins that &lt;em&gt;do&lt;&#x2F;em&gt; something.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s start by doing something that is trivial without plugins.
Take two strings from Host, concatenate them together and send the result back.
This requires no API from the Host, but it helps formulate how passing parameters will look like.&lt;&#x2F;p&gt;
&lt;p&gt;After a bit of experimentation, I ended up with this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;use&lt;&#x2F;span&gt;&lt;span&gt; std&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	alloc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Layout&lt;&#x2F;span&gt;&lt;span&gt;, alloc &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;as&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; allocate, handle_alloc_error},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;NonNull&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-storage z-type&quot;&gt;pub extern&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;C&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span&gt; alloc(size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u32&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;NonNull&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; layout&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Layout&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from_size_align(size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;, std&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;mem&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;align_of&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;())&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; unsafe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; { allocate(layout) };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;NonNull&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(ptr)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap_or_else(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;||&lt;&#x2F;span&gt;&lt;span&gt; handle_alloc_error(layout))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-storage z-type&quot;&gt;pub extern&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;C&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span&gt; concat&amp;lt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-lifetime&quot;&gt;a&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	lhs_size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;NonNull&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	rhs_size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	rhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;NonNull&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	out&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;NonNull&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt; -&amp;gt; u32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-option&quot;&gt;Some&lt;&#x2F;span&gt;&lt;span&gt;(lhs),&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-option&quot;&gt; Some&lt;&#x2F;span&gt;&lt;span&gt;(rhs))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (lhs, rhs)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;	};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;	let mut&lt;&#x2F;span&gt;&lt;span&gt; lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; non_null_to_str(lhs, lhs_size);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; rhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; non_null_to_str(rhs, rhs_size);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;push_str(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;rhs);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;shrink_to_fit();&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; to get rid of excess capacity;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; (ptr, length, _)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;into_raw_parts();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	*&lt;&#x2F;span&gt;&lt;span&gt;out&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;NonNull&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(ptr);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span&gt; length&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u32&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; The Unsafe functions could be provided by a crate or wrapped in a proc macro.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; non_null_to_str&amp;lt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-lifetime&quot;&gt;a&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;NonNull&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;String&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;NonNull&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;slice_from_raw_parts(ptr, size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; unsafe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; { string&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;as_ref() };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;String&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from_utf8_lossy(string)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;into_owned()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that I have been writing a bunch of Zig for a while, so the code is somewhat Zig-brained.
It assumes the Host knows what they are doing and has not passed bad info.
Now to compile that into wasm.&lt;&#x2F;p&gt;
&lt;p&gt;The compilation is simple enough:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cargo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; build&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -r --target&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; wasm32-unknown-unknown&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;.. and fish it out of the &lt;code&gt;target&lt;&#x2F;code&gt; directory.
There are plenty of tools to interrogate &lt;code&gt;wasm&lt;&#x2F;code&gt; blobs, but I am settling for the stupid approach:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;use&lt;&#x2F;span&gt;&lt;span&gt; eyre&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;use&lt;&#x2F;span&gt;&lt;span&gt; wasmi&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Engine&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Module&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; main()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;lt;()&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; wasm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt; include_bytes!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;..&#x2F;scratch.wasm&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; engine&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Engine&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;default();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; module&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Module&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;engine, wasm)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;	println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;EXPORTS:&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span&gt; export&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; module&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;exports()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;filter(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ty()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;func()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;is_some()) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; export&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;name();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; func&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; export&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ty()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;func()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; params&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; func&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;params();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; results&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; func&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;results();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;		println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{name}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;params: {params:?}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;results: {results:?}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type z-result&quot;&gt;	Ok&lt;&#x2F;span&gt;&lt;span&gt;(())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;.. which prints out .. nothing.
Oh I forget to add &lt;code&gt;no_mangle&lt;&#x2F;code&gt; above exported functions, silly me.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;#[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;unsafe&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;(no_mangle)]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; so small, so powerful&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and it now prints this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EXPORTS:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	alloc	params: [I32]	results: [I32]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	concat	params: [I32, I32, I32, I32, I32]	results: [I32]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Success!!
Now onto using it.
This is a bit longwinded.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;use&lt;&#x2F;span&gt;&lt;span&gt; eyre&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;use&lt;&#x2F;span&gt;&lt;span&gt; wasmi&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Engine&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Linker&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Module&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Store&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; main()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;lt;()&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; wasm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt; include_bytes!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;..&#x2F;concat_plugin.wasm&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; engine&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Engine&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;default();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; module&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Module&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;engine, wasm)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;	let mut&lt;&#x2F;span&gt;&lt;span&gt; store&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Store&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;engine, ());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; linker&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Linker&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;()&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;engine);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; linker&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;instantiate_and_start(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; store,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;module)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Get exported functions.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; alloc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_typed_func&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;store,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;alloc&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; concat&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_typed_func&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u32&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;store,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;concat&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Strings to concat&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;String&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;Hello &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; rhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;String&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;Wasm.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; allocate them in Plugin Memory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; lhs_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; alloc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;call(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; store, lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;len()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u32&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; rhs_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; alloc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;call(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; store, rhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;len()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u32&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_memory(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;store,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;memory&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; memory_data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;data_mut(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; store);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		memory_data[lhs_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-keyword z-operator&quot;&gt; usize..&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;len()]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;copy_from_slice(lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;as_bytes());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		memory_data[rhs_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-keyword z-operator&quot;&gt; usize..&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;rhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;len()]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;copy_from_slice(rhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;as_bytes());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; value doesn&amp;#39;t matter does it? This is a pointer to a pointer.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; out_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; alloc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;call(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; store, size_of&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u32&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; do the thing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; result_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; concat&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;call(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; store,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		(lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;len()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u32&lt;&#x2F;span&gt;&lt;span&gt;, lhs_ptr, rhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;len()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u32&lt;&#x2F;span&gt;&lt;span&gt;, rhs_ptr, out_ptr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; out_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;data(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;store)[out_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-keyword z-operator&quot;&gt; usize..&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;size_of&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;()]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;try_into()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; out_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-entity z-name z-type z-numeric z-keyword z-operator&quot;&gt; = u32::&lt;&#x2F;span&gt;&lt;span&gt;from_le_bytes(out_ptr)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; output&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;data(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;store)[out_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;result_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; output&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;String&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from_utf8_lossy(output);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;	println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{output}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Hello Wasm.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type z-result&quot;&gt;	Ok&lt;&#x2F;span&gt;&lt;span&gt;(())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;IT PRINTS!&lt;&#x2F;p&gt;
&lt;p&gt;Obviously a lot of this is just insane boilerplate, but onwards I persist.
It outputs correctly and that is all that matters.&lt;&#x2F;p&gt;
&lt;p&gt;The casting between &lt;code&gt;u32&lt;&#x2F;code&gt; and &lt;code&gt;usize&lt;&#x2F;code&gt; is because the Plugin works in a 32 bit environment, so its pointers are &lt;code&gt;u32&lt;&#x2F;code&gt;.
But indices into things in Rust is &lt;code&gt;usize&lt;&#x2F;code&gt;, hence the small friction.&lt;&#x2F;p&gt;
&lt;p&gt;One thing to note here is that there is nothing from Host side that prevents the function to return both the pointer and the length.
WebAssembly, after all, allows multiple returns.
However, as far as I can tell, there is no easy way in Rust to compile a function with multiple returns.
(And the fact is, even in languages with multiple returns, like Odin, it compiles them as out parameters like I did here.)&lt;&#x2F;p&gt;
&lt;p&gt;However, the Plugin &lt;em&gt;could&lt;&#x2F;em&gt; return either a pointer to a struct that has a length and a pointer (which is the sane option, to be honest), or return a &lt;code&gt;u64&lt;&#x2F;code&gt; that is a &lt;code&gt;u32&lt;&#x2F;code&gt; size and &lt;code&gt;u32&lt;&#x2F;code&gt; pointer address stuck side by side.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;second-plugin-create-an-image-and-save-it&quot;&gt;Second Plugin. Create an Image and Save it&lt;&#x2F;h2&gt;
&lt;p&gt;With no WASI, I hear you ask, how will you save an image?
Simple: have the Host export a function (&lt;code&gt;save_file&lt;&#x2F;code&gt;) where it takes a byte stream and returns a file path, which the Plugin can pass back to the Host to embed in the HTML template.
This was all motivated by OpenGraph images, wasn&#x27;t it?&lt;&#x2F;p&gt;
&lt;p&gt;Now, laying out what specifically happens in that image is beyond the scope of this particular section.
Instead, we can have the exported function, called &lt;code&gt;create_image&lt;&#x2F;code&gt; or whatever, take a color, and it creates a small 64x64 image of that color, uses &lt;code&gt;save_file&lt;&#x2F;code&gt; to save it, and then &lt;code&gt;create_image&lt;&#x2F;code&gt; returns the path.
To make the API slightly simpler, I will pass strings and paths around as null-terminated strings, so just a pointer.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;host-side&quot;&gt;Host Side&lt;&#x2F;h3&gt;
&lt;p&gt;Here is the &lt;code&gt;save_file&lt;&#x2F;code&gt; function that Plugin will be able to import.
Note that &lt;code&gt;Caller&lt;&#x2F;code&gt; is an implementation detail for &lt;code&gt;wasmi&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; save_file(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	caller&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Caller&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;()&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	file_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	file_size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt; -&amp;gt; u32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	save_file_impl(caller, name, file_ptr, file_size)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;map(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;into())&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap_or_default()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; save_file_impl(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;	mut&lt;&#x2F;span&gt;&lt;span&gt; caller&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Caller&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;()&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; null terminated&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	file_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	file_size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;NonZero&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Get the necessary exports out&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; caller&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_export(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;memory&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?.&lt;&#x2F;span&gt;&lt;span&gt;into_memory()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; alloc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; caller&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_export(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;alloc&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?.&lt;&#x2F;span&gt;&lt;span&gt;into_func()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;data(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;caller);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; name can be whatever. It can even be randomly genrated because we are not in WASM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; dir_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;PathBuf&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;plugin_images&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; not very robust error handling&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	_&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;fs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;create_dir(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;dir_path);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;CStr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from_bytes_until_nul(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;data[name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-keyword z-operator&quot;&gt; usize..&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ok()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?.&lt;&#x2F;span&gt;&lt;span&gt;to_str()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ok()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; straight forward writing the file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; file_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dir_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;join(name);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; file_data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;data[file_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-keyword z-operator&quot;&gt; usize..&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;file_size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;	let mut&lt;&#x2F;span&gt;&lt;span&gt; file&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;fs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;File&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;create(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;file_path)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ok()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; _written&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; file&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;write(file_data)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ok()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; now that&amp;#39;s done, return a the file path to the caller.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; trading the API simplicity of null terminated strings with code complexity&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; file_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; file_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;as_os_str()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;as_encoded_bytes();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; file_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;CString&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(file_path)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ok()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; file_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; file_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;as_bytes_with_nul();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;	let mut&lt;&#x2F;span&gt;&lt;span&gt; func_outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Val&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	alloc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;call(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; caller,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[Val&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;I32(file_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;len()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; i32&lt;&#x2F;span&gt;&lt;span&gt;)],&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; func_outputs)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ok()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-entity z-name z-type z-option&quot;&gt;	let Some&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Val&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;I32(return_pointer))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; func_outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;first()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-entity z-name z-type z-option&quot;&gt;		return None&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;	};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; return_pointer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = *&lt;&#x2F;span&gt;&lt;span&gt;return_pointer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u32&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; This silly dance to avoid wriitng into address 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; return_value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;NonZeroU32&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(return_pointer)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; write file_path into Plugin memory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;data_mut(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; caller);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	data[return_pointer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-keyword z-operator&quot;&gt; usize..&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;file_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;len()]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;copy_from_slice(file_path);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type z-option&quot;&gt;	Some&lt;&#x2F;span&gt;&lt;span&gt;(return_value)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And, back in &lt;code&gt;main&lt;&#x2F;code&gt;, add it to imports by calling &lt;code&gt;func_wrap&lt;&#x2F;code&gt; on &lt;code&gt;linker&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; linker&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Linker&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;()&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;engine);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;linker&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;func_wrap(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;scratch_env&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;save_file&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, save_file)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that &lt;code&gt;scratch_env&lt;&#x2F;code&gt; here can be anything the ABI author decides.
LLVM puts &lt;code&gt;env&lt;&#x2F;code&gt; as default value for imports, if I remember correctly.
This is something the Plugin author needs to be aware of.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;plugin-side&quot;&gt;Plugin side&lt;&#x2F;h3&gt;
&lt;p&gt;To import &lt;code&gt;save_file&lt;&#x2F;code&gt;, which the Plugin author knows is there because of the correct and up-to-date documentation, they do the following incantation.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;#[link(wasm_import_module &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;scratch_env&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;)]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; this name must be the same.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-storage z-type&quot;&gt;unsafe extern&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;C&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;	fn&lt;&#x2F;span&gt;&lt;span&gt; save_file(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;NonNull&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		file_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;NonNull&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		file_size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;NonNull&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and the function is available to use from within your Plugin, gated with &lt;code&gt;unsafe&lt;&#x2F;code&gt;, of course.
You can never have enough places where you write &lt;code&gt;unsafe&lt;&#x2F;code&gt; in Rust.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;create_image&lt;&#x2F;code&gt; itself is straightforward.
It even returns the same pointer given to it by &lt;code&gt;save_file&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;#[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;unsafe&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;(no_mangle)]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; don&amp;#39;t forget!!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-storage z-type&quot;&gt;pub extern&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;C&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span&gt; create_image(color&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u32&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;NonNull&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; first things first&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt; format!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{color:X}.png&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;CString&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from_str(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;name)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ok()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;NonNull&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;into_raw())&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;map(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;cast());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Rgba and RgbaImage from the `image` crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; color&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; color&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;to_le_bytes();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; color&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Rgba&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from(color);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;	let mut&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Cursor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(buffer);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; image&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;RgbaImage&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from_pixel(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 64&lt;&#x2F;span&gt;&lt;span&gt;, color);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	image&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;write_to(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; buffer, image&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;ImageFormat&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Png&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ok()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;	let mut&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;into_inner();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;as_mut_ptr();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;NonNull&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(ptr);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;	unsafe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; { save_file(name, ptr, buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;len()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;) }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;host-side-again&quot;&gt;Host side again&lt;&#x2F;h3&gt;
&lt;p&gt;All that&#x27;s left now is defining the new exported function and calling it.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; main()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;lt;()&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; wasm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt; include_bytes!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;..&#x2F;create_image.wasm&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; engine&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Engine&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;default();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; module&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Module&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;engine, wasm)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;	let mut&lt;&#x2F;span&gt;&lt;span&gt; store&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Store&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;engine, ());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;	let mut&lt;&#x2F;span&gt;&lt;span&gt; linker&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Linker&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;()&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;engine);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	linker&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;func_wrap(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;scratch_env&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;save_file&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, save_file)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; linker&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;instantiate_and_start(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; store,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;module)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_memory(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;store,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;memory&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Get exported functions.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; _alloc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_typed_func&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;store,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;alloc&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; create_image&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_typed_func&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;store,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;create_image&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; image_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; create_image&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;call(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; store,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0xFF0000FF&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; red&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; image_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;CStr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from_bytes_until_nul(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;data(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;store)[image_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-keyword z-operator&quot;&gt; usize..&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;	println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;image saved at {}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, image_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;to_string_lossy());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type z-result&quot;&gt;	Ok&lt;&#x2F;span&gt;&lt;span&gt;(())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And I run this, and it saves this glorious image right where I asked it to:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;adding-wasm-plugins-to-your-app&#x2F;FF0000FF.png&quot; alt=&quot;red square&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Yes it is a red square.
That is what it is asked to do.
However .. &lt;code&gt;main&lt;&#x2F;code&gt; above prints the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;image saved at&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;debugging&quot;&gt;Debugging&lt;&#x2F;h3&gt;
&lt;p&gt;No path given!
&lt;code&gt;create_image&lt;&#x2F;code&gt; actually returned (from its point of view, at least) a null pointer.
Obviously the image was created and saved, so the error must be within &lt;code&gt;save_file&lt;&#x2F;code&gt;.
Poking at it a bit, with good old debug printing, I found the error is in &lt;em&gt;this&lt;&#x2F;em&gt; part in &lt;code&gt;save_file&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; func_outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Val&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;alloc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;call(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; caller,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[Val&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;I32(file_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;len()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; i32&lt;&#x2F;span&gt;&lt;span&gt;)],&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; func_outputs)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ok()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Apparently that&#x27;s not the way this should be called, so I am confused.
I thought it would fill up the &lt;code&gt;func_outputs&lt;&#x2F;code&gt; buffer, but instead it is giving me an &lt;code&gt;encountered an incorrect number of results&lt;&#x2F;code&gt; error.
Hm. Time to read the documentation:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F; Calls the Wasm or host function with the given inputs.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F; The result is written back into the `outputs` buffer.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F; # Errors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F; - If the function returned a [`Error`].&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F; - If the types of the `inputs` do not match the expected types for the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;   function signature of `self`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F; - If the number of input values does not match the expected number of&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;   inputs required by the function signature of `self`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F; - If the number of output values does not match the expected number of&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;&#x2F;   outputs required by the function signature of `self`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So while that does say the &lt;code&gt;&amp;amp;mut [Val]&lt;&#x2F;code&gt; outputs parameter needs to have the correct number, it does not actually say how to use it.
The only version of this specific method being called in &lt;code&gt;wasmi&lt;&#x2F;code&gt; codebase is calling it is a &lt;code&gt;&amp;amp;mut []&lt;&#x2F;code&gt; which is not very helpful.&lt;&#x2F;p&gt;
&lt;p&gt;Anyhow, changing the first of the above to lines to&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; func_outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt; vec!&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Val&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;I32(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;alloc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;call(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; caller,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[Val&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;I32(file_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;len()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; i32&lt;&#x2F;span&gt;&lt;span&gt;)],&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; func_outputs)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ok()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and running the scratch repo again (this time changing the color to blue) gives a beautiful blue square similar to the previous red square and the following message:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;image saved at plugin_images&#x2F;FFFF0000.png&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;adding-wasm-plugins-to-your-app&#x2F;FFFF0000.png&quot; alt=&quot;blue square&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Maybe I should&#x27;ve used &lt;code&gt;to_be_bytes&lt;&#x2F;code&gt; instead of &lt;code&gt;to_le_bytes&lt;&#x2F;code&gt; to make it make more sense, but no matter.
The important thing is that it works.
Also, perhaps I could have arranged &lt;code&gt;save_file&lt;&#x2F;code&gt; better so it cannot fail after writing the file.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;tera&quot;&gt;Tera&lt;&#x2F;h2&gt;
&lt;p&gt;By now, a clear ABI has been established.
Data and functions are successfully shepherded back and forth between Host and Plugin.
Next on the menu is tying it to Tera.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-tera-2&quot;&gt;&lt;a href=&quot;#fn-tera&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;
I have almost no idea how to do that.&lt;&#x2F;p&gt;
&lt;p&gt;Browsing the Zola codebase, the main gateway seems to be a method called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;tera&#x2F;latest&#x2F;tera&#x2F;struct.Tera.html#method.register_function&quot;&gt;&lt;code&gt;register_function&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.
This method takes something which implements a trait called, appropriately enough, &lt;code&gt;Function&lt;&#x2F;code&gt;, which requires objects to implement a method with another appropriate name: &lt;code&gt;call&lt;&#x2F;code&gt;, that takes its inputs in the form of a &lt;code&gt;HashMap&amp;lt;String, Value&amp;gt;&lt;&#x2F;code&gt;.
Function parameters in Tera &lt;em&gt;must&lt;&#x2F;em&gt; have a name, while in Wasm land, they don&#x27;t.
First point of friction right there, and no I am not touching the component model.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;Value&lt;&#x2F;code&gt; in here is a little more interesting.
It is actually exported all the way over from &lt;code&gt;serde_json&lt;&#x2F;code&gt;, for some reason, and it is therefore a viable JSON &lt;code&gt;Value&lt;&#x2F;code&gt;.
Unsure yet how to bridge this back and forth, but only Plugin exported functions that are &lt;em&gt;not&lt;&#x2F;em&gt; &lt;code&gt;alloc&lt;&#x2F;code&gt; need to fit that mould.&lt;&#x2F;p&gt;
&lt;p&gt;It is more interesting right now to consider how the object that implements this trait looks like.
It needs to have some sort of reference to the &lt;code&gt;Module&lt;&#x2F;code&gt;, (or perhaps an instantiated &lt;code&gt;Module&lt;&#x2F;code&gt; in a &lt;code&gt;LazyLock&lt;&#x2F;code&gt;?) which it can call functions from.
Each instance of said object only needs concern itself with one, and only one, exported function.&lt;&#x2F;p&gt;
&lt;p&gt;The second immediate point of friction is how to map the &lt;em&gt;types&lt;&#x2F;em&gt; from one function model to the other.
Both models allow integers, floats, and strings, pretty easily, but how to actually know which parameter is which type, considering they all look the same (&lt;code&gt;i32&lt;&#x2F;code&gt;) when inspected in Wasm?
The simplest approach to this is Typst&#x27;s: all parameters are all &lt;del&gt;strings&lt;&#x2F;del&gt; byte slices all the time and if the Host needs to pass numbers they pass them as &lt;del&gt;strings&lt;&#x2F;del&gt; byte slices and let the Plugin worry about parsing them.&lt;&#x2F;p&gt;
&lt;p&gt;Return types are a bit simpler: they can always be &lt;del&gt;strings&lt;&#x2F;del&gt; byte slices.
This plugin system is going to produce text, so no need to overthink this &lt;em&gt;too&lt;&#x2F;em&gt; much.
But knowing success from failure is a bit trickier: so far, I signaled failure by returning &lt;code&gt;0&lt;&#x2F;code&gt;, and success by returning any other number (which is usually a valid pointer).
There is no space for error messages should that be needed.
In which case, I could copy Typst&#x27;s approach here again, and provide a &lt;code&gt;send_result_to_host&lt;&#x2F;code&gt; function that can either contain an arbitrary slice of bytes or an error message.&lt;&#x2F;p&gt;
&lt;p&gt;This, coming to think of it, sounds a lot like &lt;code&gt;save_file&lt;&#x2F;code&gt; already.
Maybe I could have the Host define a function to report error strings that is checked when return value is &lt;code&gt;0&lt;&#x2F;code&gt;?
Tricky.&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, enough of this stream of thought. The crowds want to see some &lt;em&gt;code&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;say-hello-randomly&quot;&gt;Say Hello randomly&lt;&#x2F;h3&gt;
&lt;p&gt;I have never used Tera before, but it seems straightforward enough.
First let me define the terribly inefficient function I would like to call from templates:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; get_random_name()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;String&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;	let mut&lt;&#x2F;span&gt;&lt;span&gt; names&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;HashSet&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	names&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;insert(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;Abdul-Karim&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	names&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;insert(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;Faisal&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	names&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;insert(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;Juman&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	names&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;into_iter()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;next()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;to_owned()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Who said there is no randomness in the standard library?
Implementing the &lt;code&gt;tera::Function&lt;&#x2F;code&gt; trait is similarly straightforward.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;GetRandom&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Function&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;GetRandom&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;	fn&lt;&#x2F;span&gt;&lt;span&gt; call(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-self&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		_&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;HashMap&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt;, tera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Value&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; tera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;tera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; get_random_name();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type z-result&quot;&gt;		Ok&lt;&#x2F;span&gt;&lt;span&gt;(tera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;String(ret))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There is no use for any arguments being passed, so &lt;code&gt;args&lt;&#x2F;code&gt; is discarded. Note that there is no way to pass &lt;em&gt;positional&lt;&#x2F;em&gt; arguments, here, which does make the WASM-Tera interop slightly more difficult.
Maybe if instead of &lt;code&gt;HashMap&lt;&#x2F;code&gt; there was some sort of ordered map instead, where the user can simply iterate over the hashmap to get arguments in order, regardless of the key value?
But I digress. Back to &lt;code&gt;main&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; main()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;lt;()&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;	let mut&lt;&#x2F;span&gt;&lt;span&gt; tera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;default();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; register our function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	tera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;register_function(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;random_name&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;GetRandom&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; call our function in the `hello` template&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	tera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;add_raw_template(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;hello&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt; concat!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;Hello {{  random_name() }}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; context&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Context&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; render `hello`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; rendered&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;render(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;hello&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;context)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;	println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{rendered}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type z-result&quot;&gt;	Ok&lt;&#x2F;span&gt;&lt;span&gt;(())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And .. that is it.
Run it and get &lt;code&gt;Hello, Abdul-Karim!&lt;&#x2F;code&gt;, or any of the other names, right into your terminal.
Coming to think of it, it is kinda funny that this is &lt;em&gt;not&lt;&#x2F;em&gt; the most convoluted &lt;code&gt;Hello World&lt;&#x2F;code&gt; in this article.&lt;&#x2F;p&gt;
&lt;p&gt;Well, the Tera section was easier and shorter than I expected.
Time to tie the knot, bridge the gap, mix metaphors.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;tying-the-two-threads&quot;&gt;Tying the Two Threads&lt;&#x2F;h2&gt;
&lt;p&gt;The tricky part is to know which parts of the Wasm Rube Goldberg machine to store references to.
Conferring with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;hikikomorphism.bsky.social&#x2F;post&#x2F;3lwamjk3pjk2x&quot;&gt;the ghost trapped in a jar&lt;&#x2F;a&gt;, which I am sure has done ample research on the problem, we came up with this struct:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;WasmFunction&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	store_memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Arc&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Mutex&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Store&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;()&amp;gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Memory&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	func&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Func&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;Arc&amp;lt;Mutex&amp;lt;(Store&amp;lt;()&amp;gt;, Memory)&amp;gt;&amp;gt;&lt;&#x2F;code&gt; type salad speaks for itself. &lt;code&gt;Func&lt;&#x2F;code&gt; is a &quot;type-erased&quot; version of the instantiated module&#x27;s functions.
As a matter of fact, it is the same type that &lt;code&gt;save_file&lt;&#x2F;code&gt;, way above, used to call &lt;code&gt;alloc&lt;&#x2F;code&gt;, which would explain the different calling syntax between it and ones in &lt;code&gt;main&lt;&#x2F;code&gt; (which operate on &lt;code&gt;TypedFunc&amp;lt;Params, Results&amp;gt;&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;This also has the potential drawback of eagerly compiling all plugins, instead of only lazily instantiating plugins the user uses.&lt;&#x2F;p&gt;
&lt;p&gt;Implementing &lt;code&gt;tera::Function&lt;&#x2F;code&gt; needs deciding on one element of the API.
Tera functions are named, with no positional arguments and no guaranteed order.
Wasm functions are only positional, and the arguments have no easy names to extract.
The gap &lt;em&gt;could&lt;&#x2F;em&gt; be bridged by requiring Plugins to provide some sort of &lt;code&gt;manifest.json&lt;&#x2F;code&gt; file that included exported function names and their parameters names.&lt;&#x2F;p&gt;
&lt;p&gt;The simplest way to do is simple generate names for the Wasm function&#x27;s parameters, based on their position.
So the first parameter would be &lt;code&gt;p0&lt;&#x2F;code&gt; (must start with a letter), second is &lt;code&gt;p1&lt;&#x2F;code&gt;, and so on.&lt;&#x2F;p&gt;
&lt;p&gt;Regarding the function&#x27;s types, I will kick this can down the road.
I &lt;em&gt;know&lt;&#x2F;em&gt; &lt;code&gt;create_image&lt;&#x2F;code&gt; specifically takes a &lt;code&gt;u32&lt;&#x2F;code&gt; integer, so I will just make that assumption.
If the API discussion decides &lt;del&gt;strings&lt;&#x2F;del&gt; byte slices all the time everywhere is the way to go, then the logic here will be different.
For example, creating a slice out of every pair of parameters or whatever, or just provide a manifest.&lt;&#x2F;p&gt;
&lt;p&gt;Without further ado, here is the implementation with comments.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span&gt; tera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Function&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;WasmFunction&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;	fn&lt;&#x2F;span&gt;&lt;span&gt; call(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-self&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;HashMap&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Value&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; tera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;		let mut&lt;&#x2F;span&gt;&lt;span&gt; sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-self&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;store_memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;lock()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; unused here, but you can get number and types of params from it&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; _func_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-self&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;func&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ty(sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0.&lt;&#x2F;span&gt;&lt;span&gt;as_context());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; hardcoded for `create_image`. Ideally this would be different&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-entity z-name z-type z-option&quot;&gt;		let Some&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;Number(color))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;p0&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-entity z-name z-type z-result&quot;&gt;			return Err&lt;&#x2F;span&gt;&lt;span&gt;(tera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;msg(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;Missing parameter&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;		};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; color&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; color&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;as_u64()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u32&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; the code from here is similar to `save_file`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;		let mut&lt;&#x2F;span&gt;&lt;span&gt; func_outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt; vec!&lt;&#x2F;span&gt;&lt;span&gt;[wasmi&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Val&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;I32(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language z-self&quot;&gt;		self&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;func&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;			.&lt;&#x2F;span&gt;&lt;span&gt;call(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;				sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0.&lt;&#x2F;span&gt;&lt;span&gt;as_context_mut(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;				&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[wasmi&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;Val&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;I32(color&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; i32&lt;&#x2F;span&gt;&lt;span&gt;)],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;				&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; func_outputs,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;			.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-entity z-name z-type z-option&quot;&gt;		let Some&lt;&#x2F;span&gt;&lt;span&gt;(wasmi&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Val&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;I32(image_path))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; func_outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;first()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;			unreachable!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;lots of handwaiving&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;		};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; and from here is similar to what was in `main`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; image_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = *&lt;&#x2F;span&gt;&lt;span&gt;image_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u32&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; image_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;CStr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from_bytes_until_nul(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;			&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1.&lt;&#x2F;span&gt;&lt;span&gt;data(sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0.&lt;&#x2F;span&gt;&lt;span&gt;as_context())[image_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-keyword z-operator&quot;&gt; usize..&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		.&lt;&#x2F;span&gt;&lt;span&gt;unwrap()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		.&lt;&#x2F;span&gt;&lt;span&gt;to_string_lossy();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type z-result&quot;&gt;		Ok&lt;&#x2F;span&gt;&lt;span&gt;(image_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;into())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that this is hardcoded for the same &lt;code&gt;create_image&lt;&#x2F;code&gt; module I created earlier, no recompilation necessary.
A correct implementation would be more .. I dunno .. correct.
This is but a proof of concept.&lt;&#x2F;p&gt;
&lt;p&gt;Adding Tera things to &lt;code&gt;main&lt;&#x2F;code&gt;, we now have this monstrosity:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; main()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;lt;()&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; wasm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt; include_bytes!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;..&#x2F;create_image.wasm&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; engine&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Engine&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;default();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; module&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Module&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;engine, wasm)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;	let mut&lt;&#x2F;span&gt;&lt;span&gt; store&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Store&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;engine, ());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;	let mut&lt;&#x2F;span&gt;&lt;span&gt; linker&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Linker&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;()&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;engine);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	linker&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;func_wrap(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;scratch_env&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;save_file&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, save_file&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;save_file)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; linker&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;instantiate_and_start(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; store,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;module)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_memory(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;store,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;memory&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Get exported functions.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; _alloc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_typed_func&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;store,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;alloc&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; create_image&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_typed_func&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;store,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;create_image&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Arc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(Mutex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new((store, memory)));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; tera_func&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;WasmFunction&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; { store_memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; state, func&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; create_image&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;func()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;clone() };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; from here on we do Tera things&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;	let mut&lt;&#x2F;span&gt;&lt;span&gt; tera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;default();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; register our function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	tera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;register_function(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;create_image&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, tera_func);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; call our function in the `hello` template&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; 4278255360 is 0xFF00FF00 . No hex, apparently.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	tera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;add_raw_template(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;hello&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt; concat!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;Hello {{ create_image(p0=4278255360) }}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; context&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Context&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; render `hello`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; rendered&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;render(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;hello&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;context)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;	println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{rendered}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type z-result&quot;&gt;	Ok&lt;&#x2F;span&gt;&lt;span&gt;(())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And this prints the follwing message and saves the following glorious green square:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Hello plugin_images&#x2F;FF00FF00.png&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;adding-wasm-plugins-to-your-app&#x2F;FF00FF00.png&quot; alt=&quot;green square&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This has been an overwhelming success.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;what-is-left&quot;&gt;What is Left&lt;&#x2F;h2&gt;
&lt;p&gt;This article has gone long enough.
Now all the hard work is done, all that remains is small details like the following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;How to organize the internal data structures.&lt;&#x2F;li&gt;
&lt;li&gt;Which layer of Zola to expose these functions.&lt;&#x2F;li&gt;
&lt;li&gt;Where to place plugin files in the Zola directory.&lt;&#x2F;li&gt;
&lt;li&gt;The full ABI: What types to force Plugin writers to use.&lt;&#x2F;li&gt;
&lt;li&gt;The full API: What functions are available to Plugin writers.&lt;&#x2F;li&gt;
&lt;li&gt;How to name the functions on Tera&#x27;s end so they do not overlap with other functions.&lt;&#x2F;li&gt;
&lt;li&gt;Whether Plugin authors should be left to their own devices or given a small crate to build on.&lt;&#x2F;li&gt;
&lt;li&gt;Whether this is wanted or not, and whether Lua or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rhai.rs&quot;&gt;Rhai&lt;&#x2F;a&gt; would be more preferable.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;All small details, insignificant in the grand scheme of things.
I expect this feature to get approved and built and upstreamed in no time.&lt;&#x2F;p&gt;
&lt;p&gt;I love Zola: it enabled me to start this site and get my voice out into the world. This makes it even better.&lt;&#x2F;p&gt;
&lt;p&gt;Until later.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-tera&quot;&gt;
&lt;p&gt;Zola&#x27;s templating engine. &lt;a href=&quot;#fr-tera-1&quot;&gt;↩&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-tera-2&quot;&gt;↩2&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-cstring&quot;&gt;
&lt;p&gt;Note that when passing &lt;em&gt;strings&lt;&#x2F;em&gt; back and forth, one often could just use C-strings and not need to pass a length.
That is not possible for arbitrary byte streams like images, but I will cross that bridge when I come to it. &lt;a href=&quot;#fr-cstring-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>النشيد السوري الجديد</title>
        <published>2026-03-18T00:00:00+00:00</published>
        <updated>2026-03-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/thoughts/nashd-suri-jadid/"/>
        <id>https://ar-ms.me/thoughts/nashd-suri-jadid/</id>
        
        <content type="html" xml:base="https://ar-ms.me/thoughts/nashd-suri-jadid/">&lt;p&gt;مؤخرا نشرت وزارة الثقافة السورية سبعة أناشيد مطروحة للملحنين والمغنين أن يختاروا واحدا منها ويلحنوه ليكون النشيد الوطني السوري القادم، بعد النشيد المغضوب (حماة الديار). فلذا رأيت أن أكتب مقارنة بسيطة بين هذه الأناشيد للممفاضلة ما بينها مع نشيد (في سبيل المجد).&lt;&#x2F;p&gt;
&lt;p&gt;وليس انتقادي هنا انتقادا للأشخاص، وإنما نقد أدبي بحت يعنى بالكلمة كما قرأتها، عليا بأن اطلاعي على الشعر والكتابة أوسع قليلا من سماع الأناشيد الحماسية على اليوتيوب.&lt;&#x2F;p&gt;
&lt;p&gt;باسم الله نبدأ&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lnshyd-l-wl&quot;&gt;النشيد الأول&lt;&#x2F;h2&gt;
&lt;p&gt;لكاتبه محمد أسعد عز الدين طالب&lt;&#x2F;p&gt;

&lt;table class=&quot;poem&quot; &gt;
	&lt;tr&gt;
				&lt;td&gt;بلادي بلادُ العُلا والإباء&lt;&#x2F;td&gt;
		
				&lt;td&gt;شآمُ المكارِمِ والكِبرياء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;إليها انتمائي بها خُيَلائي&lt;&#x2F;td&gt;
		
				&lt;td&gt;فداها دمائي وحُقّ الفداء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;لإرث الجدودِ ومجدٍ تليدِ&lt;&#x2F;td&gt;
		
				&lt;td&gt;لمثوى الشهيدِ ومسرى السماء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;حرامٌ علينا نزاعٌ يبُثُّ&lt;&#x2F;td&gt;
		
				&lt;td&gt;أصيل الإخاءِ ويُردي الرّجاء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;وعهداً سنحمي رُباكِ ونُعلي&lt;&#x2F;td&gt;
		
				&lt;td&gt;لِواكِ ونمضي نُعيدُ البِناء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;ونرعى كرامة شعب سقاها&lt;&#x2F;td&gt;
		
				&lt;td&gt;كِرامُ النّفوسِ زكيَّ الدٌماء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;وإنّا جحيمُ العُداةِ وحتفُ&lt;&#x2F;td&gt;
		
				&lt;td&gt;الطُّغاة لنا أبداً ما نشاء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;وخيرُ البُناةِ ونورُ الدّواةِ&lt;&#x2F;td&gt;
		
				&lt;td&gt;ملأنا الدّهور هُدىً وبهاء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;فدُمتِ شآمٌ عروسَ المعالي&lt;&#x2F;td&gt;
		
				&lt;td&gt;وفخر البيانِ ومغنى الضّياء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;ودام لراياتك الغُرَّ عِزٌّ&lt;&#x2F;td&gt;
		
				&lt;td&gt;يبزُّ الشموس سنا وعلاء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;هذا نشيد جميل يستقيم فيه المعنى والمبنى وسهولة الغناء والحفظ. لا غبار عليه. لكنه يطول قليلا فلعله يتخصر إلي نصفه أو ثلثيه. والتقليل فيه من الحشو، فما هو (نور الدواة)؟ وكيف (ملأنا الدهور هدى وبهاء)؟ &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;nashid-suri&#x2F;&quot;&gt;وما هي الشموس المذكورة&lt;&#x2F;a&gt; إلا تذكيرا بنشيد (حماة الديار) المكروه؟&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lnshyd-lthny&quot;&gt;النشيد الثاني&lt;&#x2F;h2&gt;
&lt;p&gt;لكاتبه تميم علي اليونس&lt;&#x2F;p&gt;

&lt;table class=&quot;poem&quot; &gt;
	&lt;tr&gt;
				&lt;td&gt;على هامِها قد رفعنا اللّواء&lt;&#x2F;td&gt;
		
				&lt;td&gt;ورمزَ الكرامة والكِبرِياء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;فقد خضٌبته جراح الشهيدِ&lt;&#x2F;td&gt;
		
				&lt;td&gt;وآمال شعبٍ نماها الإخاء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;تلاقت عليه نجومُ العُلا&lt;&#x2F;td&gt;
		
				&lt;td&gt;على ياسمينِ غدٍ والنّقاء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;وإرث الحضارة فيه بدا&lt;&#x2F;td&gt;
		
				&lt;td&gt;يشير لجيل الهدى والبناء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;فمن تُربها فاح عِطرُ الخلودِ&lt;&#x2F;td&gt;
		
				&lt;td&gt;ووشّت رباها زُهورُ الفِداء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;تتيهُ على زاهرات النجوم&lt;&#x2F;td&gt;
		
				&lt;td&gt;وحُقَّ اختيالٌ لشام الإباء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;فما أيأس الطامعين الغزاةَ&lt;&#x2F;td&gt;
		
				&lt;td&gt;وتلك قبورهمو في العراء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;فمن ذا يداني سُمُوَّ الشآمِ&lt;&#x2F;td&gt;
		
				&lt;td&gt;ومن ذا يحاول نيل السماء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;هذا النص من أضعف النصوص المختارة، لا شيء فيه مختص بسوريا والشام عن غيرها (سوى الياسمين..). والضمير في (شامها) عائد على من؟ مرة مذكر فيقول (وإرث الحضارة فيه) ومرة مؤنث فيقول (فمن تربها). والبيت الأخير يكرر الفكرة نفسها على الشطرين، كأننا والماء من حولنا قوم جلوس حولهم ماء.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lnshyd-lthlth&quot;&gt;النشيد الثالث&lt;&#x2F;h2&gt;
&lt;p&gt;لكاتبيه أنس الدغيم ومحمد ياسين الصالح&lt;&#x2F;p&gt;

&lt;table class=&quot;poem&quot; &gt;
	&lt;tr&gt;
				&lt;td&gt;بالله نُقسِمُ والعوالي تُقسَمُ&lt;&#x2F;td&gt;
		
				&lt;td&gt;والتينُ والزٌيتونُ فينا والدمُ&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;والأرضُ من أطرافها والأنجمُ&lt;&#x2F;td&gt;
		
				&lt;td&gt;أن لا يهونَ الحقُّ أو يَهِنَ اللواء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;كانوا وكنٌا .. والكواكبُ لا تُطالْ&lt;&#x2F;td&gt;
		
				&lt;td&gt;تاريخنا مجدٌ وحاضرنا جلالْ&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;إنا ولو ضجّت بنا حَر النّصالْ&lt;&#x2F;td&gt;
		
				&lt;td&gt;نبني ونُعلي في السما صرحَ البِناء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;لبِلادِنا دَينٌ علينا ظاهرُ&lt;&#x2F;td&gt;
		
				&lt;td&gt;أنْ لا يصولَ على ثراها غادرُ&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;ويذودَ عنها صَابرٌ ومُصابِرُ&lt;&#x2F;td&gt;
		
				&lt;td&gt;يفدونَ بالأرواحِ شامَ الأنبِياء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;يا سُورِيا يا موطنَ الحرفِ القديمْ&lt;&#x2F;td&gt;
		
				&lt;td&gt;يا غٌرَّةَ التاريخ والنصرِ المقيمْ&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;نفديكِ بالأرواحِ في وجهِ الغريمْ&lt;&#x2F;td&gt;
		
				&lt;td&gt;نسمو بأرضٍ ترتدي معنى السماءْ&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;واضح أن كاتبي هذا النشيد—وهما الشاعر المعروف أنس الدغيم ووزير الثقافة الحالي محمد الصالح—ملآ الفراغات به. إذ بنوه بطريقة هندسية مجدولة شملت كل المواضيع. ففيه الربط بالقرأن بذكر التين والزيتون، والربط ببقية الأديان بقولهم شام الأنبياء، وفيه الابتداء بالقسم مثل الأناشيد الجهادية، ووزنه وقافيته مناسبة للأناشيد الحماسية، وفيه ترميز لأوغاريت (الحرف القديم) وقولهم مهد الحضارات (غرة التاريخ)، وفيه الترميز إلى النشيد الحالي (أرض ترتدي معنى السماء).&lt;&#x2F;p&gt;
&lt;p&gt;لكن فيما بين هذه العناصر لا يستقيم التركيب ولا يخلو من الحشو. فمثلا قولهم (كانوا وكنا والكواكب لا تطال) .. ما معنى هذا؟ من هم الذين كانوا وكيف كانوا؟ وما هي الكواكب التي لا تطال؟ وما معنى أن الحاضر جلال؟&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-مجد-1&quot;&gt;&lt;a href=&quot;#fn-مجد&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; أظن أن البيت اللاحق (إنا ولو ضجّت بنا حَر النّصالْ) كْتب أولا ثم ملؤوا الفراغ ببيت ضعيف المعنى. ولعل لو هذين البيتي أزيلا لكان النشيد كله أقوى وآفضل.&lt;&#x2F;p&gt;
&lt;p&gt;تعديل لاحق: لعل يمكن استبدال الشطر (كانوا وكنا) بـ(لبلادنا عز رفيع لا يُطال) ويبقى الباقي كما هو.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lnshyd-lrb&quot;&gt;النشيد الرابع&lt;&#x2F;h2&gt;
&lt;p&gt;لكاتبه محمد المحمد محمد جاسم&lt;&#x2F;p&gt;

&lt;table class=&quot;poem&quot; &gt;
	&lt;tr&gt;
				&lt;td&gt;نحن سوريون من نسل الأُباة&lt;&#x2F;td&gt;
		
				&lt;td&gt;ولنا العلياءُ في ماضٍ وآتْ&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;كم قصمنا من ظلومٍ غاشمٍ&lt;&#x2F;td&gt;
		
				&lt;td&gt;ولنا عزمٌ يدكُّ الرّاسيات&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;لا نخافُ الموت لا نخشى الردى&lt;&#x2F;td&gt;
		
				&lt;td&gt;ليس منّا من يهابُ الحادثات&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;نطلب المجدَ ونعلو فوقَهُ&lt;&#x2F;td&gt;
		
				&lt;td&gt;وخُطانا واثقاتٌ ثابتات&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;في شآم العزِّ علّمنا الدُّنى&lt;&#x2F;td&gt;
		
				&lt;td&gt;أنّ أهل الحق هم أهل الثبات&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;من أتانا زائرا أهلا به&lt;&#x2F;td&gt;
		
				&lt;td&gt;إنّنا الأحرارُ أهل المكرُمات&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;غير أنّا للأعادي حتفُهم&lt;&#x2F;td&gt;
		
				&lt;td&gt;وقِراهُم من حِدادٍ مُرهَفات&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;نمنح السِّلم لمن سالمنا&lt;&#x2F;td&gt;
		
				&lt;td&gt;ونذيقُ المعتدي طعم المماتْ&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;يا بلادي عهدنا نقطعه&lt;&#x2F;td&gt;
		
				&lt;td&gt;أننا لا ننحني للنائبات&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;سوف نبقى أمّةً سوريّةً&lt;&#x2F;td&gt;
		
				&lt;td&gt;تجمع الكلَّ ولا ترضى الشتات&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;إن شكت حورانُ يوماٌ ظمأً&lt;&#x2F;td&gt;
		
				&lt;td&gt;هبّ يروي تُربَها نهر الفرات&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;قصيدة حميلة، توحي بالأناشيد الجهادية المشتهرة. لا أدري إن كان يصلح نشيدا وطنيا يردد في المدارس والمباريات أم قصيدة جميلة تقال في المناسبات. ولكن فيه مشاكل في الوزن والكتابة لا أدري كيف فاتت على كاتبه وعلى من اختاره.&lt;&#x2F;p&gt;
&lt;p&gt;البيت (نمنح السلم لمن سالمنا) مكسور الوزن ولا يستقيم مع بقية النشيد. فـ(سالمنا) فيها ثلاث حروف معلولة متتابعة وباقي القصيدة حرفان. ويزيد على ذلك أنه ركيك الصياغة (كأنه يقول «نطعميهم قتلة») ويكرر المعنى في البيتين السابقين. وحذفه أفضل.&lt;&#x2F;p&gt;
&lt;p&gt;والبيت الذي يليه (يا بلادي)، مع حسن معناه، إلا أنه مكسور الوزن أيضا، وضعيف البمنى حيث يتحول المتكلم في منتصف الشطر من المفرد إلى الجمع. ولعل لو استُبدل الشطر الأول بشيء مثل (شامَنا عهدٌ علينا قاطعٌ) يستقيم المعنى والمبنى.&lt;&#x2F;p&gt;
&lt;p&gt;أما البيت الأخير (إن شكت حوران يوما ظمأ) على أنه بيت القصيد، إلا أنه يعاني من كسر الوزن في «ظمأ» (ويستقيم الوزن إن قال: إن شكا الجولانُ يوما ظامئا). ويزيد على هذا أن المعنى يقصُر عن المطلوب. فيوحي كأن لا مورد في سوريا غير الفرات والجزيرة، وكأن حلب والساحل «خارج المعادلة». ولا أدري كيف يُصلَح.&lt;&#x2F;p&gt;
&lt;p&gt;وغير هذا فهو نشيد جميل ولعل الملحنين يظهرون فيه ما لا أراه.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-مرهف-1&quot;&gt;&lt;a href=&quot;#fn-مرهف&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lnshyd-lkhms&quot;&gt;النشيد الخامس&lt;&#x2F;h2&gt;
&lt;p&gt;لكاتبه عكرمة عدنان مصطفى&lt;&#x2F;p&gt;

&lt;table class=&quot;poem&quot; &gt;
	&lt;tr&gt;
				&lt;td&gt;نهضنا أُباةً لعزّ الوطن&lt;&#x2F;td&gt;
		
				&lt;td&gt;وردع الطغاة ووأد الفِتن&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;نجِدُّ نجِدُّ لنيل المنى&lt;&#x2F;td&gt;
		
				&lt;td&gt;فكل لها قد أعدّ الثمن&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;لنا كلّ يوم جديد مفيد&lt;&#x2F;td&gt;
		
				&lt;td&gt;وعهدا عن الحق أن لا نحيد&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;نصون العهودَ ونْعلي البنودَ&lt;&#x2F;td&gt;
		
				&lt;td&gt;ونرضي الجدود بعهد رشيد&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;نمانا يقينٌ فكنّا الأباة&lt;&#x2F;td&gt;
		
				&lt;td&gt;وعشنا لحفظ الحقوق الحُماة&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;نحقّق عدلا وننشر حبا&lt;&#x2F;td&gt;
		
				&lt;td&gt;فتصفو النفوس وتحلو الحياة&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;لئن راح إثرَ الشَّهيدِ الشّهيدْ&lt;&#x2F;td&gt;
		
				&lt;td&gt;تقدّم للنَّصرِ منَّا المزِيدْ&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;فنحيا السلامَ ونَهدي الأنامَ&lt;&#x2F;td&gt;
		
				&lt;td&gt;فيورقُ صخرٌ وتخضر بيد&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;لنا في ضمير الخلودِ رسالةْ&lt;&#x2F;td&gt;
		
				&lt;td&gt;بها الكون يهدَى فيحيا كماله&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;فليس لعزِّ الوجود سواها&lt;&#x2F;td&gt;
		
				&lt;td&gt;وليس سِوانا لحمل الرسالة&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;هذا جميل، ولكنه ليس فيه من سوريا والشام شيء ويصلح لأي بلد.&lt;&#x2F;p&gt;
&lt;p&gt;ولي عليه عدد من الملاحظات البسيطة: أولها على عبارة (نرضي الجدود)، فليست الغاية في دين الإسلام (وهو دين عموم الشعب) رضا الجدود، وإنما رضا الله عز وجل. ولعله إن قال (نرضي الإله) أو (نرضي الودود) لكان أفضل. وثانيها تكرار كلمتي (الأُباة) و(الرسالة) في موضعين متفرقين، مما يجعلهما أشبه بالحشو بعيدا عن التأكيد الحميل في (نجدٌ) و(الشهيد). وآخر الملاحظات موضوع نشر الحب وحلو الحياة، فأين الحماسة والفخر؟ هل الشعب شُعبة من الكشافة؟&lt;&#x2F;p&gt;
&lt;p&gt;ويجدر بالذكر هنا أن البيتين المطلعهما (لئن راح إثر الشهيد الشهيد) هما أجمل بيتين في هذه المجموعة كلها.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;lnshyd-lsds&quot;&gt;النشيد السادس&lt;&#x2F;h2&gt;
&lt;p&gt;لكاتبه إبراهيم سليم الحريري&lt;&#x2F;p&gt;

&lt;table class=&quot;poem&quot; &gt;
	&lt;tr&gt;
				&lt;td&gt;موئل للنور يا دار الخلود&lt;&#x2F;td&gt;
		
				&lt;td&gt;موطن يزهو على خفق البنود&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;دون مجد الشام عُقبان السما&lt;&#x2F;td&gt;
		
				&lt;td&gt;وشهيد ماجد تلوَ الشهيد&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;راية الأحرار نبراس الهدى&lt;&#x2F;td&gt;
		
				&lt;td&gt;آية تسمو على طول المدى&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;من عهود الفتح تعلو قاسيون&lt;&#x2F;td&gt;
		
				&lt;td&gt;ودماء الطهر لم تذهب سدى&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;نبتدي من يبتدينا بالسلام&lt;&#x2F;td&gt;
		
				&lt;td&gt;وعلى الباغين كالموت الزؤام&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;غصن زيتون مددنا للهدى&lt;&#x2F;td&gt;
		
				&lt;td&gt;ولكيد المعتدي سيف حسام&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;يا رمال البحر يا أرض الفرات&lt;&#x2F;td&gt;
		
				&lt;td&gt;كلنا نبت الربوع الطاهرات&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;من سهول الخصب من شم الجبال&lt;&#x2F;td&gt;
		
				&lt;td&gt;إخوة من مهدنا حتى الممات&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;

&lt;table class=&quot;poem&quot; &gt;
	&lt;tr&gt;
				&lt;td&gt;دمتِ أرض الماجدين&lt;&#x2F;td&gt;
		
				&lt;td&gt;للعلا دنيا ودين&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;دمت عزا لا يدانى&lt;&#x2F;td&gt;
		
				&lt;td&gt;باسم رب العالمين&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;تعديل (٢١-٢-٢٠٢٦): أغلب ظني أن الطباعة ظلمت الكلمة الأولى في هذا النشيد، إذ طُبعت «مؤئل»، وأخطأت في قراءتها. وأغلب ظني أنها (موئل) وليست (مؤثل) كما ظننت.&lt;&#x2F;p&gt;
&lt;p&gt;النشيد عشرة من عشرة ويكاد يكون أجمل السبعة عندي لولا السابع.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;lnshyd-lsb&quot;&gt;النشيد السابع&lt;&#x2F;h2&gt;
&lt;p&gt;لكاتبه أيمن الجبلي&lt;&#x2F;p&gt;

&lt;table class=&quot;poem&quot; name=&quot;7-1&quot;&gt;
	&lt;tr&gt;
				&lt;td&gt;جدّدي الأمجاد يا أرض الإباءِ&lt;&#x2F;td&gt;
		
				&lt;td&gt;واحملي للفجرِ آياتِ الضّياءِ&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;لا يموتُ الحقّ بل يحيا كريماً&lt;&#x2F;td&gt;
		
				&lt;td&gt;حين تسقيهِ دماءُ الشّهداءِ&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;

&lt;table class=&quot;poem&quot; name=&quot;7-2&quot;&gt;
	&lt;tr&gt;
				&lt;td&gt;كلٌُنا نفدي الوطنْ&lt;&#x2F;td&gt;
		
				&lt;td&gt;درعُهُ عند المِحن&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;عهدنا طولَ الزمن&lt;&#x2F;td&gt;
		
				&lt;td&gt;أن نسير إلى العلا&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;

&lt;table class=&quot;poem&quot; name=&quot;7-1&quot;&gt;
	&lt;tr&gt;
				&lt;td&gt;شعبنا حر ولا يحني الجباها&lt;&#x2F;td&gt;
		
				&lt;td&gt;صاغ من تاريخِهِ عِزًّا وجاها&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;غاية الأحرار أن يبقى عزيزا&lt;&#x2F;td&gt;
		
				&lt;td&gt;موطنٌ راياته تعلو سماها&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;

&lt;table class=&quot;poem&quot; name=&quot;7-2&quot;&gt;
	&lt;tr&gt;
				&lt;td&gt;كلٌُنا نفدي الوطنْ&lt;&#x2F;td&gt;
		
				&lt;td&gt;درعُهُ عند المِحن&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;عهدنا طولَ الزمن&lt;&#x2F;td&gt;
		
				&lt;td&gt;أن نسير إلى العلا&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;

&lt;table class=&quot;poem&quot; name=&quot;7-1&quot;&gt;
	&lt;tr&gt;
				&lt;td&gt;نحمل الأقلام في السِّلم سلاحا&lt;&#x2F;td&gt;
		
				&lt;td&gt;ثُمَّ تَغدو ساعة الحربِ رماحا&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;هكذا نبني بعِلمٍ ونِضالٍ&lt;&#x2F;td&gt;
		
				&lt;td&gt;وشبابٍ يملؤ الدنيا كفاحا&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;Ten out of ten no notes.&lt;&#x2F;p&gt;
&lt;p&gt;هذا هو آفضل المجموعة إطلاقا. (تعديل ٢١-٣-٢٠٢٦) أفضلها شعرا، لكن للأسف لا شيء فيه يخص الشام وسوريا تحديدا.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;fy-sbyl-lmjd-w-hm-ldyr&quot;&gt;(في سبيل المجد) و (حماة الديار)&lt;&#x2F;h2&gt;
&lt;p&gt;لا يخلو الكلام عن النشيد الوطني السوري عن نشيدين مهمين: أولهما هو النشيد الحالي المعروف بـ(حماة الديار) من تأليف الشاعر الكبير خليل مردم بك، وهو غير ارتباطه في أذهان الناس بحزب البعث الغاشم (رغم أنه نشيد سوريا منذ قبل الاستقلال) فهو نشيد ركيك ضعيف المعنى ما فيه إلا بيت واحد جميل. كتب فيه الشيخ علي الطنطاوي مقالة عام ١٩٤٦ &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;nashid-suri&#x2F;&quot;&gt;أعدت نشرها هنا&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;أما نشيد عمر أبو ريشة، &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=FYAcDDeUq0k&quot;&gt;في سبيل المجد والأوطان&lt;&#x2F;a&gt; فهو المنتشر والمشتهر بين الناس، والذي اعتمده عموم الناس نشيدا وطنيا بعد سقوط نظام البعث. وهو حقيقةً أجمل من الأناشيد المطروحة هنا، وينبغي في الاستفتاء إن حصل أن يجعله ضمن بقية الخيارات، إذ عليه اختيار أغلب الناس.&lt;&#x2F;p&gt;
&lt;p&gt;لكن النشيد لا يعجبني شخصيا، لسببين: أولهما أن النشيد ليس مخصصا بسوريا، وإنما بأوطان العرب عامة. يدل عليها قوله (في سبيل المجد والأوطان) وذكره أن الوطن هو مهبط الوحي (ومهبط الوحي عند المسلمين مكة والمدينة).&lt;&#x2F;p&gt;
&lt;p&gt;والثاني وهو الأشد عندي هي عبارة (إن عيش الذل والإرهاق أولى بالعبيد). من هم العبيد المقصودون؟ ألسنا السوريون نريد الحرية للشعوب كلها؟ أم ما هو لنا لا يصح لغيرنا؟&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ltrtyb&quot;&gt;الترتيب&lt;&#x2F;h2&gt;
&lt;p&gt;هذا ترتيبي ورأيي (تعديل ٢١-٣-٢٠٢٦)&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;موئل للنور (السادس)&lt;&#x2F;li&gt;
&lt;li&gt;جددي الأمجاد (السابع)&lt;&#x2F;li&gt;
&lt;li&gt;في سبيل المجد والأوطان&lt;&#x2F;li&gt;
&lt;li&gt;نحن سوريون (الرابع) (بعد تعديل الوزن المنكسر)&lt;&#x2F;li&gt;
&lt;li&gt;بالله نقسم (الثالث)&lt;&#x2F;li&gt;
&lt;li&gt;بلادي بلاد العلا (الأول)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;أما الباقون فلم يعجبوني. هذا والله أعلم&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-مجد&quot;&gt;
&lt;p&gt;يجدر بالذكر هنا آن عمي اسمه مجد وابنه اسمه جلال &lt;a href=&quot;#fr-مجد-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-مرهف&quot;&gt;
&lt;p&gt;من الطريف في النشيد تسمية السيوف بالمرهفات، ولعلها تكون نسبة لوزير الدفاع السوري الحالي مرهف أبو قصرة. &lt;a href=&quot;#fr-مرهف-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>النشيد السوري</title>
        <published>2026-03-17T00:00:00+00:00</published>
        <updated>2026-03-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            علي الطنطاوي
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/thoughts/nashid-suri/"/>
        <id>https://ar-ms.me/thoughts/nashid-suri/</id>
        
        <content type="html" xml:base="https://ar-ms.me/thoughts/nashid-suri/">&lt;blockquote&gt;
&lt;p&gt;كل ما يلي، بما فيها الهوامش، هي كلمات الشيخ علي الطنطاوي رحمه الله&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;كانت &lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-ناظم-1&quot;&gt;&lt;a href=&quot;#fn-ناظم&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; نشأتنا الأولى في عهد العثمانيين، وكانت لهم أناشيد يلقونها علينا باللسان التركي، إذ لم نكن نفهم معانيها الضخمة إلا بالترجمة، والترجمة لا تحمل دائما المعنى كله، فلقد كانت تهزنا ألحانها القوية المثيرة التي وضعت لتكون لمشاة الجيش قوة وعونا. وكنا إذا أنشدناها سائرين لا نستطيع أن نقف، وإذا تلوناها واقفين سرنا، وإن قرأناها قاعدين حركنا، من غير قصد منا، أيدينا وأرجلنا—وإنها لتحرك الحجر! ثم جاء عهد فيصل، وكان عهد ازدهار وحياة ونشاط بدا في كل شيء، فنشطت فيه الأناشيد العربية من عقالها. فترجمت أكثر الأناشيد التركية. فكان منها نشيد:&lt;&#x2F;p&gt;

&lt;table class=&quot;poem&quot; &gt;
	&lt;tr&gt;
				&lt;td&gt;أنا أمي لم تلدني&lt;&#x2F;td&gt;
		
				&lt;td&gt;لا للحرب العوان&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;بنغمته القوية، ولحنه العاصف—وكان أسْيَرَ أناشيد ذلك الزمان وأشهرها نشيد (أيها المولى العظيم)، الذي اعتبر النشيد الوطني السوري بل العربي، على هلهلة أسلوبه، وضعف معانيه، يليه في الشهرة والذيوع نشيد:&lt;&#x2F;p&gt;

&lt;table class=&quot;poem&quot; &gt;
	&lt;tr&gt;
				&lt;td&gt;أنت سوريا بلادي&lt;&#x2F;td&gt;
		
				&lt;td&gt;أنت عنوان الفخامة&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;كل من يأتيك يوماً&lt;&#x2F;td&gt;
		
				&lt;td&gt;طامعاً يلقى حمامه&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;لفخري بك البارودي، وهو نشيد ضعيف النسج، متهافت البناء، لكن معانيه في الذروة، واشتهرت أناشيد أخرى منها نشيد: (سيروا للمجد طراً سيروا للحرب، واستعيدوا بالمواضي دولة العرب)؛ ونشيد طلاب المدرسة الحربية: (نحن جند الله شبان البلاد)، وهو من خيرها لفظا ومعنى، وقد جمعها (الفلاح العربي) في رسالتيه المعروفتين في تلك الأيام.&lt;&#x2F;p&gt;
&lt;p&gt;ثم لما قضى الله قضاءه فينا في (ميسلون)، ووقعت الواقعة، ودخل العدو ديارنا، منعت هذه الأناشيد كلها، إلا أن تردد همساً، واشتهر يومئذ نشيد الأستاذ أديب التقي، رحمه الله: (في كل صوب حشدت عساكر مدججون)، الذي يصور فيه موقعة ميسلون، فكان ينشد وراء الأبواب، وحيث لا يسمعه الغاصبون، وهو نشيد جيّد، لحنه حزين مؤثر.&lt;&#x2F;p&gt;
&lt;p&gt;وانقطع بعد ذلك سيل الأناشيد الوطنية، حتى قدم علينا من العراق الكشافون في العهد الوطني الأول (سنة ١٩٣٦)، فأخذنا منهم نشيدين اشتهرا فينا وسارا بيننا، حتى كان الطفل الذي لم يتعلم بعد الكلام يدير في حلقه كلمات منهما، وهما (هذا الوطن حق له أن يفتدى بالدما والمهج) و(نحن كشاف العراق)، والشعر فيهما ليس بذاك، واللحن فظيع هو أشبه بصراخ لا دلالة له، منه باللحن الذي يؤثر في الأعصاب ويحرك القلب، ولكنها مع ذلك نشيدان قويان.&lt;&#x2F;p&gt;
&lt;p&gt;ووضعت على أثر ذلك أناشيد جيدة منها (نحن الشباب لنا الغد)، ولكن يعيب لحنه هذه الصيحة المؤنثة في آخر البيت، عند تكرار (نحن الشباب)، فهي صيحة عجوز ثاكل كان لها الأمس، لا صيحة شباب لهم الغد، والنشيد العظيم حقا في نظمه ولحنه، ولفظه ومعناه، نشيد (موطني) لفقيد الشعر إبراهيم طوقان—رحمه الله—ومن أجودها لحنا نشيد الأستاذ حسني كنعان: (أيها الكشاف بادر وارتق أوج العلا)؛ ولحنه نموذج للألحان الحماسية—نسجل هذا للتاريخ!&lt;&#x2F;p&gt;
&lt;p&gt;وصحت النية على وضع نشيد للجمهورية السورية، وكانت مسابقة، ولجنة، وجائزة، ثم عدل عن ذلك واختير النشيد الذي قدمه هذا الأديب الكبير، فلما قرأناه علمنا أنه لوحظ باختياره اسم الشاعر ومنزلته، وأنه لهما لا لبراعة الشعر فرض علينا هذا النشيد، واحتملناه سنين، غير أنه لا يصح أن نتحمله الآن، وقد تم استقلالنا، أو هو قد أشرف على التمام، واستقبلنا عهدا من حياتنا جديدا، ولابد من بيان عيب هذا النشيد لنسبتدل به.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;الأصل في النشيد الوطني أن يكون على لسان المتكلم، لأن الأمة هي التي تردده وتنطق به، وهذا النشيد موجه إلى حماة الديار، مطلعه:&lt;&#x2F;p&gt;

&lt;table class=&quot;poem&quot; name=&quot;humat-aldiyar&quot;&gt;
	&lt;tr&gt;
				&lt;td&gt;حماة الديار عليكم سلام&lt;&#x2F;td&gt;
		
				&lt;td&gt;أبت أن تذل النفوس الكرام&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;فمن الذي يقول هذا الكلام، ومن المخاطب به؟ إن كان ينطق به الشباب وهم حماة الديار، لم يعقل أن ينادوا أنفسهم، ويسلموا عليها، وليس هذا من (التجريد) الذي كان يألفه شعراء العرب؛ وإن كان يقوله غير الشعب لم يكن مقبولا لأن النشيد يوضع ليقوله الشعب ويترجم به عن آماله ومطامحه.&lt;&#x2F;p&gt;
&lt;p&gt;وهذا السلام أليس أشبه بلهجة أروام الإسكندرية وأرناؤوط الشام، منه بأسلوب الشعراء الأبيناء&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-أبيناء-1&quot;&gt;&lt;a href=&quot;#fn-أبيناء&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;؟&lt;&#x2F;p&gt;
&lt;p&gt;ثم يقول بعد هذا:&lt;&#x2F;p&gt;

&lt;table class=&quot;poem&quot; name=&quot;humat-aldiyar&quot;&gt;
	&lt;tr&gt;
				&lt;td&gt;عرين العروبة بيت حرام&lt;&#x2F;td&gt;
		
				&lt;td&gt;وعرش الشموس حمى لا يضام&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;فلا يعرف السامع ما عرين العروبة هذا، أهو الجزيرة أم مصر أم الشام أم العراق؟ ولا يعرف المسلم (بيتا حراما) إنما يعرف البيت الحرام، لا ثاني له، فهذا التنكير أولا، وابتذال اسم البيت الحرام في كل مكان ثانيا، كلاهما قبيح. وما هو هذا العرش، والنشيد نشيد جمهورية؟ أفنظمه ليكون النشيد الرسمي لبني أمية، وأي شموس هذه؟ وما هذا الإبهام حتى لا يحسن إلا التصريح والتوضيح؟ يأتي بعد ذلك هذا المقطع العجيب:&lt;&#x2F;p&gt;

&lt;table class=&quot;poem&quot; name=&quot;humat-aldiyar&quot;&gt;
	&lt;tr&gt;
				&lt;td&gt;ربوع الشآم بروج العلاء&lt;&#x2F;td&gt;
		
				&lt;td&gt;تحاكي السماء بعالي السناء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
				&lt;td&gt;وأرض زهت بالنجوم الوضاء&lt;&#x2F;td&gt;
		
				&lt;td&gt;سماء لعمرك أو كالسماء&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;أما (بروج العلاء) هذه فتصح في كل أرض يريد أن يبالغ في مدحها القائل، ولا تدل على ميزة للشام ولا تصفها بصفة فيها ولا تعرّف بها الغريب عنها، ولا تحببها إلى أبنائها، فهي كمراثي الأستاذ علي الجارم التي تصلح لغازي والإسكندر المكدوني وللشيخ المراغي، لأنها تهد الجبال وتبكي السماء، وتقيم القيامة، أو ترسل على الدنيا قنبلة ذرية، لا بحجم البيضة، بل بحجم الفيل، ثم لا تذكر المرثيّ بشيء مما كان عليه. وهذا استطراد نعتذر إلى الشاعر الكبير علي الجارم بك منه، فقد جرته المناسبة.&lt;&#x2F;p&gt;
&lt;p&gt;وما دامت الشام بروج العلاء، وكان ذلك قد تقرر لدى السامع فما معنى كونها تحاكي السماء، وبروج العلاء هي السماء في أفهام الناس كلهم، وهل السماء أسمى سنا من البروج؟ المسألة تحتاج إلى خبير فلكي.&lt;&#x2F;p&gt;
&lt;p&gt;ثم إن الضياء هو السنا بالقصر، أما السناء بالمد فهو الارتفاع، ومن هنا أطلق على المجد مجازا، فصار معنى قوله: (بعالي السناء) برفع الارتفاع، وهو الحشو نفسه وهو إذا قبل في القصيدة لا يقبل في النشيد، لأن النشيد كلمات معدودة وألفاظ محدودة، لا يجوز أن يذهب لفظ واحد منها من غير أن يدل على شيء.&lt;&#x2F;p&gt;
&lt;p&gt;وهو بعد أن جعلها بروج العلاء التي تحاكي السماء، عاد فهبط بها فجعلها (أرضا زهت) ولكن بالشموس الوضاء؟ وما فهمت إلى اليوم ما يرد بهذه الشموس التي يرددها ولا يشبع من ذكرها، إن كان يريد الحقيقة فهي شمس واحدة ما خلق الله سواها؛ ،إن كان يقصد المجاز؛ فليذكر ما يدل عليها ويصرف الفكر إليه، وما كل سامع للنشيد أو تالٍ يستطيع أن يجد له التأويل، هذا إذا كان لهذا الكلام العجيب تخريج أو تأويل.&lt;&#x2F;p&gt;
&lt;p&gt;وأعجب العجب، وأقبح القبح، أن يعود بعد كل ما مر، فيجعلها سماء ثم ينزل بها فيجعلها كالسماء، وهذا ضدّ ما عليه البلغاء في كل عصر، وفي كل أمة، ولا أحسب ذوقا من الدنيا يسيغه، عدِّ من هذا الحشو في كلمة (لعمرك) وعمر من هذا الذي يحلف به؟ ولمن هذا الخطاب؟ والمفروض في النشيد كما بينت أن ينطق به الشعب كله؟!&lt;&#x2F;p&gt;
&lt;p&gt;وما هو مغزى هذا كله، وما دلالته، وأي مجد للشام يذكر، وأي عاطفة تثير؟ لا شيء، إلا هذه المناقشة المزعجة في الشام: هل هي بروج العلاء تشابه السماء برفيع الارتفاع؟ أم هي أرض ولكن زهت بالشموس؟ أم هي سماء (وحياة عمرك ...) أم هي كالسماء؟ هذه هي المشكلة الوطنية الكبرى، ملأ النشيد بذكرها، وهذه هي آمال الوطن ومطامحه، والله المستعان!&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;وباقي النشيد لا يختلف كثيرا عما ذكرت منه، على حين أن النشيد يجب أن يكون موضوعا على لسان الشعب، وأن يكون قوي العبارة، خاليا من الحشو، واضحا كل الوضوح، صالحا لكل زمان، معبرا عن آمال الشعب وآلامه ومطامحه، مثيرا نخوته وحماسته، مشيرا إلى ماضيه، وجمال أرضه ودياره، إلى غير ذلك مما يوصل إلى الغاية من وضع النشيد، وهي إثارة العزة الوطنية في النفوس، وأن يختار له النغم القوي من غير خشونة، العاطفي بلا ضعف. وحياة النشيد بحلنه وما يهز هذا اللحن من أوتار القلوب، ويحرك على أعصاب السامعين، فإذا كان لنا نشيد يشتمل على هذه كله... وإلا فلا تقولوا: لنا نشيد&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-نشيد-1&quot;&gt;&lt;a href=&quot;#fn-نشيد&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;!!&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-ناظم&quot;&gt;
&lt;p&gt;ناظم هذا النشيد أديب كبير، وصديق كريم، وهو يعلم أن ليس له عندي إلا الإجلال والتوقير، وأن الشاعر «وإن نبغ» يسبق تارة ويقصر، وإن النقد «وإن قسا» لا يصدر عن حقد ولا يرمي إلى تحقير، وإن مصلحة الوطن بإصلاح نشيده تسوغ مفاجأة الكبير بنقد هذا النشيد. &lt;a href=&quot;#fr-ناظم-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-أبيناء&quot;&gt;
&lt;p&gt;الأبيناء: جمع بيّن. &lt;a href=&quot;#fr-أبيناء-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-نشيد&quot;&gt;
&lt;p&gt;ناظم هذا النشيد هو أستاذنا خليل مردم بك رحمه الله، وهو شاعر بليغ، رفيع المقام، فاضل الأخلاق. وابنه الأستاذ عدنان شاعر كبير. وملحن النشيد أستاذنا مصطفى الصواف. &lt;a href=&quot;#fr-نشيد-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Unbearable Frustration of Figuring Out APIs</title>
        <published>2026-01-14T00:00:00+00:00</published>
        <updated>2026-01-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/thoughts/translation-cli/"/>
        <id>https://ar-ms.me/thoughts/translation-cli/</id>
        
        <content type="html" xml:base="https://ar-ms.me/thoughts/translation-cli/">&lt;p&gt;In the ongoing effort for activities that fill the void made by unemployment, I have recently started to learn Chinese. Got into a Chinese language institute and everything. And because not every app supports right-clicking some text and selecting the &quot;Translate&quot; menu option, I found myself launching TextEdit just to do that. So, I figured, maybe I can do a small command line tool where I&#x27;d write something like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;translate&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; 你好&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And the terminal would happily tell me it means &quot;Hello&quot;. Should be easy. A &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;hikikomorphism.bsky.social&#x2F;post&#x2F;3lwamjk3pjk2x&quot;&gt;hungry ghost trapped in a jar&lt;&#x2F;a&gt; can probably figure it out in one shot.&lt;&#x2F;p&gt;
&lt;p&gt;First I figured I&#x27;d look for some translation API. Almost everything I looked at seemed to want an API token and there is a rate limit (not that I&#x27;d hit it), and maybe a credit card number. Then I remembered that macOS has that Translate right click action, surely I can just hook into that.&lt;&#x2F;p&gt;
&lt;p&gt;Note that this article, unlike what I do usually, is written after the fact.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;first-steps&quot;&gt;First Steps&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;zig&quot;&gt;Zig&lt;&#x2F;h3&gt;
&lt;p&gt;I have been using Zig for different projects this year. So I got the Ghost to write the thing for me, and it even gave me the correct flags to pass to the compiler! But then when I tried it, I realized it used the &lt;em&gt;Dictionary&lt;&#x2F;em&gt; service instead of the Translation service. When I asked it for that instead, it was like yeah you cannot call Swift &lt;code&gt;async&lt;&#x2F;code&gt; functions from Zig, you need a Swift shim.&lt;&#x2F;p&gt;
&lt;p&gt;So let&#x27;s do the thing in Swift instead. I have been meaning to learn Swift anyway.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mycli&quot;&gt;MyCLI&lt;&#x2F;h3&gt;
&lt;p&gt;Thankfully, Swift was already set up on my machine with an LSP and a formatter and the works. I had even &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.swift.org&#x2F;getting-started&#x2F;cli-swiftpm&#x2F;&quot;&gt;followed the basic tutorial&lt;&#x2F;a&gt; and the file is on my machine already, A small edit and I can be on my way.&lt;&#x2F;p&gt;
&lt;p&gt;For reference, this is the code at the end of the tutorial:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArgumentParser&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Figlet&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;@main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;FigletTool&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-inherited-class&quot;&gt;ParsableCommand &lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;	@Option&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;(help&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Specify the input&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;	public var&lt;&#x2F;span&gt;&lt;span&gt; input: String&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-storage z-type&quot;&gt;	public func&lt;&#x2F;span&gt;&lt;span&gt; run()&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt; throws&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		Figlet.say(self.input)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After so long in Rust and Zig lands, the most jarring thing about Swift so far is that &lt;code&gt;import&lt;&#x2F;code&gt; creates glob imports. This is not quite apparent here, but it is there. Also, this is the accompanying &lt;code&gt;Package.swift&lt;&#x2F;code&gt;, comments and all.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; swift-tools-version: 5.8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; The swift-tools-version declares the minimum version of Swift required to build this package.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;PackageDescription&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;let package&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Package(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;MyCLI&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    dependencies: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      .package(url:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;https:&#x2F;&#x2F;github.com&#x2F;apple&#x2F;example-package-figlet&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, branch:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;main&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      .package(url:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;https:&#x2F;&#x2F;github.com&#x2F;apple&#x2F;swift-argument-parser&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, from:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;1.0.0&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    targets: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Targets are the basic building blocks of a package, defining a module or a test suite.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Targets can depend on other targets in this package and products from dependencies.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .executableTarget(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            name:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;MyCLI&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            dependencies: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .product(name:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Figlet&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, package:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;example-package-figlet&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .product(name:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ArgumentParser&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, package:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;swift-argument-parser&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            path:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Sources&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is run with &lt;code&gt;swift run&lt;&#x2F;code&gt;, but to pass arguments, one needs to do the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swift&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; run MyCLI&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; --input&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; Hello&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I spent like 15 minutes trying different variations of this&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;# this does NOT work&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;swift&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; run&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -- --input&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; Hello&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Anyway, I deleted the &lt;code&gt;Figlet&lt;&#x2F;code&gt; related lines and went from there.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;false-starts&quot;&gt;False Starts&lt;&#x2F;h2&gt;
&lt;p&gt;I asked the Ghost in the Jar for how the API to use it looks like, but every version it gave me was hallucinated in some fashion. So I wrote &lt;code&gt;import Translation&lt;&#x2F;code&gt; at the top of the file, and figured maybe I can figure it out as I go along. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.apple.com&#x2F;documentation&#x2F;Translation&quot;&gt;Here is the Apple API documentation&lt;&#x2F;a&gt;. A quick look tells you all the functions in here return a &lt;code&gt;some View&lt;&#x2F;code&gt;, and the only function seemingly unrelated to SwiftUI is the &lt;code&gt;init&lt;&#x2F;code&gt; function in &lt;code&gt;TranslationSession&lt;&#x2F;code&gt;, which, annoyingly, &lt;em&gt;needs&lt;&#x2F;em&gt; a known source language.&lt;&#x2F;p&gt;
&lt;p&gt;So I do this&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArgumentParser&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Translation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;@main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Translate&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-inherited-class&quot;&gt;ParsableCommand &lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;	@Argument&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;(help&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Specify the input&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;	public var&lt;&#x2F;span&gt;&lt;span&gt; input: String&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-storage z-type&quot;&gt;	public func&lt;&#x2F;span&gt;&lt;span&gt; run()&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt; async throws&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;\(input)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; source &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; Locale.Language(identifier:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;zh_CN&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; target &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; Locale.Language(identifier:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;en_US&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; session &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; TranslationSession(installedSource: source, target: target)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; response &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try await&lt;&#x2F;span&gt;&lt;span&gt; session.translate(input)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; response.targetText&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;\(result)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can see the number of small changes to the original file here. I changed the struct&#x27;s name (because it shows up in the &lt;code&gt;--help&lt;&#x2F;code&gt; message.) I changed &lt;code&gt;Option&lt;&#x2F;code&gt; to &lt;code&gt;Argument&lt;&#x2F;code&gt; so it does not need a flag. I even turned &lt;code&gt;run&lt;&#x2F;code&gt; into an &lt;code&gt;async&lt;&#x2F;code&gt; function so I can &lt;code&gt;await&lt;&#x2F;code&gt; the &lt;code&gt;session.translate&lt;&#x2F;code&gt; function call.&lt;&#x2F;p&gt;
&lt;p&gt;However, I start to hit a couple of snags. First is that &lt;code&gt;TranslationSession.init&lt;&#x2F;code&gt; is restricted to macOS 26. Not wanting to do a bunch of conditional compilation, (after all this tool is for my own use), I will just add the &lt;code&gt;platforms&lt;&#x2F;code&gt; field in &lt;code&gt;Package.swift&lt;&#x2F;code&gt;。 Oh it needs to be &lt;em&gt;before&lt;&#x2F;em&gt; &lt;code&gt;dependencies&lt;&#x2F;code&gt;? Fine, whatever.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; swift-tools-version: 5.8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; The swift-tools-version declares the minimum version of Swift required to build this package.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;PackageDescription&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;let package&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Package(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	name:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;MyCLI&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	platforms: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		.macOS(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;* one problem, I cannot find v26 in the dropdown *&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	dependencies: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		.package(url:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;https:&#x2F;&#x2F;github.com&#x2F;apple&#x2F;swift-argument-parser&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, from:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;1.0.0&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	targets: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; Targets are the basic building blocks of a package, defining a module or a test suite.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; Targets can depend on other targets in this package and products from dependencies.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		.executableTarget(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			name:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;MyCLI&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			dependencies: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;				.product(name:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;ArgumentParser&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, package:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;swift-argument-parser&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			path:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Sources&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I cannot find &lt;code&gt;.v26&lt;&#x2F;code&gt; in the LSP&#x27;s drop down. There is no &lt;code&gt;.Tahoe&lt;&#x2F;code&gt; either. Even if I type it manually, I get an error. I am on Tahoe. I have the latest version of Swift (I checked). why can&#x27;t I select it from here?&lt;&#x2F;p&gt;
&lt;p&gt;You probably already know this, but apparently the first line in the file, that &lt;em&gt;comment&lt;&#x2F;em&gt;, is actually significant. I edited that to say &lt;code&gt;swift-tools-version: 6.2&lt;&#x2F;code&gt;, and now I can write &lt;code&gt;.v26&lt;&#x2F;code&gt; in peace. I &lt;em&gt;hate&lt;&#x2F;em&gt; syntactic comments.&lt;&#x2F;p&gt;
&lt;p&gt;Ok, the LSP is happy. The compiler seems happy. Let&#x27;s get going.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;async-woes&quot;&gt;Async Woes&lt;&#x2F;h2&gt;
&lt;p&gt;Running this with &lt;code&gt;swift run -q MyCLI 你好&lt;&#x2F;code&gt; gives the following message:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;USAGE: translate &amp;lt;input&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ARGUMENTS:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &amp;lt;input&amp;gt;                 Specify the input&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OPTIONS:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -h, --help              Show help information.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Eh, I clearly passed in something. What gives? I tried changing &lt;code&gt;Argument&lt;&#x2F;code&gt; back to &lt;code&gt;Option&lt;&#x2F;code&gt;, same result. Hm. I realized that the problem maybe is that &lt;code&gt;run&lt;&#x2F;code&gt; is not supposed to be &lt;code&gt;async&lt;&#x2F;code&gt;. Fine, let&#x27;s remove &lt;code&gt;async&lt;&#x2F;code&gt;, but then how do I call &lt;code&gt;session.translate&lt;&#x2F;code&gt; ?&lt;&#x2F;p&gt;
&lt;p&gt;Looking things up, and communing with ghosts, apparently I can wrap the thing in &lt;code&gt;Task&lt;&#x2F;code&gt;. Sure.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Task {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; response &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try await&lt;&#x2F;span&gt;&lt;span&gt; session.translate(input)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; response.targetText&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;\(result)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And this runs! I rerun the command I do &lt;code&gt;swift run -q MyCLI 你好&lt;&#x2F;code&gt; and I get ... nothing. Just the print message that prints &lt;code&gt;input&lt;&#x2F;code&gt; at the start. I think hah .. I have fallen into the classic trap, I am spawning a Task but I am not waiting for it. &lt;em&gt;How&lt;&#x2F;em&gt; do I wait for it?&lt;&#x2F;p&gt;
&lt;p&gt;The ghosts suggested a &lt;code&gt;DispatchSemaphore&lt;&#x2F;code&gt;. This is the full code:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArgumentParser&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Translation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;@main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Translate&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-inherited-class&quot;&gt;ParsableCommand &lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;	@Argument&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;(help&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Specify the input&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;	public var&lt;&#x2F;span&gt;&lt;span&gt; input: String&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-storage z-type&quot;&gt;	public func&lt;&#x2F;span&gt;&lt;span&gt; run()&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt; throws&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;\(input)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; source &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; Locale.Language(identifier:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;zh_CN&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; target &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; Locale.Language(identifier:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;en_US&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; session &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; TranslationSession(installedSource: source, target: target)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; semaphore &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; DispatchSemaphore(value:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		Task {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;			let&lt;&#x2F;span&gt;&lt;span&gt; response &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try await&lt;&#x2F;span&gt;&lt;span&gt; session.translate(input)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;			let&lt;&#x2F;span&gt;&lt;span&gt; result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; response.targetText&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;\(result)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			semaphore.signal()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		semaphore.wait()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ok .. for some reason, when I tried this right now, it actually works. But when I tried it before, probably with a different arrangement of stuff, it did not. It just froze and gave no feedback. The power of hindsight, I guess.&lt;&#x2F;p&gt;
&lt;p&gt;Nonetheless, since it did not work, I figured I was doing something wrong. So I searched for &quot;how to call an async function from a sync function in Swift&quot;, and came across &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.hackingwithswift.com&#x2F;quick-start&#x2F;concurrency&#x2F;what-calls-the-first-async-function&quot;&gt;What calls the first async function?&lt;&#x2F;a&gt; from Hacking With Swift, and the tl;dr of that article was &quot;not you, just make your main &lt;code&gt;async&lt;&#x2F;code&gt;&quot;. Very helpful, Paul. Apparently I needed to make &lt;code&gt;run&lt;&#x2F;code&gt; async. I looked into the docs of &lt;code&gt;swift-argument-parser&lt;&#x2F;code&gt;, I figured surely they have &lt;em&gt;some&lt;&#x2F;em&gt; guidance on how to deal with &lt;code&gt;async&lt;&#x2F;code&gt; functions. Apparently the guidance was just to replace the &lt;code&gt;ParsableCommand&lt;&#x2F;code&gt; protocol with &lt;code&gt;AsyncParsableCommand&lt;&#x2F;code&gt;. Ok, now I felt like an idiot. This is the full code:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArgumentParser&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Translation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;@main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Translate&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-inherited-class&quot;&gt;AsyncParsableCommand &lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;	@Argument&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;(help&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Specify the input&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;	public var&lt;&#x2F;span&gt;&lt;span&gt; input: String&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-storage z-type&quot;&gt;	public func&lt;&#x2F;span&gt;&lt;span&gt; run()&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt; async throws&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;\(input)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; source &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; Locale.Language(identifier:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;zh_CN&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; target &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; Locale.Language(identifier:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;en_US&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; session &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; TranslationSession(installedSource: source, target: target)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; response &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try await&lt;&#x2F;span&gt;&lt;span&gt; session.translate(input)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; response.targetText&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;\(result)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Works like magic &lt;em&gt;now&lt;&#x2F;em&gt;. Except, at the time, it did not. It gave me the following message:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt;	你好&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Error: Unable to Translate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Also it leaves the small detail of autodetecting the language, which is here hardcoded as &lt;code&gt;zh_CN&lt;&#x2F;code&gt;.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-languagecode-1&quot;&gt;&lt;a href=&quot;#fn-languagecode&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;language-recognition&quot;&gt;Language Recognition&lt;&#x2F;h2&gt;
&lt;p&gt;The error had &lt;em&gt;zero&lt;&#x2F;em&gt; feedback. Absolutely unhelpful. No idea what&#x27;s going on. I added a &lt;code&gt;try await session.prepareTranslation()&lt;&#x2F;code&gt; line I saw in some online examples, but .. nothing. I looked a bit more around for tutorials, I could not find anything. All tutorials just regurgitate the same SwiftUI code examples, but I am not using SwiftUI. Ekh.&lt;&#x2F;p&gt;
&lt;p&gt;Eventually, I came across the original &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=MuIFhbHNmqA&quot;&gt;WWDC video introducing the Translation API&lt;&#x2F;a&gt;, and decided to watch it. And it was actually very helpful, despite it being SwiftUI focused.&lt;&#x2F;p&gt;
&lt;p&gt;It does not touch on how to use &lt;code&gt;TranslationSession.init&lt;&#x2F;code&gt;, instead it mentions that a &lt;code&gt;session&lt;&#x2F;code&gt; is given to you to run in a SwiftUI closure. It gives the rationale behind the API, but it also introduces the bit I needed for autodetection, and that is &lt;code&gt;NLLanguageRecognizer&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;NaturalLanguage&lt;&#x2F;code&gt; is an Apple framework for dealing with natural language (How did you guess?). I pretty much copied the code from the video into its own function (after &lt;code&gt;import NaturalLanguage&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;func&lt;&#x2F;span&gt;&lt;span&gt; identify_lang(_ sample: String)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Locale.Language&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; recognizer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; NLLanguageRecognizer()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	recognizer.processString(sample)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-keyword z-other&quot;&gt;	guard let&lt;&#x2F;span&gt;&lt;span&gt; language &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; recognizer.dominantLanguage &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span&gt; Locale.Language(identifier: language.rawValue)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And this is my new &lt;code&gt;func run()&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-storage z-type&quot;&gt;public func&lt;&#x2F;span&gt;&lt;span&gt; run()&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt; async throws&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;\(input)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; unwrapping here but I handle it more gracefully in the code&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; source &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; identify_lang(input)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; target &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; Locale.Language(identifier:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;en_US&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; session &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; TranslationSession(installedSource: source, target: target)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	try await&lt;&#x2F;span&gt;&lt;span&gt; session.prepareTranslation()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; response &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try await&lt;&#x2F;span&gt;&lt;span&gt; session.translate(input)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; response.targetText&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;\(result)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The other thing the video pointed out, is that the API user should check language availability. I saw that earlier, but did not particularly care. I &lt;em&gt;know&lt;&#x2F;em&gt; Chinese and English are available. I have been using them! Nonetheless, I copied that code as well just to be thorough, to figure out what the API does.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; availability &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; LanguageAvailability()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; is_it &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; await&lt;&#x2F;span&gt;&lt;span&gt; availability.status(from: source, to: target)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;switch&lt;&#x2F;span&gt;&lt;span&gt; is_it {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;case&lt;&#x2F;span&gt;&lt;span&gt; .unsupported&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;gt; language pairing from \(source.languageCode) to \(target.languageCode) unsupprted&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;case&lt;&#x2F;span&gt;&lt;span&gt; .supported&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;gt; language pairing from \(source.languageCode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;) to \(target.languageCode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;) not installed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;case&lt;&#x2F;span&gt;&lt;span&gt; .installed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This gave me a compile error, as it happens, as apparently the enum is marked the Swift equivelant of &lt;code&gt;#[non_exhaustive]&lt;&#x2F;code&gt;. Going over StackOverflow and the Swift book, told me the answer is to add a &lt;code&gt;@unknown default:&lt;&#x2F;code&gt; case. I could not quickly figure out how to merge it with another case so I did not bother.&lt;&#x2F;p&gt;
&lt;p&gt;To my surprise, the pairing returned &lt;code&gt;.supported&lt;&#x2F;code&gt;, and &lt;em&gt;not&lt;&#x2F;em&gt; &lt;code&gt;.installed&lt;&#x2F;code&gt;. In a SwiftUI app, the &lt;code&gt;try await session.prepareTranslation()&lt;&#x2F;code&gt; call creates a pop up to ask the user to download the model.&lt;&#x2F;p&gt;
&lt;p&gt;But it is already installed! I am already using it via the right click menu! Nonetheless, that must be the reason for the &lt;code&gt;Unable to Translate&lt;&#x2F;code&gt; error.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;installing-models&quot;&gt;Installing Models&lt;&#x2F;h2&gt;
&lt;p&gt;Communing again with Ghosts, they told me to install the models through System Settings, General, Language, etc. I went where they told me, to this dialogue, where I can install the models locally.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;translation-cli&#x2F;dialogue.png&quot; alt=&quot;the dialogue&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You can see that Mandarin is installed now, but the only language installed at the time was English(US). No matter, I installed Mandarin SImplified and Arabic, and added a note to the &lt;code&gt;switch&lt;&#x2F;code&gt; above showing where to install the items. And then I tried again: &lt;code&gt;swift run -q MyCLI 你好&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;And .. same error. I guessed that it identified the language as Mandarin Traditional for some reason, so I installed that as well, and now it works, finally!!&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;% swift&#x2F;MyCLI ❭ swift run -q MyCLI 你好&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt;	你好&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt;	Hello&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Why was that so hard? Why are the models here separate from the ones in the right click menu? Too many questions.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;final-code&quot;&gt;Final Code&lt;&#x2F;h2&gt;
&lt;p&gt;This is the full final code, with some proper error names thrown in for good measure.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArgumentParser&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;NaturalLanguage&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Translation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;@main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Translate&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-inherited-class&quot;&gt;AsyncParsableCommand &lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;	@Argument&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;(help&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Specify the input&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;	public var&lt;&#x2F;span&gt;&lt;span&gt; input: String&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-storage z-type&quot;&gt;	public func&lt;&#x2F;span&gt;&lt;span&gt; run()&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt; async throws&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;\(input)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; target &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; Locale.Language(identifier:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;en_US&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-keyword z-other&quot;&gt;		guard let&lt;&#x2F;span&gt;&lt;span&gt; source &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; identify_lang(input)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;gt; could not identify language&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;			throw&lt;&#x2F;span&gt;&lt;span&gt; CliError.Recognitionfailed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; availability &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; LanguageAvailability()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; is_it &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; await&lt;&#x2F;span&gt;&lt;span&gt; availability.status(from: source, to: target)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;		switch&lt;&#x2F;span&gt;&lt;span&gt; is_it {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;		case&lt;&#x2F;span&gt;&lt;span&gt; .unsupported&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;gt; language pairing from \(source.languageCode) to \(target.languageCode) unsupprted&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;			throw&lt;&#x2F;span&gt;&lt;span&gt; CliError.PairingUnsupported&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;		case&lt;&#x2F;span&gt;&lt;span&gt; .supported&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;gt; language pairing from \(source.languageCode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;) to \(target.languageCode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;) not installed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;gt; Go to System Settings &amp;gt; General &amp;gt; Language &amp;amp; Region &amp;gt; Translation Languages and download the models.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;			throw&lt;&#x2F;span&gt;&lt;span&gt; CliError.PairingNotInstalled&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;		case&lt;&#x2F;span&gt;&lt;span&gt; .installed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;			break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-keyword z-control&quot;&gt;		@unknown default&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;Unknown status.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; session &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; TranslationSession(installedSource: source, target: target)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;		try await&lt;&#x2F;span&gt;&lt;span&gt; session.prepareTranslation()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; response &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try await&lt;&#x2F;span&gt;&lt;span&gt; session.translate(input)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; response.targetText&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;\(result)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;func&lt;&#x2F;span&gt;&lt;span&gt; identify_lang(_ sample: String)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Locale.Language&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; recognizer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; NLLanguageRecognizer()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	recognizer.processString(sample)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-keyword z-other&quot;&gt;	guard let&lt;&#x2F;span&gt;&lt;span&gt; language &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; recognizer.dominantLanguage &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span&gt; Locale.Language(identifier: language.rawValue)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;CliError&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-inherited-class&quot;&gt;Error &lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	case&lt;&#x2F;span&gt;&lt;span&gt; Recognitionfailed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	case&lt;&#x2F;span&gt;&lt;span&gt; PairingUnsupported&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	case&lt;&#x2F;span&gt;&lt;span&gt; PairingNotInstalled&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So I compiled it for release, put it in &lt;code&gt;&#x2F;usr&#x2F;local&#x2F;bin&lt;&#x2F;code&gt;, and called it a day. You can see an example of a failing call if you do &lt;code&gt;swift run -q MyCLI Bonjour&lt;&#x2F;code&gt;, where it prompts to install the dictionary.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;in-conclusion&quot;&gt;In Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;To rub some salt on the wound, during the time I was trying to puzzle this out, I realized that Spotlight (with the Cmd+Space key) can already do this exactly how I envisioned it, with around the same number of keystrokes, and it does not need this dance with installing models and whatever.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-ghostty-1&quot;&gt;&lt;a href=&quot;#fn-ghostty&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;translation-cli&#x2F;spotlight.png&quot; alt=&quot;spotlight&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Also, Swift is frustrating. API of Swift libraries is frustrating.&lt;&#x2F;p&gt;
&lt;p&gt;Until later.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-languagecode&quot;&gt;
&lt;p&gt;By the way, there is no documentation anywhere I could find on &lt;em&gt;what&lt;&#x2F;em&gt; the strings accepted here are. The only comment exists is &quot;A Unicode language identifier, like &lt;code&gt;en-US&lt;&#x2F;code&gt;, &lt;code&gt;es-419&lt;&#x2F;code&gt;, or &lt;code&gt;zh-Hant-TW&lt;&#x2F;code&gt;.&quot; No list or anything. Am I supposed to guess? &lt;a href=&quot;#fr-languagecode-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-ghostty&quot;&gt;
&lt;p&gt;Also this supports Chinese input, while Ghostty&#x27;s quick terminal does not, for some reason. &lt;a href=&quot;#fr-ghostty-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A Dumb Introduction to z3</title>
        <published>2025-09-15T00:00:00+00:00</published>
        <updated>2025-09-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/thoughts/a-gentle-introduction-to-z3/"/>
        <id>https://ar-ms.me/thoughts/a-gentle-introduction-to-z3/</id>
        
        <content type="html" xml:base="https://ar-ms.me/thoughts/a-gentle-introduction-to-z3/">&lt;p&gt;Recently I have come across a nice article: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;buttondown.com&#x2F;hillelwayne&#x2F;archive&#x2F;many-hard-leetcode-problems-are-easy-constraint&#x2F;&quot;&gt;Many Hard Leetcode Problems are Easy Constraint Problems&lt;&#x2F;a&gt;, and I figured, I really should learn how to use these things! What else do I really have to do? I have had use for solvers (or as they are commonly called: theorem provers) &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-hanging-gardens-problem&#x2F;&quot;&gt;In a previous article&lt;&#x2F;a&gt;, but then I tried to prove the things with good old algorithms. I looked at &lt;code&gt;z3&lt;&#x2F;code&gt; at the time, but found the whole concept a bit too opaque. Now however, it seemed a bit easier to get into.&lt;&#x2F;p&gt;
&lt;p&gt;To be clear, as of writing these words, I have only been looking at &lt;code&gt;z3&lt;&#x2F;code&gt; reading material for two days. I am in no way an expert, and I have not written anything more complex than a solver for the change counter problem (the first example in the article listed above). So I am writing this really knowing nothing about the underlying theory, theorem provers, or whatever the hell &quot;unification&quot; is. There is a good chance you know more about this than I do.&lt;&#x2F;p&gt;
&lt;p&gt;There are &lt;code&gt;z3&lt;&#x2F;code&gt; bindings in many popular languages. I will be using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;z3&#x2F;latest&#x2F;z3&#x2F;&quot;&gt;&lt;code&gt;z3&lt;&#x2F;code&gt;&#x27;s Rust bindings&lt;&#x2F;a&gt;, because I am more comfortable in Rust than, say, Python or JavaScript. The examples I worked with to understand &lt;code&gt;z3&lt;&#x2F;code&gt; however, can be found in two nice documents:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;z3prover.github.io&#x2F;papers&#x2F;programmingz3.html&quot;&gt;First is in Python&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;microsoft.github.io&#x2F;z3guide&#x2F;programming&#x2F;Z3%20JavaScript%20Examples&#x2F;&quot;&gt;Second in JavaScript&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;what-are-solvers&quot;&gt;What are Solvers?&lt;&#x2F;h2&gt;
&lt;p&gt;Solvers are a class of .. tools? libraries? where you input some rules and constraints and have the tool just .. solve it for you. It is not going to be a faster or more optimized solution than a custom made algorithm, but it is much easier to change the rules on the fly.&lt;&#x2F;p&gt;
&lt;p&gt;There are many real world uses. They are often used for scheduling and resource allocation problems. Consider the common scenario of a school schedule: Mary cannot work on Tuesdays because she needs to take care of her father; John lives far so he cannot give classes before 10; Class 3-A is full of nerds so their math hours are double; city council regulates no outdoor activity after 12; Susan and Sarah hate each other so you should not have them teach the same class; etc. You can either have two teachers work on it for a week, or just pop it in a solver!&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.minizinc.org&quot;&gt;MiniZinc homepage&lt;&#x2F;a&gt; (another popular solver) has a couple of nice examples: a seating chart, rostering, vehicle routing, grid coloring.&lt;&#x2F;p&gt;
&lt;p&gt;On that note, you might wonder: why did I go with &lt;code&gt;z3&lt;&#x2F;code&gt; when MiniZinc has a more colorful homepage and is actually referenced by the article linked at the start of this article? The answer is because &lt;code&gt;z3&lt;&#x2F;code&gt; has bindings in Rust. That is pretty much it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-note-on-terminology&quot;&gt;A Note on Terminology&lt;&#x2F;h2&gt;
&lt;p&gt;Documentation on &lt;code&gt;z3&lt;&#x2F;code&gt; and its API use a lot of jargon,&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-jargon-1&quot;&gt;&lt;a href=&quot;#fn-jargon&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; which makes the whole thing really difficult to wade into without a previous background. I will explain things as I understand when I get to them, but two things really stand out.&lt;&#x2F;p&gt;
&lt;p&gt;The first is the word &lt;code&gt;Sort&lt;&#x2F;code&gt;. You see this in the context of arrays and function declarations (we will get to those, I hope). But it has nothing to do with .. well .. sorting. &lt;code&gt;Sort&lt;&#x2F;code&gt; is just the jargon word for &lt;em&gt;types&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The second one is &lt;strong&gt;constants&lt;&#x2F;strong&gt;. They are not what a normal person would call constants: they are actually the knobs the solvers use to solve problems. There are two types of constants: &lt;em&gt;free&lt;&#x2F;em&gt;, which are what one would call variables; and &lt;em&gt;interpreted&lt;&#x2F;em&gt;, which is when you&#x27;d type an integer literal and clever type machinations turns it into a constant in the solver.&lt;&#x2F;p&gt;
&lt;p&gt;Note that also solvers do not work within the regular type system of the programming language. They have their own types (sorry, sorts), and operations that may or may not map nicely to the language&#x27;s types and operations. Much of the actual code you are writing is about expressing things in the target solver&#x27;s language. &lt;code&gt;z3&lt;&#x2F;code&gt; uses a language called &quot;SMT-LIB2&quot; (henceforth called &lt;code&gt;smt2&lt;&#x2F;code&gt;), apparently. And you can actually write your constraints immediately in said language and have the library consume it. Much of what the bindings is take your code and translate internally to this language before feeding it to the solver.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-dsl-1&quot;&gt;&lt;a href=&quot;#fn-dsl&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;a-simple-equation&quot;&gt;A Simple Equation&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s start with what might be the simplest, dumbest equation. Solve for &lt;code&gt;x&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;x + 4 = 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Yes, a child (literally) can solve this. But it is nice. Here is the Rust program to solve it.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;use&lt;&#x2F;span&gt;&lt;span&gt; z3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Solver&lt;&#x2F;span&gt;&lt;span&gt;, ast&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; main() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; define the variable.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new_const(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;x&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; define the equation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert((&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eq(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; run the solver&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	_&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;check();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_model()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;	println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{model:?}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This prints out the solution. &lt;code&gt;x&lt;&#x2F;code&gt; equals three. Who would have guessed?&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;smt2&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;x -&amp;gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The Rust bindings have some nice ergonomics here. You can simply do &lt;code&gt;&amp;amp;x + 4&lt;&#x2F;code&gt; and it would do all the bookkeeping behind closed doors to transform the &lt;code&gt;4&lt;&#x2F;code&gt; (and the &lt;code&gt;7&lt;&#x2F;code&gt;) into an interpreted constant and have them inserted into the internal model.&lt;&#x2F;p&gt;
&lt;p&gt;The reason you have to pass in a string in &lt;code&gt;new_const&lt;&#x2F;code&gt; is that this is the name given to the variable in &lt;code&gt;smt2&lt;&#x2F;code&gt;. It does not have to be &lt;code&gt;&quot;x&quot;&lt;&#x2F;code&gt;, it can be anything. Why do the bindings not autogenerate the name for you? Who knows.&lt;&#x2F;p&gt;
&lt;p&gt;If you print the solver (as in &lt;code&gt;println!(&quot;{solver:?}&quot;);&lt;&#x2F;code&gt;), you will get the following output in the &lt;code&gt;smt2&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;smt2&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;declare-fun&lt;&#x2F;span&gt;&lt;span&gt; x () Int)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; (= (+ x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that the variable you declared is declared as a &lt;em&gt;function&lt;&#x2F;em&gt;. A free constant is basically a function that takes no input and gives an output (here of &lt;del&gt;type&lt;&#x2F;del&gt; sort &lt;code&gt;Int&lt;&#x2F;code&gt;). The solver finds which version of the function satisfies the assertions. This also explains the arrow in &lt;code&gt;x -&amp;gt; 3&lt;&#x2F;code&gt; earlier. &lt;code&gt;x&lt;&#x2F;code&gt; &lt;em&gt;evaluates to&lt;&#x2F;em&gt; 3.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;a-jump-in-complexity&quot;&gt;A Jump in Complexity&lt;&#x2F;h2&gt;
&lt;p&gt;In school, jumping from solving equations with a single variable to equations with two variables was a real jump on complexity. Everything was doubled! Here is a pair of equations we will try to solve next:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;x + y = 17&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;y = 2 * x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here is the program. I am going to print the result of &lt;code&gt;solver.check()&lt;&#x2F;code&gt; first, tho. I just made up those numbers!&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;use&lt;&#x2F;span&gt;&lt;span&gt; z3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Solver&lt;&#x2F;span&gt;&lt;span&gt;, ast&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; main() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; define the variable.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new_const(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;x&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new_const(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; define the equation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert((&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; + &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;y)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eq(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert((&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eq(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;y));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;	println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{solver:?}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;check();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;	println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;; {c:?}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This prints out the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;smt2&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;declare-fun&lt;&#x2F;span&gt;&lt;span&gt; y () Int)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;declare-fun&lt;&#x2F;span&gt;&lt;span&gt; x () Int)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; (= (+ x y) &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; (= (* x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;) y))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;; Unsat&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Oh it is &lt;code&gt;Unsat&lt;&#x2F;code&gt;. Unsatisfiable. Bummer. This means this cannot be solved as defined.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s try changing the type to &lt;code&gt;Real&lt;&#x2F;code&gt;.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-float-1&quot;&gt;&lt;a href=&quot;#fn-float&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; The &lt;code&gt;Real&lt;&#x2F;code&gt; type does not have the same nice ergonomics as &lt;code&gt;Int&lt;&#x2F;code&gt; apparently, so the code will look slightly uglier. This is the new updated code.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;use&lt;&#x2F;span&gt;&lt;span&gt; z3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Solver&lt;&#x2F;span&gt;&lt;span&gt;, ast&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Real&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; main() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; define the variable.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Real&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new_const(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;x&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Real&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new_const(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; seventeen&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Real&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from_rational(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; two&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Real&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from_rational(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; define the equation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert((&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; + &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;y)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eq(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;seventeen));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert((&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; * &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;two)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eq(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;y));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;	println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{solver:?}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;check();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;	println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;; {c:?}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which prints&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;smt2&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;declare-fun&lt;&#x2F;span&gt;&lt;span&gt; y () Real)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;declare-fun&lt;&#x2F;span&gt;&lt;span&gt; x () Real)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; (= (+ x y) &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;17.0&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; (= (* x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2.0&lt;&#x2F;span&gt;&lt;span&gt;) y))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;; Sat&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Excellent! Using &lt;code&gt;get_model()&lt;&#x2F;code&gt; and printing the model as before gives us the following answer, presented as a nice rational number.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;smt2&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;y -&amp;gt; (&#x2F; &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;34.0 3.0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;x -&amp;gt; (&#x2F; &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;17.0 3.0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To actually extract the values programmatically, instead of debug printing &lt;code&gt;model&lt;&#x2F;code&gt;, requires some song and dance with the API, but it is simple, really. This is what it would look like.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; to avoid panicking on unsatisfiable models&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-storage z-type&quot;&gt;if let&lt;&#x2F;span&gt;&lt;span&gt; z3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SatResult&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sat&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;check() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_model()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; do not ask me what the `true` is for. I don&amp;#39;t know.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eval(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;x,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;approx_f64();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eval(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;y,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;approx_f64();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;	println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;x: {x:.3}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;y: {y:.3}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which prints&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;x: 5.667	y: 11.333&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nice. Isn&#x27;t this grand?&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;multiple-solutions&quot;&gt;Multiple Solutions&lt;&#x2F;h2&gt;
&lt;p&gt;As I am sure you know from your high school math, some equations have multiple solutions. Here is a simple one.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;x * x = 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The Rust bindings have a nice method for getting multiple solutions out of a solver, simply called &lt;code&gt;solutions&lt;&#x2F;code&gt;. It works similarly to &lt;code&gt;model.eval()&lt;&#x2F;code&gt; above, and takes the same parameters with the same output. Here is the complete program. (I am going back to &lt;code&gt;Int&lt;&#x2F;code&gt; because I am not cool enough for &lt;code&gt;Real&lt;&#x2F;code&gt; numbers.)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;use&lt;&#x2F;span&gt;&lt;span&gt; z3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Solver&lt;&#x2F;span&gt;&lt;span&gt;, ast&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; main() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new_const(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;x&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert((&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; * &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;x)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eq(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;	println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{solver:?}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; This terminates when `check` does not return `Sat`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span&gt; (idx, s)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;solutions(x,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;enumerate() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;as_i64()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;		println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;;{}:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{s}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which prints:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;smt2&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;declare-fun&lt;&#x2F;span&gt;&lt;span&gt; x () Int)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; (= (* x x) &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;;1:	-2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;;2:	2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I am not clear really on how to get multiple solutions with the regular &lt;code&gt;check&lt;&#x2F;code&gt; followed by &lt;code&gt;get_model&lt;&#x2F;code&gt; method, but this one is easy enough to use. Also, some problems might have infinitely many solutions, so it is advisable to use &lt;code&gt;take&lt;&#x2F;code&gt; with the &lt;code&gt;solutions&lt;&#x2F;code&gt; iterator. To demonstrate, I will use the circle equation.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;x * x + y * y = 25&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here is the straightforward script followed by the printed out result. Note that the &lt;code&gt;fresh_const&lt;&#x2F;code&gt; API creates a unique name for every invocation.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;use&lt;&#x2F;span&gt;&lt;span&gt; z3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Solver&lt;&#x2F;span&gt;&lt;span&gt;, ast&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; main() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;fresh_const(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;x&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;fresh_const(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;x&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; area&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; * &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; + &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; * &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;y;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert(area&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eq(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;25&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;	println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{solver:?}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span&gt; (idx, (x,y))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;solutions((x,y),&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;enumerate() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;as_i64()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;as_i64()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;		println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;; {}:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{x:&amp;gt;2},{y:?2} &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;smt2&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;declare-fun&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt; () Int)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;declare-fun&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt; () Int)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; (= (+ (* x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;) (* x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;25&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;; 1:	 0, 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;; 2:	-5, 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;; 3:	-3,-4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;; 4:	-4,-3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;; 5:	 0,-5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;; 6:	 3,-4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;; 7:	 4,-3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;; 8:	 5, 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;; 9:	 3, 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;; 10:	 4, 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;; 11:	-3, 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;; 12:	-4, 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This goes without saying, but if I used the &lt;code&gt;Real&lt;&#x2F;code&gt; type in this example it would generate infinite solutions.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;coin-change-problem&quot;&gt;Coin Change Problem&lt;&#x2F;h2&gt;
&lt;p&gt;The Coin Change problem is a simple one: given a list of denominations and a total, find the smallest number of coins that add up to said total. Emphasis on &lt;em&gt;smallest&lt;&#x2F;em&gt;. Unlike previous problems, this is an optimization problem. We are looking for a solution that satisfies specific criteria instead of just &lt;em&gt;a&lt;&#x2F;em&gt; solution. Conveniently enough, &lt;code&gt;z3&lt;&#x2F;code&gt; provides an &lt;code&gt;Optimize&lt;&#x2F;code&gt; object which we can use to optimize.&lt;&#x2F;p&gt;
&lt;p&gt;Let us set up the parameters of the problem in plain language. The denominations we have are 1, 5, and 10. We need to give 37 money in the least amount of coins. This is simple enough that we can know the solution is three 10 coins, one 5 coin, and two 1 coins. Let&#x27;s see if we can get the same result. As usual, code followed by output:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;use&lt;&#x2F;span&gt;&lt;span&gt; z3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Optimize&lt;&#x2F;span&gt;&lt;span&gt;, ast&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; main() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; opt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Optimize&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; c1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new_const(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;c1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; c5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new_const(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;c5&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; c10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new_const(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;c10&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; total&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; + &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; + &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c10;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	opt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;total&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eq(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;37&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	opt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;minimize(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;count);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;	println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{opt:?}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-storage z-type&quot;&gt;	if let&lt;&#x2F;span&gt;&lt;span&gt; z3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SatResult&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sat&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; opt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;check(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;[]) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; opt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_model()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; c1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eval(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c1,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; c5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eval(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c5,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; c10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eval(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c10,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;		println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;; c1: {c1:?}, c5: {c5:?}, c10: {c10:?}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;	}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;		println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;; woe for us&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;smt2&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;declare-fun&lt;&#x2F;span&gt;&lt;span&gt; c10 () Int)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;declare-fun&lt;&#x2F;span&gt;&lt;span&gt; c5 () Int)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;declare-fun&lt;&#x2F;span&gt;&lt;span&gt; c1 () Int)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; (= (+ (* c1&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;) (* c5&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;) (* c10&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;37&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(minimize (+ c1 c5 c10))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;check-sat&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;; c1: 37, c5: 0, c10: 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Oops. This cannot be right.&lt;&#x2F;p&gt;
&lt;p&gt;I do not really understand why the answer is so nonsensical here. The problem is that &lt;code&gt;Int&lt;&#x2F;code&gt; really spans the entire natural integers range, so it is accounting for negative amounts of coins. This still does not explain how the optimal solution given is 37 coins. (If you can explain, please let me know.)&lt;&#x2F;p&gt;
&lt;p&gt;The solution for this&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-mystery-1&quot;&gt;&lt;a href=&quot;#fn-mystery&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; is to constrain the amount of coins to be non-negative. So let&#x27;s do that. Add these assertions somewhere before &lt;code&gt;check&lt;&#x2F;code&gt;, and Bob&#x27;s your uncle.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;opt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ge(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;opt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ge(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;opt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ge(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;smt2&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;declare-fun&lt;&#x2F;span&gt;&lt;span&gt; c1 () Int)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;declare-fun&lt;&#x2F;span&gt;&lt;span&gt; c5 () Int)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;declare-fun&lt;&#x2F;span&gt;&lt;span&gt; c10 () Int)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; (&amp;gt;= c1&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; (&amp;gt;= c5&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; (&amp;gt;= c10&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; (= (+ (* c1&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;) (* c5&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;) (* c10&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;37&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(minimize (+ c1 c5 c10))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;check-sat&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;; c1: 2, c5: 1, c10: 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s more like it.  Now let&#x27;s try with different denominations. Something like 10. 9, and 1. Note that the optimal solution for 37 would be: one 10 coin, three 9 coins, and no 1 coins. The greedy solution would fail to catch that. Here is the output of printing the optimizer and the result.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;smt2&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;declare-fun&lt;&#x2F;span&gt;&lt;span&gt; c1 () Int)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;declare-fun&lt;&#x2F;span&gt;&lt;span&gt; c9 () Int)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;declare-fun&lt;&#x2F;span&gt;&lt;span&gt; c10 () Int)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; (&amp;gt;= c1&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; (&amp;gt;= c9&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; (&amp;gt;= c10&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt; (= (+ (* c1&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;) (* c9&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;) (* c10&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;37&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(minimize (+ c1 c9 c10))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;check-sat&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;; c1: 0, c9: 3, c10: 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Success!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;push-and-pop&quot;&gt;&lt;code&gt;push&lt;&#x2F;code&gt; and &lt;code&gt;pop&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Currently, the total 37 is hardcoded. But what if I want the answers for a number of different totals? Thankfully, you do not need to build the optimizer from scratch for every total. Instead, use the magical functions &lt;code&gt;push&lt;&#x2F;code&gt; and &lt;code&gt;pop&lt;&#x2F;code&gt;. The first one essentially creates a bookmark in the stack of assertions. The second removes everything above said bookmark, and the bookmark. It is simple really. Here are the solutions from 30 to 39, because why not.&lt;&#x2F;p&gt;
&lt;p&gt;Here is the full &lt;code&gt;main&lt;&#x2F;code&gt;. I will spare you the output.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; opt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Optimize&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; c1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new_const(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;c1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; c9&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new_const(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;c9&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; c10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new_const(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;c10&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;opt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ge(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;opt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c9&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ge(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;opt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ge(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; total&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c9&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; + &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c9&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; + &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c10;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;opt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;minimize(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;count);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;; total&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;count&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;c1&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;c9&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;c10&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;30&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-keyword z-operator&quot;&gt;u32..&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;take(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;	print!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;; {t}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	opt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;push();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	opt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;total&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eq(t));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-storage z-type&quot;&gt;	if let&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SatResult&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sat&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; opt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;check(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;[]) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; opt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_model()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; c1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eval(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c1,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;as_u64()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; c9&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eval(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c9,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;as_u64()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; c10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eval(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c10,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;as_u64()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; c1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; c9&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; c10;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;		println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{count}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{c1:?}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{c9:?}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{c10:?}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;	}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;		println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;; woe for us&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	opt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;pop();&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; no RAII for you&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that the &lt;code&gt;push&lt;&#x2F;code&gt; and &lt;code&gt;pop&lt;&#x2F;code&gt; API is available for &lt;code&gt;Solver&lt;&#x2F;code&gt; as well. At any rate, back to solving.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;sudoku&quot;&gt;Sudoku&lt;&#x2F;h2&gt;
&lt;p&gt;This is a significant jump in complexity, so bear with me. We are going to solve a Sudoku.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-js-1&quot;&gt;&lt;a href=&quot;#fn-js&quot;&gt;5&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; So let&#x27;s write the constraints first. We can use Rust&#x27;s arrays or &lt;code&gt;Vec&lt;&#x2F;code&gt; to organize our &lt;code&gt;z3.Int&lt;&#x2F;code&gt;s and check their constraints. First, this is the puzzle we are solving:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;....94.3.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...51...7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.89....4.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;......2.8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.6.2.1.5.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1.2......&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.7....52.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9...65...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.4.97....&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I will forgo the steps to turn that into a &lt;code&gt;[[Option&amp;lt;u8&amp;gt;;9];9]&lt;&#x2F;code&gt;. Instead the code below will get that info from a &lt;code&gt;get_puzzle()&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; Note that we&amp;#39;re using Rust arrays here. The solver does not really know about them.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [[_;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;];&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	array&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from_fn(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; array&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from_fn(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;j&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; Int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new_const(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;format!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;x{i}{j}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; each cell contains a value 1&amp;lt;=x&amp;lt;=9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;iter()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;flatten()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;for_each(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert(i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ge(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;le(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;9&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; each row contains a digit only once&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;grid {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert(Ast&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;distinct(row));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; each column contains a digit only once&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;	let mut&lt;&#x2F;span&gt;&lt;span&gt; col&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;with_capacity(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;9&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;iter()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;for_each(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; col&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;push(r[idx]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;clone()));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert(Ast&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;distinct(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;col))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; each 3x3 contains a digit at most once&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; x_s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;9&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;step_by(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span&gt; y_s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;9&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;step_by(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;		let mut&lt;&#x2F;span&gt;&lt;span&gt; square&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;with_capacity(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;9&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;		for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; (x_s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;take(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;			for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; (y_s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;take(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;				&#x2F;&#x2F; very nested loop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;				square&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;push(grid[x][y]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;clone());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;			}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert(Ast&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;distinct(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;square))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; Finally, assert that each cell equals a provided clue in the given puzzle&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;get_puzzle()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;iter()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;flatten()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;zip(grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;iter()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;flatten())&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;for_each(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;(clue, variable)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-storage z-type z-entity z-name z-type z-option&quot;&gt;	if let Some&lt;&#x2F;span&gt;&lt;span&gt;(clue)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; clue {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert(variable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eq(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;clue));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;eprintln!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{solver:?}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Printing the solver after each step lets you debug whether you have your constraints correctly. The printout is over 200 lines long, so let&#x27;s skip that. All we have to do next is to check the value of each cell in &lt;code&gt;grid&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-storage z-type&quot;&gt;if let&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SatResult&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sat&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;check() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_model()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span&gt; row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; grid {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;		for&lt;&#x2F;span&gt;&lt;span&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; row {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;			let&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eval(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;int,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;			print!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{result:?}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;		println!&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;	println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;Unsolvable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And this prints out the result. You can verify for yourself whether this is correct or not. Maybe try other puzzles. Or add more constraints. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=yKf9aUIxdb4&quot;&gt;You can even try the Miracle Sudoku&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;715894632&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;234516897&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;689723145&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;493657218&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;867231954&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;152489763&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;376148529&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;928365471&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;541972386&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;One thing of note here: which is how &lt;em&gt;dumb&lt;&#x2F;em&gt; the solver is. Note that if you print out the solver, there is no notion of rows and columns and squares. It does not know any Sudoku tricks like X-wings and what have you. All the data is organized on the Rust side of things, and what is given to the solver is &quot;these two variables cannot be the same&quot; over and over and over again. And it just .. tells you what the rest of them are.&lt;&#x2F;p&gt;
&lt;p&gt;Another thing that is not obvious at first glance, is that it does not check if there is a unique solution. The puzzle may be badly constructed and have multiple solutions, and it will happily give you one, or two, or how many you ask for. It does, however, check if it is unsolvable!&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;page-layout&quot;&gt;Page Layout&lt;&#x2F;h2&gt;
&lt;p&gt;One of the famous examples of using solvers in production is .. layouting. You have a number of elements and you want to arrange them on a page, or a browser window, or whatever. So let&#x27;s do a rudimentary version of that.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-simon-1&quot;&gt;&lt;a href=&quot;#fn-simon&quot;&gt;6&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The page we are layouting has an arbitrary size of 190mm width by 270mm tall. We are to put three boxes on the page of varying sizes and rules. I am just spitballing the sizes here: first box is 105mm by 140mm; second is 85 by 135, third is 120 by 110. They should not overlap, and like .. that&#x27;s it?&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; page_width&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 190&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; page_height&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 270&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; box_dims&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;105&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 140&lt;&#x2F;span&gt;&lt;span&gt;), (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;85&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 135&lt;&#x2F;span&gt;&lt;span&gt;), (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;120&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 110&lt;&#x2F;span&gt;&lt;span&gt;)];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; box_locs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; box_dims&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;map(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; left&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;fresh_const(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;x&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; top&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;fresh_const(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; right&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; bottom&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;top&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; assert the boxes fit within the page&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;left&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ge(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;top&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ge(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;right&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;le(page_width));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;bottom&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;le(page_height));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; assert each box aligns to lines. line height is 10mm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;bottom&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;rem(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eq(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	(left, top, right, bottom)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; assert boxes do not overlap&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;box_locs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;len() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span&gt; j&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;box_locs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;len() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; fst_box&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;box_locs[i];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; snd_box&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;box_locs[j];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; tuple structure: (left, top, right, bottom)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; cond_1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; fst_box&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0.&lt;&#x2F;span&gt;&lt;span&gt;ge(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;snd_box&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; fst left &amp;gt;= snd right&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; cond_2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; fst_box&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1.&lt;&#x2F;span&gt;&lt;span&gt;ge(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;snd_box&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; fst top &amp;gt;= snd bottom&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; cond_3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; fst_box&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2.&lt;&#x2F;span&gt;&lt;span&gt;le(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;snd_box&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; fst right &amp;lt;= snd left&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; cond_4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; fst_box&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3.&lt;&#x2F;span&gt;&lt;span&gt;le(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;snd_box&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; fst bottom &amp;lt;= snd top&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;assert(Bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;or(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[cond_1, cond_2, cond_3, cond_4]));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; println!(&amp;quot;{solver:?}&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-storage z-type&quot;&gt;if let&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SatResult&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sat&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;check() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	let&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; solver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get_model()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span&gt; (idx, b)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; box_locs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;into_iter()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;enumerate() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;		print!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;box {}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; left&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eval(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; top&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eval(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; right&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eval(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		let&lt;&#x2F;span&gt;&lt;span&gt; bottom&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eval(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;		println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{left}, {top}, {right}, {bottom}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;	println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;Unsolvable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This prints out this neat solution:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;box 1	85, 0, 190, 140&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;box 2	0, 5, 85, 140&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;box 3	0, 140, 120, 250&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Turned out easier than I thought. Hah.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;epilogue&quot;&gt;Epilogue&lt;&#x2F;h2&gt;
&lt;p&gt;Obviously, all these examples are rather simple. Figuring out how to model the problem in the form of boolean rules and constraints is almost all the challenge. There are some limitations, too: &lt;code&gt;z3&lt;&#x2F;code&gt; cannot solve equations of the sort &lt;code&gt;2^x == 3&lt;&#x2F;code&gt;; it cannot call external functions to get values (though there are ways to work around that).&lt;&#x2F;p&gt;
&lt;p&gt;There is plenty of stuff I have not shown. &lt;code&gt;Array&lt;&#x2F;code&gt;s, which are nothing like programming language arrays and more mappings from one domain to another. &lt;code&gt;BV&lt;&#x2F;code&gt;, bit vectors, which allow bitwise operations on their values like &lt;code&gt;and&lt;&#x2F;code&gt; and &lt;code&gt;or&lt;&#x2F;code&gt; and bit shifting. (Which are the key to solving &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-hanging-gardens-problem&#x2F;&quot;&gt;the Hanging Gardens Problem&lt;&#x2F;a&gt;.) &lt;code&gt;Set&lt;&#x2F;code&gt;s and &lt;code&gt;Seq&lt;&#x2F;code&gt;s and &lt;code&gt;String&lt;&#x2F;code&gt;s and regexes and stuff I have not really looked into. Unfortunately, most resources on the web are a bit heavy on theory, and are not targeted to stupid coders like myself.&lt;&#x2F;p&gt;
&lt;p&gt;Until later.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-jargon&quot;&gt;
&lt;p&gt;Domain specific terminology. &lt;a href=&quot;#fr-jargon-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-dsl&quot;&gt;
&lt;p&gt;Probably not true. For all I know the C API constructs the model directly without the intermediate step. However, I found it much easier to understand them in this manner. &lt;a href=&quot;#fr-dsl-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-float&quot;&gt;
&lt;p&gt;Can also use &lt;code&gt;Float&lt;&#x2F;code&gt;. &lt;a href=&quot;#fr-float-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-mystery&quot;&gt;
&lt;p&gt;Again, for reasons I do not understand. &lt;a href=&quot;#fr-mystery-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-js&quot;&gt;
&lt;p&gt;This example is translated from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;microsoft.github.io&#x2F;z3guide&#x2F;programming&#x2F;Z3%20JavaScript%20Examples#solve-sudoku&quot;&gt;The &lt;code&gt;z3&lt;&#x2F;code&gt; Guide&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-js-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-simon&quot;&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;typo.social&#x2F;@simoncozens&#x2F;115197804741172296&quot;&gt;I got the suggestion for this from Simon Cozens&lt;&#x2F;a&gt;. Admittedly, implementation of this section was aided by a Robot. &lt;a href=&quot;#fr-simon-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Define Zig Enums from Data</title>
        <published>2025-08-13T00:00:00+00:00</published>
        <updated>2025-08-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/thoughts/define-zig-enums-from-data/"/>
        <id>https://ar-ms.me/thoughts/define-zig-enums-from-data/</id>
        
        <content type="html" xml:base="https://ar-ms.me/thoughts/define-zig-enums-from-data/">&lt;p&gt;I am working currently on a small Zig library which I am not quite ready to talk about yet. However, it involves parsing a big table of data and then doing operations based on that data.&lt;&#x2F;p&gt;
&lt;p&gt;For the remainder of this article, I shall pretend the library is about wind directions.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note that this article uses Zig &lt;code&gt;0.14.1&lt;&#x2F;code&gt;. Big changes have happened in the &lt;code&gt;master&lt;&#x2F;code&gt; branch since that was released. Though the parts discussed are probably still the same.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;library-structure-outline&quot;&gt;Library Structure Outline&lt;&#x2F;h2&gt;
&lt;p&gt;There is a data file called &lt;code&gt;WindData.txt&lt;&#x2F;code&gt;. It looks something like this.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-gemini-1&quot;&gt;&lt;a href=&quot;#fn-gemini&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;00;Mistral;N&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;01;Bora;N&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;02;Sirocco;S&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;03;Khamaseen;S&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;04;Chinook;W&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;05;Zonda;W&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;06;Föhn;S&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;07;Santa Ana;E&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;08;Harmattan;E&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;09;Leste;E&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0A;Pampero;S&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0B;Nor&amp;#39;easter;N&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0C;Southerly Buster;S&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0D;Berg Wind;E&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0E;Vendavales;S&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This text file is parsed by a &lt;code&gt;generate.zig&lt;&#x2F;code&gt; file that organizes winds by their direction. The data is put into a &lt;code&gt;wind_data.zon&lt;&#x2F;code&gt; file, which is added by the build system as an &lt;code&gt;Import&lt;&#x2F;code&gt; so it is simply imported into the code base and .. calculated on.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;enum&lt;&#x2F;code&gt; that describes wind directions is duplicated between the main code base and &lt;code&gt;generate.zig&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Direction&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; { N, E, S, W };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;problem-statement&quot;&gt;Problem Statement&lt;&#x2F;h2&gt;
&lt;p&gt;What if a new version of the data adds a new wind direction: &lt;code&gt;U&lt;&#x2F;code&gt; (for Upwards)? Now the code fails! It needs a way to create the type out of the data.&lt;&#x2F;p&gt;
&lt;p&gt;A rational person would just add the new direction manually, because the algorithms depending on it are going to need to change anyway.&lt;&#x2F;p&gt;
&lt;p&gt;The normal solution (in widely used rust crate &lt;code&gt;wind-direction&lt;&#x2F;code&gt;, for example) is good old fashioned code generation using a &lt;code&gt;generate.py&lt;&#x2F;code&gt; script that is run manually every once in a while by the maintainers, which generates a &lt;code&gt;tables.rs&lt;&#x2F;code&gt; file that includes the above enum.&lt;&#x2F;p&gt;
&lt;p&gt;But this is Zig. Things are not done with code generation. Things are done with &lt;code&gt;comptime&lt;&#x2F;code&gt; and build systems!&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;generate-zig&quot;&gt;&lt;code&gt;generate.zig&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;I will spare you the boring mechanical parts of &lt;code&gt;generate.zig&lt;&#x2F;code&gt; that read a file and iterate over each line and collects the data into some sort of hashmap. The interesting bit I want to talk about is generating &lt;code&gt;type-definition.zon&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;During file reading, all the direction strings are collected into a set to make sure there are no repeats. This is simple enough code.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;var&lt;&#x2F;span&gt;&lt;span&gt; set: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;StringArrayHashMapUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .empty;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; later in the loop,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt; set.put(gpa, wind_direction_string, {});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After the set is collected, it needs to be serialized into &lt;code&gt;zon&lt;&#x2F;code&gt; (which is Zig&#x27;s own &lt;code&gt;json&lt;&#x2F;code&gt;-like data type). This is as simple as outputting text to a file, but the Zig standard library provides some helpful builtins.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-json-1&quot;&gt;&lt;a href=&quot;#fn-json&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; This is easiest way I found to serialize the strings to what Zig calls &lt;code&gt;enum_literal&lt;&#x2F;code&gt;s. (I will get back to that).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; out&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.io.getStdOut().writer();&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- replace with output file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; after finishing up the set.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; directions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; set.keys();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;var&lt;&#x2F;span&gt;&lt;span&gt; sz&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.zon.stringify.serializer(out, .{});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;var&lt;&#x2F;span&gt;&lt;span&gt; container&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; sz.beginTuple(.{});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; (directions,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;..) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;direction, idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt; sz.writer.writeByte(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;,&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; a bit hacky but w&#x2F;e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; sz.ident(direction);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt; container.end();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; maybe should print a new line here too?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And voila! Here is the happy &lt;code&gt;data.zon&lt;&#x2F;code&gt;. Note that this is written to an output file, not &lt;code&gt;stdout&lt;&#x2F;code&gt; like the code snippet below.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.{.N,.E,.S,.W}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;build-zig&quot;&gt;&lt;code&gt;build.zig&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;This is the least interesting part. It is just plumbing. Here is the code. It would get invoked whenever &lt;code&gt;zig build&lt;&#x2F;code&gt; commands are called, and cached accordingly, hopefully?&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; calling genrate script&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; generate_wind_data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.addExecutable(.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;wind_dir_data&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .root_source_file&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.path(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;tools&#x2F;generate.zig&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.graph.host,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; generate_step&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.addRunArtifact(generate_wind_data);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;generate_step.addFileArg(b.path(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;WindData.txt&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; wind_zon&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; generate_step.addOutputFileArg(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;data.zon&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; Main library.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; lib_mod&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.createModule(.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .root_source_file&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.path(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;src&#x2F;lib.zig&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; target,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .optimize&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; optimize,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; piping the two&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lib_mod.addAnonymousImport(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;wind_tables&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ .root_source_file&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; wind_zon },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And that&#x27;s it. Fairly simple code if you&#x27;re familiar with the Zig build system.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-library&quot;&gt;The Library&lt;&#x2F;h2&gt;
&lt;p&gt;Here is the cool stuff, if I may. Since this for defining a normal, non-generic type, we shall start it thus. All the code in the following snippets will be in there.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; WindData&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; WD: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; All following code is in here.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;First, we need to &lt;code&gt;@import&lt;&#x2F;code&gt; the data. That&#x27;s why it is in a &lt;code&gt;zon&lt;&#x2F;code&gt; file to begin with! But import as what type? In &lt;code&gt;0.14.1&lt;&#x2F;code&gt;, we still need to define the types &lt;code&gt;zon&lt;&#x2F;code&gt; imports (a restriction I understand is lifted in &lt;code&gt;master&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Zig has a special &lt;code&gt;comptime&lt;&#x2F;code&gt; only type called &lt;code&gt;enum_literal&lt;&#x2F;code&gt;. Oddly enough, unlike &lt;code&gt;comptime_int&lt;&#x2F;code&gt; and &lt;code&gt;comptime_float&lt;&#x2F;code&gt;, you cannot just do this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; does not compile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; foo: enum_literal&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .bar;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The type can actually be written out as &lt;code&gt;@TypeOf(.enum_literal)&lt;&#x2F;code&gt;. Sure. A &lt;code&gt;const&lt;&#x2F;code&gt; slice of those would be &lt;code&gt;[]const @TypeOf(.enum_literal)&lt;&#x2F;code&gt;. Not that you need the &lt;code&gt;const&lt;&#x2F;code&gt; here for deserialization, as you cannot deserialize into a mutable slice.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; data: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @TypeOf&lt;&#x2F;span&gt;&lt;span&gt;(.enum_literal) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @import&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;test.zon&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then we need to iterate over the fields and convert them, one by one, to another type. This time it is &lt;code&gt;std.builtin.Type.EnumField&lt;&#x2F;code&gt;. An array of which will become our final &lt;code&gt;enum&lt;&#x2F;code&gt;. We create a &lt;code&gt;BoundedArray&lt;&#x2F;code&gt; at home with just an index and an iterator. This code was pretty much lifted from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mitchellh.com&#x2F;writing&#x2F;zig-comptime-tagged-union-subset&quot;&gt;Mitchell Hashimoto&#x27;s &#x27;Tagged Union Subsets with Comptime in Zig&#x27; article&lt;&#x2F;a&gt;, which is actually the inspiration for &lt;em&gt;this&lt;&#x2F;em&gt; post.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-matklad-1&quot;&gt;&lt;a href=&quot;#fn-matklad&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;var&lt;&#x2F;span&gt;&lt;span&gt; i:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt; usize =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;var&lt;&#x2F;span&gt;&lt;span&gt; fields: [data.len]std.builtin.Type.EnumField&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; undefined&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; outer: &#x2F;&#x2F; uneeded block label. see below&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; (data) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;literal&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @tagName&lt;&#x2F;span&gt;&lt;span&gt;(literal);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; &#x2F;&#x2F; Deduplication code. It is not needed because the file is&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; &#x2F;&#x2F; generated from a hash set.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; for (fields[0..i]) |f|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;     if (std.mem.eql(u8, f.name, name))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;         continue :outer;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    fields[i] &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; name,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; i,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we simply create the &lt;code&gt;enum&lt;&#x2F;code&gt; with the helpful builtin &lt;code&gt;@Type&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt; :WD&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @Type&lt;&#x2F;span&gt;&lt;span&gt;(.{ .@&amp;quot;enum&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .tag_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-type z-integer z-zig&quot;&gt; = usize&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .fields&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; fields[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..i],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .decls&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .is_exhaustive&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-bool z-zig&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; maybe?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;} });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Fairly simple. One small trick remains. &lt;code&gt;tag_type&lt;&#x2F;code&gt; is not an optional value, so we need to specify it. It is the integer that should hold the results of the enum.. &lt;code&gt;usize&lt;&#x2F;code&gt; is playing it safe, because it is extremely unlikely to hold more than .. whatever the largest &lt;code&gt;usize&lt;&#x2F;code&gt; is. But that&#x27;s a very big enum for something than potentially fit into one byte. So it is incumbent upon us to create the smallest integer possible.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; backing_int:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig z-keyword z-operator z-assignment&quot;&gt; type =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @Type&lt;&#x2F;span&gt;&lt;span&gt;(.{ .int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .bits&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; what to put here??&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .signedness&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .unsigned,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;} });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To calculate the smallest number of bits that can hold our &lt;code&gt;fields&lt;&#x2F;code&gt; count, two simple (for computers at least) math operations are needed. First, &lt;code&gt;i&lt;&#x2F;code&gt; (our counter) is raised to the nearest power of two. Then the &lt;code&gt;log2&lt;&#x2F;code&gt; is taken from it. Boom. Two &lt;code&gt;std.math&lt;&#x2F;code&gt; function calls and that is IT.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; next_p_of_2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.math.ceilPowerOfTwoAssert(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; bits&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.math.log2_int(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, next_p_of_2);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And this does it. Here is the full code.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; WindData&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; WD: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; data: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @TypeOf&lt;&#x2F;span&gt;&lt;span&gt;(.enum_literal) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @import&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;test.zon&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; i:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt; usize =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; fields: [data.len]std.builtin.Type.EnumField&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; undefined&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; (data) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;literal&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @tagName&lt;&#x2F;span&gt;&lt;span&gt;(literal);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        fields[i] &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; name,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; i,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; next_p_of_2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.math.ceilPowerOfTwoAssert(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; bits&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.math.log2_int(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, next_p_of_2);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    break&lt;&#x2F;span&gt;&lt;span&gt; :WD&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @Type&lt;&#x2F;span&gt;&lt;span&gt;(.{ .@&amp;quot;enum&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .tag_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @Type&lt;&#x2F;span&gt;&lt;span&gt;(.{ .int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .bits&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bits,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .signedness&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .unsigned,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        } }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .fields&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; fields[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..i],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .decls&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .is_exhaustive&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-bool z-zig&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Your &lt;code&gt;enum&lt;&#x2F;code&gt; is ready. Now your data definition is resilient to new types added to the database. You still need to fix all the &lt;code&gt;switch&lt;&#x2F;code&gt; statements, tho.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;In the actual library I just put out the enum definition into its own separate file that is imported by both &lt;code&gt;generate.zig&lt;&#x2F;code&gt; and the library. But hey, this was a fun exercise.&lt;&#x2F;p&gt;
&lt;p&gt;Until later.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-gemini&quot;&gt;
&lt;p&gt;Generated with Gemini help. &lt;a href=&quot;#fr-gemini-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-json&quot;&gt;
&lt;p&gt;Unlike formatting and &lt;code&gt;json&lt;&#x2F;code&gt; serialization, &lt;code&gt;zon&lt;&#x2F;code&gt; serialization does not seem to depend on defining &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.openmymind.net&#x2F;Writing-Json-To-A-Custom-Output-in-Zig&#x2F;&quot;&gt;specific magic functions&lt;&#x2F;a&gt; to customize the behaviour. &lt;a href=&quot;#fr-json-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-matklad&quot;&gt;
&lt;p&gt;Also, slightly related, is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;matklad.github.io&#x2F;2025&#x2F;08&#x2F;08&#x2F;partially-matching-zig-enums.html&quot;&gt;matklad&#x27;s Partially Matching Zig Enums&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-matklad-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>LLMs in the Building Industry</title>
        <published>2025-07-13T00:00:00+00:00</published>
        <updated>2025-07-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/thoughts/llms-in-the-building-industry/"/>
        <id>https://ar-ms.me/thoughts/llms-in-the-building-industry/</id>
        
        <content type="html" xml:base="https://ar-ms.me/thoughts/llms-in-the-building-industry/">&lt;p&gt;This is a collection of ideas that may or may not be feasible to implement or to have as the base idea of a start up. It is &lt;em&gt;not&lt;&#x2F;em&gt; a structured document, but more of a stream of thought.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ifc&quot;&gt;IFC&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Industry_Foundation_Classes&quot;&gt;Industry Foundation Classes&lt;&#x2F;a&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-ifc-1&quot;&gt;&lt;a href=&quot;#fn-ifc&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; is an open source data format for modeling BIM (Building Information Modeling). It is supported by Revit, the market leader. A well known open source implementation is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;bonsaibim.org&quot;&gt;Bonsai BIM&lt;&#x2F;a&gt;. I &lt;em&gt;believe&lt;&#x2F;em&gt; the implementation is inherently text based and can be accessed with programmer oriented tooling such as &lt;code&gt;git&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;There are graphical tools that allow the user to see the difference between two files visually. An added wall in this revision would show up as green, for example. A deleted wall would be shown in red. This is all existing tooling.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;for-potential-homeowners&quot;&gt;For Potential Homeowners&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;scenario&quot;&gt;Scenario&lt;&#x2F;h3&gt;
&lt;p&gt;Imagine the following: a website where a client can submit their plot details, their budget, and make a write up on what they want in their dream house.&lt;&#x2F;p&gt;
&lt;p&gt;For example: They have three kids and their eldest wants to be a ballerina so they need a dance studio space. The father works from home so he needs a home office and a quiet space for virtual meetings. The mother is a hobbyist swimmer so they want a swimming pool. They have no need for a specific guest space, etc. Whatever a potential customer would tell their architect.&lt;&#x2F;p&gt;
&lt;p&gt;The website would take the hard data from the plot and the plot&#x27;s location, and the specifics of the local area building code, and the text description provided by the client (the more detailed the better). Then out of these disparate pieces of the info and combine them together into the ideal house for the subject.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sanity-checks&quot;&gt;Sanity Checks&lt;&#x2F;h3&gt;
&lt;p&gt;This would require some sort of sanity checker to verify the results, similar to how LLM-based coding agents work with compilers and language serverso.[lsp] The LLMs hallucinate whatever they want, and the Editor tells them whether the code compiles or not. Sanity checks include, but are not limited to, code compliance, cost overruns, &quot;there is a room without a door&quot;, etc.&lt;&#x2F;p&gt;
&lt;p&gt;This process can be automated very far. IFC can include data relevant to the other disciplines than Architecture. Most importantly, structural design. This should be an algorithmic task as it is a life and death matter and there is no room for &lt;del&gt;hallucinations&lt;&#x2F;del&gt; creativity. The other disciplines such as plumbing, electric wiring, etc is doable and any mistakes can be easily adjusted (or completely ignored) on site by the installation teams.&lt;&#x2F;p&gt;
&lt;p&gt;The IFC files also include dimensions. Combine that with the specifications, or the approved suppliers, (which the client may or may not choose from a drop down menu), and you get a quick and easy to calculate cost.&lt;&#x2F;p&gt;
&lt;p&gt;There &lt;em&gt;must&lt;&#x2F;em&gt; be a qualified human reviewer, as the final sanity check. More importantly, to shoulder the legal liability of architectural and structural designs.&lt;&#x2F;p&gt;
&lt;p&gt;The price could be fairly cheap: 1,000SAR for one plan. The absolute cheapest office is about 5,000, and these are the ones just pulling a predesigned house out of the drawer.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;scale&quot;&gt;Scale&lt;&#x2F;h3&gt;
&lt;p&gt;Working at scale, a similar technology can be used to benefit real estate developers. Instead of the usual cookie cutting measure of a thousand identical houses, variation can be made in each individual unit. Depending on the construction methods used, this might not be more expensive to actually build than cookies.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;for-engineering-offices&quot;&gt;For Engineering Offices&lt;&#x2F;h2&gt;
&lt;p&gt;There are many different professions working in a regular Engineering&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-chagrin-1&quot;&gt;&lt;a href=&quot;#fn-chagrin&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; practice. This is an overview following the different stages of a project.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;client-brief&quot;&gt;Client Brief&lt;&#x2F;h3&gt;
&lt;p&gt;Every project starts with a brief.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-brief-1&quot;&gt;&lt;a href=&quot;#fn-brief&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; The brief includes an intro the project and the different stakeholders and potential desires etc. To respond to the brief, offices are required usually to make both a technical offer and a financial offer.&lt;&#x2F;p&gt;
&lt;p&gt;The technical offer is essentially a listing of the Office&#x27;s capabilities. What is their experience like? What are their core competencies? What big projects they have done before? And what have you. The exact format is usually specified by the client, in the brief, but the details are generally all the same. The same info and files are regurgitated between different projects.&lt;&#x2F;p&gt;
&lt;p&gt;The financial offer is more of the same. It is based on however the office wants to to price the subject. The structure of which is also often dictated by the brief. It could be by man hours or by lump sum or depending on the phase of the moon. The cost can depends on the size of the project and the nature of the client (government vor private).&lt;&#x2F;p&gt;
&lt;p&gt;This is a lot of clerical and reptitive work that nonetheless must be customized for each client. It involves a large number of staff from different departments: accounting, secretaries, engineering, const estimation (which could fall under engineering).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;specifications&quot;&gt;Specifications&lt;&#x2F;h3&gt;
&lt;p&gt;Specifications are the most important, and perhaps the most overlooked, part of the design documents. They can either be dictated by the client or, more appropriately, delivered as part of the service.&lt;&#x2F;p&gt;
&lt;p&gt;First, a brief explanation of what Specifications &lt;em&gt;are&lt;&#x2F;em&gt;. Take for example masonry. The specification for masonry should specify the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Potential suppliers,&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-saudi-1&quot;&gt;&lt;a href=&quot;#fn-saudi&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Desired properties: size, material,&lt;&#x2F;li&gt;
&lt;li&gt;How to install&lt;&#x2F;li&gt;
&lt;li&gt;How to maintain&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Sepcifications for large projects can include everything up to the type of screw used to fasten the furniture together. They would be used by the eventual contractor to procure the proper materials.&lt;&#x2F;p&gt;
&lt;p&gt;A common practice in offices is to have a local databaee of approved, or potential, suppliers of different building materials. Indeed Engineering offices are often the first line of marketing for any building material supplier.&lt;&#x2F;p&gt;
&lt;p&gt;Large offices have their own specifications library. Others make them up as they go along based on the experience of the engineer responsible for them at the time, copy pasting at need from previous projects. Some companies actually sell their specifications, and supplier databses, to potential Architectural offices. One example of that is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.aia.org&#x2F;masterspec&quot;&gt;AIA MasterSpec&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A potential use of LLMs here is to genrate these specifications from a local supplier database. Perhaps even contrasting that with the client&#x27;s brief and their desired level of quality. The Model could be given a template for specifications, or the specirications for a previous project, and directed to generate specificatiosn based on the design drawings and written guidelines and up to date supplier database.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;consultancy&quot;&gt;Consultancy&lt;&#x2F;h3&gt;
&lt;p&gt;Work for Engineering offices is not restricted to design. Indeed the more profitable line of work is construction consultancy, or supervision. Reviewing the contraxctor&#x27;s submittals for materials, shop drawings,&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-shop-1&quot;&gt;&lt;a href=&quot;#fn-shop&quot;&gt;5&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; staff listings, Requests For Clarification (RFCs), and what have you.&lt;&#x2F;p&gt;
&lt;p&gt;The reviews could be given to a LLM, as a first pass before a human reviewer looks at them. But I do not think this is a valuable use as the details that would fail a review, especially for technical drawings, are something that is still currently beyond the scope of language models.&lt;&#x2F;p&gt;
&lt;p&gt;I will touch on this again when talking about contractors, but a record of all communication is extremely important to maintain throughtout the life cycle of the project. If, say, a feature of the building turned out not to have the desired quality, the consultant can point to the communication where they denied the contractor&#x27;s shop drawings or chosen materials, but were overruled by the client in the interest of expediency or whatever. Someone, or something, which can read and remember and vaguely understand the conversation, would be invaluable to, well, win arguments.&lt;&#x2F;p&gt;
&lt;p&gt;The methods of communication vary by project. Either they are official stamped by the treplicate official letters, or more commonly WhatsApp messages, or anything inbetween.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;for-construction-companies&quot;&gt;For Construction Companies&lt;&#x2F;h2&gt;
&lt;p&gt;Much of the talk about the client briefs and comparing specifications with suppliers database applies here as well. Searching a local database, not necessarily neatly organized with all the relevant info buried in PDFs and websites, to find suppliers whose products match the given specifications.&lt;&#x2F;p&gt;
&lt;p&gt;There are also many applications for logistics. How to store the materials and how to transport the materials and how to protect them from the elements are all common challenged. But not unique to construction work. So solutions from other industries (such as manufacturing) could be used.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;cost-estimations&quot;&gt;Cost Estimations&lt;&#x2F;h3&gt;
&lt;p&gt;This is perhaps a task more appropriate for proper old algorithms than language models. but a common painpoint small contractors have is how to properly estimate the cost of a building, based on drawings and a client brief. The drawings themselves are usually presented as PDFs or as DWG files (sometimes). One would be truly lucky to get the drawings in IFC (or really any BIM) format. PDFs and DWGs include no metadata about the project&#x27;s elements. The data is provided by things designed for human readers: hatching, dimensions, and labels.&lt;&#x2F;p&gt;
&lt;p&gt;There are a few ways this can be approached. Either reading the drawings as a human would: looking up the labels and cross referencing them with the specifications (if any). Measuring the length of different elements, walls and windows and what have you, multiplying that by estimated labor and material costs. All directly from the drawings.&lt;&#x2F;p&gt;
&lt;p&gt;The other approach is to create a IFC model based on the drawings, and have the regular BIM tooling to calcluate this data. The prices could be tied to some live database of material prices, or not.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;waste-reduction&quot;&gt;Waste Reduction&lt;&#x2F;h3&gt;
&lt;p&gt;Note this common particular scenario. Structual steel reinforcement comes in 12m long bars. A common floor height is 4m. However, due to structual requirements that are beyond my understanding, the bars embedded in columns should be one meter longer. This means that one bar can be cut in two 5m long pieces. You end up with a useless wasted 2m piece. There are about 12 bars in every column and the floor of a typical house can have around 25 columns. You do the marh.&lt;&#x2F;p&gt;
&lt;p&gt;There are different ways to solve this: a price concious Structural Engineer can reuse the same bar width in different locations allowing every piece to be used for other building elements.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-weld-1&quot;&gt;&lt;a href=&quot;#fn-weld&quot;&gt;6&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; Excellent, and expensive, labor force can find creative uses for the waste. Or the project manager can sell them for scrap to another project that might use them.&lt;&#x2F;p&gt;
&lt;p&gt;The problem exists beyond structural steel, however. Masnory units can have up to 15% waste or more, due to very different factors. Getting careful labor that minimizes waste is potentially more expensive than the material wasted. Different building methods, such as bearing walls, are not quite .. approved of in the local market.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-refrain-1&quot;&gt;&lt;a href=&quot;#fn-refrain&quot;&gt;7&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; A resourceful project manager or designer can find creative uses for the waste.&lt;&#x2F;p&gt;
&lt;p&gt;I am actualy unsure how algorithms or AI can help here. I am mostly typing out thoughts.&lt;&#x2F;p&gt;
&lt;p&gt;However, in a regular concrete building, a commonly used perishable, but expensive, material is formwork. Most formwork used in Saudi Arabia is wood: either plywood or &quot;white wood&quot;. It is expensive to buy. Expensive to rent. And it is necessary to cut to fit the weird concrete shapes architects come up with. And laborers, especially if it is not &lt;em&gt;their&lt;&#x2F;em&gt; wood, are extremely careless in economizing it.&lt;&#x2F;p&gt;
&lt;p&gt;A few real life products can be used to solve this problem. Aluminum and Plastic based formwork is infinitely more reusable, but because it cannot be cut, it is not as flexible for different shapes.&lt;&#x2F;p&gt;
&lt;p&gt;the ideal solution would be to design, from the start, for minimizing formwork waste. However, as this is the Contractors section, an algorithm to minimize waste on a given design (how to cut the boards in a reusable manner, etc.) would be extremely useful to contractors.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;clarifications-and-change-orders&quot;&gt;Clarifications and Change Orders&lt;&#x2F;h3&gt;
&lt;p&gt;Managing clients and consultants is perhaps the Contractor&#x27;s most difficult task. The scopes keep on expanding and the specifications keep on tightening while prices and schedules are expected to remain the same. The drawings or specificiations are often incomplete and missing vital info, or just plain wrong.&lt;&#x2F;p&gt;
&lt;p&gt;Having a record of all communications (often called Document Management) is extremely important for all parties involved. Being able to search and query the often disorganized communication records to find all the different instructions from the client and consultant is evidently important.&lt;&#x2F;p&gt;
&lt;p&gt;These clarifications can begin even before signing the contract. When bidding on the project, the contractor is expected, but not really, to completely understand and fully evaluate the contract documents (drawings and specifications), and point out any missing info. A bid is, usually, essentially, an agreement that the contract documents are completely clear. However, analysis and fully reading and grokking the documents is very time consuming, potentally money-losing, work. Automating that discovery phase would be a huge boon to contractors bidding.&lt;&#x2F;p&gt;
&lt;p&gt;The Model does not need to be extremely accurate. A few false negatives and false positives would be very tolerated, as long as it is more accuracy than a human reviewer in a reasonable amount of time (a couple of work days, maybe). You would get the contract documents, feed them to the Model, perhaps with prior art, and ask does it have any ommisions or incomplete specifications of unlabelled, unspecified, elements or any contradictions. A human reviewer would go over whatever the Model flags and go on with their day.&lt;&#x2F;p&gt;
&lt;p&gt;This verification step cen be useful for Engineering Offices as well.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;In conclusion, this documents outlines a few ways which Large Language Models and Algorithms can be used to ease the pain of the different people in the construction process. These omit some things like dealing with government regulations and accounting and human resources and what have you: the lements common in almost eveyr business. But it tpouches, instead, what is perhaps unique to the profession.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-ifc&quot;&gt;
&lt;p&gt;A pun on &quot;Issued For Construction&quot;. &lt;a href=&quot;#fr-ifc-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-chagrin&quot;&gt;
&lt;p&gt;Including Architectural and Urban Planning practices. &lt;a href=&quot;#fr-chagrin-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-brief&quot;&gt;
&lt;p&gt;Basically what the potential homeowner in the previous example wrote in our website&#x27;s entry &lt;a href=&quot;#fr-brief-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-saudi&quot;&gt;
&lt;p&gt;Not allowed in Saudi government contracts, I believe. &lt;a href=&quot;#fr-saudi-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-shop&quot;&gt;
&lt;p&gt;Exact drawings of what will &lt;em&gt;actually&lt;&#x2F;em&gt; be built. &lt;a href=&quot;#fr-shop-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-weld&quot;&gt;
&lt;p&gt;Unfortunately, apprently welding two bars together is not an acceptable option. &lt;a href=&quot;#fr-weld-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-refrain&quot;&gt;
&lt;p&gt;&quot;What if I need to change the layout?&quot; is a common refrain, even if nobody actually does. &lt;a href=&quot;#fr-refrain-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Writing a C Compiler, in Zig</title>
        <published>2025-06-17T00:00:00+00:00</published>
        <updated>2025-06-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/thoughts/c-compiler-1-zig/"/>
        <id>https://ar-ms.me/thoughts/c-compiler-1-zig/</id>
        
        <content type="html" xml:base="https://ar-ms.me/thoughts/c-compiler-1-zig/">&lt;p&gt;This is a series of articles I wrote while writing &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;asibahi&#x2F;paella&quot;&gt;&lt;code&gt;paella&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, following Nora Sandler&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;norasandler.com&#x2F;2022&#x2F;03&#x2F;29&#x2F;Write-a-C-Compiler-the-Book.html&quot;&gt;Writing a C Compiler&lt;&#x2F;a&gt;. It was both an exercise to learn Zig and a way to waste time instead of looking for work, as I am currently &quot;between jobs&quot;. I did not edit them as I collect them here outside of fixing some broken links.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;paella&#x2F;c1&#x2F;&quot;&gt;Chapter 1: Intro&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;paella&#x2F;c2&#x2F;&quot;&gt;Chapter 2: Unary&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;paella&#x2F;c3&#x2F;&quot;&gt;Chapter 3: Binary&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;paella&#x2F;c4&#x2F;&quot;&gt;Chapter 4: Logic&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;paella&#x2F;c5&#x2F;&quot;&gt;Chapter 5: Variables&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;paella&#x2F;c6&#x2F;&quot;&gt;Chapter 6: Conditions&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;paella&#x2F;c7&#x2F;&quot;&gt;Chapter 7: Blocks&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;paella&#x2F;c8&#x2F;&quot;&gt;Chapter 8: Loops&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;paella&#x2F;c9&#x2F;&quot;&gt;Chapter 9: Functions&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;paella&#x2F;c10&#x2F;&quot;&gt;Chapter 10: Linking&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If&#x2F;when I continue with the book, I shall post the following writeups here.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Chapter 10: Linking</title>
        <published>2025-06-04T00:00:00+00:00</published>
        <updated>2025-06-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/paella/c10/"/>
        <id>https://ar-ms.me/paella/c10/</id>
        
        <content type="html" xml:base="https://ar-ms.me/paella/c10/">&lt;p&gt;This is the final chapter of Part 1 of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;norasandler.com&#x2F;2022&#x2F;03&#x2F;29&#x2F;Write-a-C-Compiler-the-Book.html&quot;&gt;Writing a C Compiler&lt;&#x2F;a&gt;. Something about static variables?&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lexer&quot;&gt;Lexer&lt;&#x2F;h2&gt;
&lt;p&gt;The Book spends 15 pages talking about linkage and static variabeles and tentative declarations, etc, before it gets to the lexer. Only two new keywrods are needed: &lt;code&gt;static&lt;&#x2F;code&gt; and &lt;code&gt;extern&lt;&#x2F;code&gt;. This is the current keyword static map:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; keywords&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;StaticStringMap&lt;&#x2F;span&gt;&lt;span&gt;(Tag).initComptime(.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;int&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .type_int },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;return&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .keyword_return },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;void&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .keyword_void },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;if&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .keyword_if },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;else&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .keyword_else },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;do&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .keyword_do },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;while&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .keyword_while },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;for&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .keyword_for },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;break&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .keyword_break },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;continue&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .keyword_continue },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;static&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .keyword_static },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;extern&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .keyword_extern },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As a small update to the lexer&#x27;s API, I added a &lt;code&gt;next_force&lt;&#x2F;code&gt; function that returns an error union rather than an option, as it is easier to deal with at the call site.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub inline fn&lt;&#x2F;span&gt;&lt;span&gt; next_force(self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Tokenizer) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;Token {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; self.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.NotEnoughJunk;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; usage&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;var&lt;&#x2F;span&gt;&lt;span&gt; token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; tokens.next_force();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; rather than&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;var&lt;&#x2F;span&gt;&lt;span&gt; token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() orlse&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.NotEnoughJunk;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;ast-and-parser&quot;&gt;AST and Parser&lt;&#x2F;h2&gt;
&lt;p&gt;The parser requires deeper changes. First of all, as &lt;code&gt;Prgm&lt;&#x2F;code&gt; changed from a single function to multiple functions last chapter, now it is a list of &lt;em&gt;declarations&lt;&#x2F;em&gt;. Also, &lt;code&gt;static&lt;&#x2F;code&gt; and &lt;code&gt;extern&lt;&#x2F;code&gt; belong, by themselves, to a new semi-node for &quot;storage class specifiers&quot;, that is an optional parameter for function and variable declarations. Since a declaration cannot be both &lt;code&gt;static&lt;&#x2F;code&gt; &lt;em&gt;and&lt;&#x2F;em&gt; &lt;code&gt;extern&lt;&#x2F;code&gt;, this makes it a simple enum.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Prgm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    funcs: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SegmentedList&lt;&#x2F;span&gt;&lt;span&gt;(Decl,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; StorageClass&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; { static, @&amp;quot;extern&amp;quot; };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; FuncDecl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    sc:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt;StorageClass,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;--&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    params: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SegmentedList&lt;&#x2F;span&gt;&lt;span&gt;(Identifier,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    block:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt;Block,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; VarDecl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    sc:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt;StorageClass,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;--&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name: Identifier,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    init:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; ?*&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Changes to &lt;code&gt;parse_prgm&lt;&#x2F;code&gt; are simple enough. There already is a &lt;code&gt;parse_decl&lt;&#x2F;code&gt; so I will just use that one when iterating. Parsing specifiers is interesting and annoying, as I relied before on looking for the &lt;code&gt;int&lt;&#x2F;code&gt; token, now it can be anything! Consider these tqo equally valid variable declarations.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;static&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; example1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt; static&lt;&#x2F;span&gt;&lt;span&gt; example2 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There is no set order. Whose genius idea was this? Thankfully I do not have to think of this on my own, as the book privdes a nice pseudocode functon to parse them. When I was doing my Rust implementation, where I was using &lt;code&gt;nom&lt;&#x2F;code&gt; for parsing, I could not actually figure out to make it nicer than what the Book already provided. Here is the function translated from pseudo code to Zig.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-types-1&quot;&gt;&lt;a href=&quot;#fn-types&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_storage_class(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!?&lt;&#x2F;span&gt;&lt;span&gt;ast.StorageClass {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; type_seen&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-bool z-zig&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; sc:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt;ast.StorageClass&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (tokens.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;nt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (nt.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .type_int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; type_seen&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-bool z-zig&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .keyword_static&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .static&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.InvalidStorageClass,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .keyword_extern&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .@&amp;quot;extern&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.InvalidStorageClass,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tokens.put_back(nt);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.NotEnoughJunk;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;type_seen) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.InvalidTypeSpecifier;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; sc;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then use this new function in both &lt;code&gt;parse_func_decl&lt;&#x2F;code&gt; and &lt;code&gt;parse_variable_decl&lt;&#x2F;code&gt;. In fact, it is probably easier right now to just simply unify the two into a horrendous giant amalgamation.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_decl(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    arena: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ty:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) { @&amp;quot;var&amp;quot;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt;ast.StorageClass, either },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ast.Decl {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (ty&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .@&amp;quot;var&amp;quot;) ty.@&amp;quot;var&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else try&lt;&#x2F;span&gt;&lt;span&gt; parse_storage_class(tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expect(.identifier, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; new_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; tokens.next_force();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (new_token.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .semicolon&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; .{ .V&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; name },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        } },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .equals&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(arena, expr);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; expect(.semicolon, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; .{ .V&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; name },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; expr_ptr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            } };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .l_paren&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (ty&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .@&amp;quot;var&amp;quot;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            var&lt;&#x2F;span&gt;&lt;span&gt; params: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SegmentedList&lt;&#x2F;span&gt;&lt;span&gt;(ast.Identifier,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .{};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; param_peek&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; tokens.next_force();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            params:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (param_peek.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .keyword_void&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expect(.r_paren, tokens),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .type_int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;                    const&lt;&#x2F;span&gt;&lt;span&gt; ident&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expect(.identifier, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    try&lt;&#x2F;span&gt;&lt;span&gt; params.append(arena, .{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; ident });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;                    const&lt;&#x2F;span&gt;&lt;span&gt; inner_param_peek&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; tokens.next_force();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    switch&lt;&#x2F;span&gt;&lt;span&gt; (inner_param_peek.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        .comma&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                            try&lt;&#x2F;span&gt;&lt;span&gt; expect(.type_int, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                            continue&lt;&#x2F;span&gt;&lt;span&gt; :params .type_int;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        .r_paren&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; continue&lt;&#x2F;span&gt;&lt;span&gt; :params .invalid,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; block_peek&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; tokens.next_force();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; block: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                switch&lt;&#x2F;span&gt;&lt;span&gt; (block_peek.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    .semicolon&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; break&lt;&#x2F;span&gt;&lt;span&gt; :block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    .l_brace&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        tokens.put_back(block_peek);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                        break&lt;&#x2F;span&gt;&lt;span&gt; :block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_block(arena, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; .{ .F&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; name,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .params&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; params,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; block,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            } };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;ty&lt;&#x2F;code&gt; parameter is because there is one place in the AST that &lt;em&gt;requires&lt;&#x2F;em&gt; a variable declaration specifically, which is the initial part of a &lt;code&gt;for&lt;&#x2F;code&gt; loop. (It is not &lt;code&gt;comptime&lt;&#x2F;code&gt; because I use to sneak in an already parsed &lt;code&gt;sc&lt;&#x2F;code&gt; value, as you will see.) Everywhere else can really take either declaration type.&lt;&#x2F;p&gt;
&lt;p&gt;This is the part in &lt;code&gt;for&lt;&#x2F;code&gt; loop parsing that deals with the new parsing functions.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; init: ast.Stmt.For.Init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; init: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; peeked&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; tokens.next_force();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (peeked.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .semicolon) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt; :init .none&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tokens.put_back(peeked);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (parse_storage_class(tokens)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; decl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_decl(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                arena,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                tokens,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .@&amp;quot;var&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sc },&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- snuck in&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; decl_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(arena, decl.V);&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- unwrapped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            break&lt;&#x2F;span&gt;&lt;span&gt; :init .{ .decl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; decl_ptr };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt;_&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; &amp;lt;-- parse_sc already puts back any other token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(arena, expr);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; expect(.semicolon, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            break&lt;&#x2F;span&gt;&lt;span&gt; :init .{ .expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; expr_ptr };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Running the eye test I quickly ran into a bug. *Sigh.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;debugging-the-parser&quot;&gt;Debugging the Parser&lt;&#x2F;h2&gt;
&lt;p&gt;It failed on the first test, so obviously this is a bug in the general algorithm. With all the new changes all at once it is ahrder to pinpoint which one it is. I did not make a separate commit for every refactor, I am afraid. This is the C file it failed on (after removing comments).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; putchar (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; ch);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; print_letters(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;    static&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 65&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    putchar(i);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;        static&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 97&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        putchar(i);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    putchar(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span&gt;; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        print_letters();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Adding debugging printers to &lt;code&gt;next()&lt;&#x2F;code&gt; and &lt;code&gt;put_back()&lt;&#x2F;code&gt;, as done previously, will let me see where it failed in the file. I could also print the failed token&#x27;s span, but that would require better architecture and more dedication. I get this stream of consciusness back. I added comments to each line, manually, to be honest, to track which function does which.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   type_int 0-3		# parse_prgm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;REWIND type_int 0-3		# parse_prgm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   type_int 0-3		# parse_decl -&amp;gt;  parse_storage_class&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   identifier 4-11		# parse_storage_class&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;REWIND identifier 4-11		# parse_storage_class&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   identifier 4-11		# parse_decl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   l_paren 12-13		# parse_decl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   type_int 13-16		# parse_decl # params&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   identifier 17-19		# parse_decl # params&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   r_paren 19-20		# parse_decl # params&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   semicolon 20-21		# parse_decl # block&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   type_int 22-25		# parse_prgm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;REWIND type_int 22-25		# parse_prgm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   type_int 22-25		# parse_decl -&amp;gt;  parse_storage_class&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   identifier 26-39		# parse_storage_class&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;REWIND identifier 26-39		# parse_storage_class&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   identifier 26-39		# parse_decl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   l_paren 39-40		# parse_decl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   keyword_void 40-44	# parse_decl # params&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   r_paren 44-45		# parse_decl # params&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   l_brace 46-47		# parse_decl # block&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;REWIND l_brace 46-47		# parse_decl # block&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   l_brace 46-47		# parse_block&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   keyword_static 52-58	# parse_block&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;REWIND keyword_static 52-58	# parse_block&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   keyword_static 52-58	# parse_block_item&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;REWIND keyword_static 52-58	# parse_block_item&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   keyword_static 52-58	# .. oh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;REWIND keyword_static 52-58&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NEXT   keyword_static 52-58&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;error: SyntaxError&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Oh yeah here it is. I forgot to update it and &lt;code&gt;parse_block_item&lt;&#x2F;code&gt; still checks for whether something is a declaration or a statement using the &lt;code&gt;int&lt;&#x2F;code&gt; keyword. I could use a similar trick to what I did for the &lt;code&gt;for&lt;&#x2F;code&gt; loop where I can pass the parsed value in instead of peeking and parsing it again. This would require changes to &lt;code&gt;parse_decl&lt;&#x2F;code&gt;s signature, so I will start with that. This is the current signature.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_decl(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    arena: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ty:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) { @&amp;quot;var&amp;quot;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt;ast.StorageClass, either },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ast.Decl {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (ty&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .@&amp;quot;var&amp;quot;) ty.@&amp;quot;var&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else try&lt;&#x2F;span&gt;&lt;span&gt; parse_storage_class(tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; etc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Instead of smuggling the parsed value through &lt;code&gt;ty&lt;&#x2F;code&gt;, I could change &lt;code&gt;ty&lt;&#x2F;code&gt; to my earlier iteration of an &lt;code&gt;enum&lt;&#x2F;code&gt;, and pass whether it is parsed or not in another variable, like so.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_decl(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;    comptime&lt;&#x2F;span&gt;&lt;span&gt; ty:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; { @&amp;quot;var&amp;quot;, either },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    arena: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    parsed:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) { yes:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;ast.StorageClass, no },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ast.Decl {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (parsed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .yes) parsed.yes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else try&lt;&#x2F;span&gt;&lt;span&gt; parse_storage_class(tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; etc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And changing the call sites, again, but no matter. Here is the new and improved &lt;code&gt;parse_block_item&lt;&#x2F;code&gt;, relying on &lt;code&gt;parse_storage_class&lt;&#x2F;code&gt; putting back any unrecognized tokens.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_block_item(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    arena: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ast.BlockItem {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (parse_storage_class(tokens)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; .decl(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt; parse_decl(.either, arena, tokens, .{ .yes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sc }))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt;_&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; .stmt(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt; parse_stmt(arena, tokens));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And voila! Running the parser on the same C file above renders the following AST (with some updated printing for variable declarations).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION putchar ch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION print_letters&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		static VARIABLE i &amp;lt;- 65&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		(putchar i);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		DO&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			(i &amp;lt;- (+ i 1));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			static VARIABLE i &amp;lt;- 97&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			(putchar i);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			(i &amp;lt;- (+ i 1));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		(putchar 10);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		RETURN 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		FOR VARIABLE i &amp;lt;- 0; (&amp;lt; i 26); (i &amp;lt;- (+ i 1))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			(print_letters);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The eye test passes. The actual test suite passes. All is done and all is happy with the tiny world of this project.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;semantic-analysis&quot;&gt;Semantic Analysis&lt;&#x2F;h2&gt;
&lt;p&gt;The main difference in here from the previous chapters is that the symbol table needs to survive beyond this phase, as it is used in assembly. So far, in my compiler, the info is not kept in &lt;code&gt;ir_gen&lt;&#x2F;code&gt;. This would probably have to change. Here my idea of doing type checking in the same pass as identifier resolution is put to the test for the first, and probably last, time.&lt;&#x2F;p&gt;
&lt;p&gt;One thing to note, is that variables that do have linkage (whether internal or external) do not get their name mangled, because their name is how the linker tracks them.&lt;&#x2F;p&gt;
&lt;p&gt;The first thing I will do is resolving file scope variables. Instead of mucking around in &lt;code&gt;resolve_var_decl&lt;&#x2F;code&gt;, it is much smaller code that I will inline in &lt;code&gt;resolve_prgm&lt;&#x2F;code&gt; immediately.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; resolve_prgm(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    gpa: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    strings:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;utils.StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    prgm:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Prgm,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; variable_map: VariableMap&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .empty;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; variable_map.deinit(gpa);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; type_map: TypeMap&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .empty;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; type_map.deinit(gpa);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; bp: Boilerplate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .gpa&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; gpa,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .strings&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; strings,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .variable_map&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;variable_map,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .type_map&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;type_map,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; prgm.decls.iterator(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (item.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .F&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_func_decl(bp, f),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; right here, never mind the `.name.name`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; no type checking yet&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .V&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; variable_map.put(gpa, v.name.name, .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; strings.get_or_put(gpa, v.name.name),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .linkage&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .has_linkage,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Much of the complexity here is deferred in the Book to the type checking stage, so I presume I am heavily editing this part before the section is over. NExt comes &lt;code&gt;resolve_var_decl&lt;&#x2F;code&gt;. Unfortunately, some of the clever shenaningans I did to unify resolution for paramaters and variables are making this a bit more complex, but I persevere.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; resolve_local_var_decl(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;    comptime&lt;&#x2F;span&gt;&lt;span&gt; T:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; { param, @&amp;quot;var&amp;quot; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bp: Boilerplate,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    item:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (T) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .@&amp;quot;var&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.VarDecl,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .param&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Identifier,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; identifier,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; const&lt;&#x2F;span&gt;&lt;span&gt; sc:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt;ast.StorageClass&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (T) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .@&amp;quot;var&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;item.name, item.sc },&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- getting sc here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .param&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ item,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (bp.variable_map.get(identifier.name)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;prev&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (prev.scope&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .local)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;(prev.linkage&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .has_linkage&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .@&amp;quot;extern&amp;quot;)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; &amp;lt;--&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.DuplicateDecl;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .@&amp;quot;extern&amp;quot;) { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; &amp;lt;--&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; bp.variable_map.put(bp.gpa, identifier.name, .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.strings.get_or_put(bp.gpa, identifier.name),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .linkage&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .has_linkage,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; no type checking yet&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; snip --&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Regarding function declarations, the compiler should throw an error if a local function declaration is &lt;code&gt;static&lt;&#x2F;code&gt;. I am unsure where to put this check. I currently check if a block scope function declaration has a body (which it should not) in &lt;code&gt;resolve_block&lt;&#x2F;code&gt;, so maybe that is where I will stuff that check.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; resolve_block(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bp: Boilerplate,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    current_label:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt;utils.StringInterner.Idx,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    block:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Block,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; block.body.iterator(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (item.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .S&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_stmt(bp, current_label, s),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .D&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (d.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .F&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (f.block) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;_&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.IllegalFuncDefinition&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else if&lt;&#x2F;span&gt;&lt;span&gt; (f.sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .static) &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; &amp;lt;-- here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.TypeError&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                try&lt;&#x2F;span&gt;&lt;span&gt; resolve_func_decl(bp, f),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .V&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_local_var_decl(.@&amp;quot;var&amp;quot;, bp, v),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Next up is type checking. Instead of tracking each identifier&#x27;s type in a &lt;code&gt;type_map&lt;&#x2F;code&gt;, the compiler would track the attributes.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-attr-1&quot;&gt;&lt;a href=&quot;#fn-attr&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; So this the previous entry in &lt;code&gt;TypeMap&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    int,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    func:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        arity:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        defined:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This becomes the folloiwng. This is not identical to the Book&#x27;s design as it has its entry as a tuple of type and attributes. I will cross that bridge if I come to it.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Arrtibutes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    func:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        arity:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        defined:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        global:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    static:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ubut: Init,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        global:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    local,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; Init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tentative,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        initial:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        none,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Simply updating the existing &lt;code&gt;TypeMap&lt;&#x2F;code&gt; to have the new type as its value is enough for now. Now, back to writing code. Function declarations need to make some checks about their globality: whether they are &lt;code&gt;static&lt;&#x2F;code&gt; or not. Tracking defined functions is improved from last run as well.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; func_decl type checking&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; gop&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.type_map.getOrPut(bp.gpa, nname.real_idx);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (gop.found_existing) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (gop.value_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator&quot;&gt;* !=&lt;&#x2F;span&gt;&lt;span&gt; .func&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; or&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            gop.value_ptr.func.arity&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span&gt; func_decl.params.count())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.TypeError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else if&lt;&#x2F;span&gt;&lt;span&gt; (gop.value_ptr.func.defined&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            func_decl.block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.DuplicateFunctionDef;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else if&lt;&#x2F;span&gt;&lt;span&gt; (gop.value_ptr.func.global&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; and&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- new check&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            func_decl.sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .static)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.ConflictingFuncDecls;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        gop.value_ptr.func.defined&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; func_decl.block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- update&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt; gop.value_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .{ .func&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .arity&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; func_decl.params.count(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .defined&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; func_decl.block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .global&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; func_decl.sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span&gt; .static,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- new field&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;File scope variable declarations, which I have stubbed in &lt;code&gt;resolve_prgm&lt;&#x2F;code&gt; above, also need to by type checked. This is significantly longer, and is a bit more complex than I can process at the moment of writing so I copied it from the book without trying to refactor. I am sure I made a mistake anyway.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.V&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; file scope variables&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; nname&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; strings.get_or_put(gpa, v.name.name);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; variable_map.put(gpa, v.name.name, .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nname,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .linkage&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .has_linkage,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; TYPE CHECKING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; init_value: Arrtibutes.Init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (v.init) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (e.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; .{ .initial&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; i },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.NonConstantInit,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else if&lt;&#x2F;span&gt;&lt;span&gt; (v.sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .@&amp;quot;extern&amp;quot;) .none&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; .tentative;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; global&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; v.sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span&gt; .static;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; gop&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; type_map.getOrPut(gpa, nname.real_idx);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (gop.found_existing) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (gop.value_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator&quot;&gt;* !=&lt;&#x2F;span&gt;&lt;span&gt; .static)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.TypeError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (v.sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .@&amp;quot;extern&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            global&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; gop.value_ptr.static.global&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else if&lt;&#x2F;span&gt;&lt;span&gt; (gop.value_ptr.static.global&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span&gt; global)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.ConflictingLinkage;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (gop.value_ptr.static.init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .initial) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (init_value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .initial)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.ConflictingDefinitions;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            init_value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; gop.value_ptr.static.init;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else if&lt;&#x2F;span&gt;&lt;span&gt; (init_value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span&gt; .initial&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            gop.value_ptr.static.init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .tentative)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            init_value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .tentative;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    gop.value_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .{ .static&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; init_value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .global&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; global,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There is a strong argument to be made that this should live in its own function. Resolving local scope variables is equally annoying. You can probably tell I am bored with this already.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; resolve_local_var_decl(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;    comptime&lt;&#x2F;span&gt;&lt;span&gt; T:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; { param, @&amp;quot;var&amp;quot; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bp: Boilerplate,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    item:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (T) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .@&amp;quot;var&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.VarDecl,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .param&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Identifier,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; identifier,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; const&lt;&#x2F;span&gt;&lt;span&gt; sc:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt;ast.StorageClass&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (T) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .@&amp;quot;var&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;item.name, item.sc },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .param&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ item,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (bp.variable_map.get(identifier.name)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;prev&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (prev.scope&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .local)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;(prev.linkage&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span&gt; .none&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .@&amp;quot;extern&amp;quot;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.DuplicateDecl;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .@&amp;quot;extern&amp;quot;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; nname&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.strings.get_or_put(bp.gpa, identifier.name);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; bp.variable_map.put(bp.gpa, identifier.name, .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nname,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .linkage&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .has_linkage,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; TYPE CHECKING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (item.init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.TypeError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; gop&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.type_map.getOrPut(bp.gpa, nname.real_idx);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (gop.found_existing) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span&gt; (gop.value_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator&quot;&gt;* ==&lt;&#x2F;span&gt;&lt;span&gt; .func)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.TypeError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt; gop.value_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .{ .static&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .none,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .global&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-bool z-zig&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            } };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; unique_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.make_temporary(identifier.name);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.variable_map.put(bp.gpa, identifier.name, .{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; unique_name });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; TYPE CHECKING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; attr: Arrtibutes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .static) ret: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; init_value: Arrtibutes.Init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (item.init) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (e.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; .{ .initial&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; i },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.TypeError,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt; .{ .initial&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            break&lt;&#x2F;span&gt;&lt;span&gt; :ret .{ .static&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; init_value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .global&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-bool z-zig&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            } };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt; .local;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; gop&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.type_map.getOrPut(bp.gpa, unique_name.real_idx);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (gop.found_existing) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (gop.value_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator&quot;&gt;* ==&lt;&#x2F;span&gt;&lt;span&gt; .func)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.TypeError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        gop.value_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; attr;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    identifier.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .{ .idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; unique_name };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (T&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .@&amp;quot;var&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (item.init) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(bp, expr);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I do not like how this chapters is all these weird intermingling &lt;code&gt;if&lt;&#x2F;code&gt;s. It is very confusing logic and horrible to debug. Running the test suite, I got one failure, which is not catching the error in this C code.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;* a variable declared in a for loop header cannot have a storage class. *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;static&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; x;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Well, then. I do not think I will add another &lt;code&gt;if&lt;&#x2F;code&gt; statement in that monster function just for &lt;code&gt;for&lt;&#x2F;code&gt; loops. I will go back and reject that at the parsing stage instead. Boom: tests pass.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;internal-representation&quot;&gt;Internal Representation&lt;&#x2F;h2&gt;
&lt;p&gt;It makes sense in a weird twisted manner to have the String Interner itself hold the type info that the semantic analsys phase has been collecting. It makes perfect sense if you ask me, and it keeps me from carrying yet another type around. Changing the value of the internal map to &lt;code&gt;?sema.Attributes&lt;&#x2F;code&gt;, where the strings that do not have related values would simple be null. This, however, requires more work than I am currently willing ti put in, so I will have the semantic analysis function just return the collected type map.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; resolve_prgm(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    gpa: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    strings:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;utils.StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    prgm:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Prgm,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;TypeMap {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; yada yada&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; type_map;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The IR syntax tree changes in a similar fashion too. Programs are now a list of &lt;code&gt;TopLevel&lt;&#x2F;code&gt;s, which are either a function or a &lt;code&gt;StaticVar&lt;&#x2F;code&gt;. Functions also track whether they are &lt;code&gt;global&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Prgm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    items: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(TopLevel),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; TopLevel&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    F: FuncDef,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    V: StaticVar,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; FuncDef&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name: Identifier,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    global:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    params: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(Identifier),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    instrs: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(Instr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; StaticVar&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name: Identifier,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    global:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    init:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, to generate these new items, the &lt;code&gt;type_map&lt;&#x2F;code&gt; returned from semantic analysis is now an input parameter. This is used to determine which function declarations are global. This is the new &lt;code&gt;prgm_emit_ir&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; prgm_emit_ir(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    strings:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;utils.StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    type_map:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;sema.TypeMap,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; might make sense to move this to `utils`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    prgm:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; ast.Prgm,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ir.Prgm {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; top_level: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(ir.TopLevel) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; .initCapacity(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        prgm.decls.len,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; prgm.decls.constIterator(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (d.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator&quot;&gt;* ==&lt;&#x2F;span&gt;&lt;span&gt; .F) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (d.F.block) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;_&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        var&lt;&#x2F;span&gt;&lt;span&gt; f_ir&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; func_def_emit_ir(alloc, strings,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;d.F);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; assertions galore. so much hidden control flow&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        f_ir.global&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; type_map.get(f_ir.name.real_idx).&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;.func.global;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; top_level.append(alloc, .{ .F&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; f_ir });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .items&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; top_level };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Secondly, all variable declarations with &lt;code&gt;static&lt;&#x2F;code&gt; or &lt;code&gt;extern&lt;&#x2F;code&gt; specifiers should not be generated. Because they have linkage and therefore belong to the &lt;code&gt;Prgm&lt;&#x2F;code&gt; scope.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; var_decl_emit_ir(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bp: Boilerplate,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    decl:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; ast.VarDecl,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (decl.sc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (decl.init) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(bp, e);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .copy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(src, .{ .variable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; decl.name.idx }) });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, back in &lt;code&gt;prgm_emit_ir&lt;&#x2F;code&gt;, the &lt;code&gt;type_map&lt;&#x2F;code&gt; is traversed for every static variable. Here is hoping the semantic analysis phase tracked these correctly.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; STATIC VARS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; type_map.iterator();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;entry&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (entry.value_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator&quot;&gt;* ==&lt;&#x2F;span&gt;&lt;span&gt; .static) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; name: utils.StringInterner.Idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; hacks on hacks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .real_idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; entry.key_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .strings&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; strings,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; global&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; entry.value_ptr.static.global;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (entry.value_ptr.static.init) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .initial&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; i,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .tentative&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .none&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; continue&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; top_level.append(alloc, .{ .V&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; name,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .global&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; global,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; init,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        } });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And .. that&#x27;s fairly it. Doing the eye test on IR generation seems to work fine. Here is one sample. Running the test suite works fine as well.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;static&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; my_fun(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; call_static_my_fun(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; my_fun();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; call_static_my_fun_2(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; my_fun(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; my_fun();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;extern&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; my_fun(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;static&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; my_fun(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; my_fun(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;    static&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; i;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;	global FUNCTION call_static_my_fun&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;		fn.1 &amp;lt;- my_fun()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;		ret fn.1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;		ret 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;	global FUNCTION call_static_my_fun_2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;		fn.2 &amp;lt;- my_fun()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;		ret fn.2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;		ret 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;	FUNCTION my_fun&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;		add.3 &amp;lt;- i.0 + 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;		i.0 &amp;lt;- add.3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;		ret i.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;		ret 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;	VARIABLE i.0 = 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Onwards to codegen and exposing the actual bugs in previous stages.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;assembly-generation&quot;&gt;Assembly Generation&lt;&#x2F;h2&gt;
&lt;p&gt;Changes to the assembly syntax tree mirror those in the IR&#x27;s. Also, a new &lt;code&gt;Operand&lt;&#x2F;code&gt; type for &lt;code&gt;rodata&lt;&#x2F;code&gt;. The &lt;code&gt;Operand&lt;&#x2F;code&gt; change is tiny.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Operand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    imm:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    reg: Register,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pseudo: Identifier,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    stack: Offset,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    data: Identifier,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;--&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The changes to &lt;code&gt;Prgm&lt;&#x2F;code&gt; are similar enough to the changes in IR that repeating them here would be a chore. Changes to &lt;code&gt;asm_gen.zig&lt;&#x2F;code&gt; are equally straightforward, for the most part. The new &lt;code&gt;prgm_to_asm&lt;&#x2F;code&gt; almost contains all of it, with functions getting their &lt;code&gt;global&lt;&#x2F;code&gt; in their own function.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; prgm_to_asm(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    prgm: ir.Prgm,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;assembly.Prgm {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; items: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(assembly.TopLevel) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; .initCapacity(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        prgm.items.items.len,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; (prgm.items.items) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (item) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .F&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; items.append(alloc, .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .F&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; func_def_to_asm(alloc, f),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .V&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; items.append(alloc, .{ .V&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; assembly.StaticVar{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; v.name,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; v.init,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .global&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; v.global,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        } }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .items&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; items };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;replacing-pseudos&quot;&gt;Replacing Pseudos&lt;&#x2F;h3&gt;
&lt;p&gt;Previously, pseudoregisters were replaced by &lt;code&gt;stack&lt;&#x2F;code&gt; items. Now, the static ones, as indicated by the &lt;code&gt;type_map&lt;&#x2F;code&gt; (I am never getting rid of this am I), are going to be replaced by &lt;code&gt;data&lt;&#x2F;code&gt; operands. To facilitate this, I am just going to add a &lt;code&gt;type_map&lt;&#x2F;code&gt; field to &lt;code&gt;ir.Prgm&lt;&#x2F;code&gt; and &lt;code&gt;assembly.Prgm&lt;&#x2F;code&gt;. The map passes through all the way to &lt;code&gt;pseudo_to_stack&lt;&#x2F;code&gt; (which might warrant a change of name now), to end up with this. I also changed &lt;code&gt;PseudoMap&lt;&#x2F;code&gt;&#x27;s value type to &lt;code&gt;void&lt;&#x2F;code&gt; because I realized I am not using it.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-check-optional-1&quot;&gt;&lt;a href=&quot;#fn-check-optional&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; pseudo_to_stack(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    op: assembly.Operand,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    type_map:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; sema.TypeMap,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    map:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;PseudoMap,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;assembly.Operand {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (op) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .reg, .imm, .stack, .data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; op,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .pseudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; offset: assembly.Operand.Offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span&gt; (map.getIndex(name)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;                    &#x2F;&#x2F; already seen&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt;                    @intCast&lt;&#x2F;span&gt;&lt;span&gt;(idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else if&lt;&#x2F;span&gt;&lt;span&gt; (cond: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;                    const&lt;&#x2F;span&gt;&lt;span&gt; cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; type_map.get(name.real_idx);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    if&lt;&#x2F;span&gt;&lt;span&gt; (cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt; :cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-bool z-zig&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    break&lt;&#x2F;span&gt;&lt;span&gt; :cond cond.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;? ==&lt;&#x2F;span&gt;&lt;span&gt; .static;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                })&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; name }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;span&gt; ret: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    try&lt;&#x2F;span&gt;&lt;span&gt; map.put(name, {});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    break&lt;&#x2F;span&gt;&lt;span&gt; :ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @intCast&lt;&#x2F;span&gt;&lt;span&gt;(map.count());&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; index of last item + 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; .{ .stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; * -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt; };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;fixing-up-instructions&quot;&gt;Fixing Up Instructions&lt;&#x2F;h3&gt;
&lt;p&gt;A lot of the old, already implemented rules for moving between different stack positions already apply here for moving between different memory positions, whether they are &lt;code&gt;data&lt;&#x2F;code&gt; or &lt;code&gt;stack&lt;&#x2F;code&gt;. Otherwise, it is the same annoying state machine.&lt;&#x2F;p&gt;
&lt;p&gt;To help make things simpler, I created a helper function to tell me if an &lt;code&gt;Operand&lt;&#x2F;code&gt; is a memory location or not. This is the function defined under &lt;code&gt;Operand&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub inline fn&lt;&#x2F;span&gt;&lt;span&gt; is_mem(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @This&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return switch&lt;&#x2F;span&gt;&lt;span&gt; (self) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .stack, .data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-bool z-zig&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-bool z-zig&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And this is the new state machine in all its glory. the only changes is using &lt;code&gt;.is_mem()&lt;&#x2F;code&gt; and changing the states&#x27; names from &lt;code&gt;stack&lt;&#x2F;code&gt; to &lt;code&gt;mem&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; State&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    start,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mov_mem_mem,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cmp_mem_mem,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cmp_to_imm,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    add_mem_mem,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    sub_mem_mem,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mul_to_mem,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    idiv_const,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; (func_def.instrs.items) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;instr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    state:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (State.start) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .start&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (instr) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (m.src.is_mem() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;and&lt;&#x2F;span&gt;&lt;span&gt; m.dst.is_mem())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                continue&lt;&#x2F;span&gt;&lt;span&gt; :state .mov_mem_mem&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .cmp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (m.src.is_mem() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;and&lt;&#x2F;span&gt;&lt;span&gt; m.dst.is_mem())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                continue&lt;&#x2F;span&gt;&lt;span&gt; :state .cmp_mem_mem&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else if&lt;&#x2F;span&gt;&lt;span&gt; (m.dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .imm)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                continue&lt;&#x2F;span&gt;&lt;span&gt; :state .cmp_to_imm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .add&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (m.src.is_mem() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;and&lt;&#x2F;span&gt;&lt;span&gt; m.dst.is_mem())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                continue&lt;&#x2F;span&gt;&lt;span&gt; :state .add_mem_mem&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (m.src.is_mem() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;and&lt;&#x2F;span&gt;&lt;span&gt; m.dst.is_mem())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                continue&lt;&#x2F;span&gt;&lt;span&gt; :state .sub_mem_mem&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (m.dst.is_mem())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                continue&lt;&#x2F;span&gt;&lt;span&gt; :state .mul_to_mem&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .idiv&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (o&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .imm)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                continue&lt;&#x2F;span&gt;&lt;span&gt; :state .idiv_const&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .mov_mem_mem&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.mov.src, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }, instr.mov.dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .cmp_mem_mem&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.cmp.src, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .cmp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }, instr.cmp.dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .cmp_to_imm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.cmp.dst, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R11 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .cmp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.cmp.src, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R11 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .add_mem_mem&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.add.src, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .add&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }, instr.add.dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .sub_mem_mem&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.sub.src, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }, instr.sub.dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .mul_to_mem&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.mul.dst, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R11 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.mul.src, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R11 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R11 }, instr.mul.dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .idiv_const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.idiv, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R11 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .idiv&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R11 } },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .legal&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.append(alloc, instr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And here, I was done. The eye tests pass, with small hiccups regarding lifetimes and formatting. All is left now is the actual assembly generation. This is fairly mechanical, I think, despite hiding a nasty bug last chapter.&lt;&#x2F;p&gt;
&lt;p&gt;Thankfully, all tests pass. I am done with Part 1.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;next-thing-to-do&quot;&gt;Next Thing to Do&lt;&#x2F;h2&gt;
&lt;p&gt;I am undecided yet. Either go for Part 3, which is about optimizations, or do Part 1 again in another language, like Swift or .. I dunno .. TypeScript? Maybe I will start working on my own language, or working on a compiler for Hare. Or maybe just go find a job.&lt;&#x2F;p&gt;
&lt;p&gt;All in all, this was a fun process. I learned a lot about Zig and reinforced knowledge about writing a C compiler. I recommend buying &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;norasandler.com&#x2F;2022&#x2F;03&#x2F;29&#x2F;Write-a-C-Compiler-the-Book.html&quot;&gt;the Book&lt;&#x2F;a&gt;. It is great.&lt;&#x2F;p&gt;
&lt;p&gt;Until later.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-types&quot;&gt;
&lt;p&gt;The Book&#x27;s function is more complicated that is needed right now but is written this way to accomodate different types in Part 2. As I am not planning to implement Part 2 this run, there is need for the &lt;code&gt;parse_type&lt;&#x2F;code&gt; half. &lt;a href=&quot;#fr-types-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-attr&quot;&gt;
&lt;p&gt;This is actually part of the design of the Book&#x27;s compiler that gave me much grief in Part 2 during my Rust implementation. I do not quite exactly remember why, right now, but it felt very fiddly and prone to errors. &lt;a href=&quot;#fr-attr-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-check-optional&quot;&gt;
&lt;p&gt;&lt;code&gt;cond&lt;&#x2F;code&gt; is a block expression to make that compariosn. Because for a reason I do not understand &lt;code&gt;type_map.get(name.real_idx) == .static&lt;&#x2F;code&gt; does not work. &lt;a href=&quot;#fr-check-optional-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Chapter 9: Functions</title>
        <published>2025-06-01T00:00:00+00:00</published>
        <updated>2025-06-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/paella/c9/"/>
        <id>https://ar-ms.me/paella/c9/</id>
        
        <content type="html" xml:base="https://ar-ms.me/paella/c9/">&lt;p&gt;After &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;paella&#x2F;c8&#x2F;&quot;&gt;eight&lt;&#x2F;a&gt; grueling (not really) chapters of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;norasandler.com&#x2F;2022&#x2F;03&#x2F;29&#x2F;Write-a-C-Compiler-the-Book.html&quot;&gt;Writing a C Compiler&lt;&#x2F;a&gt;, time to implement more assembly instructions. Functions! Linkage! Commas!&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lexer-ast-and-parser&quot;&gt;Lexer, AST, and Parser&lt;&#x2F;h2&gt;
&lt;p&gt;Lexer just has a comma now. I thought about adding the comma operator but that didn&#x27;t seem worth the trouble.&lt;&#x2F;p&gt;
&lt;p&gt;The AST has two new additions. Function call expressions and function declarations (which are rebranded and improved function definitions)! Other changes include how the structures themselves are defined. A program is now a &lt;em&gt;list&lt;&#x2F;em&gt; of function declarations, instead of just one. How about that?&lt;&#x2F;p&gt;
&lt;p&gt;These are the new AST nodes. I am not sure these compile or not yet, which I will find out when I am done with the parser. The use of &lt;code&gt;SegmentedList&lt;&#x2F;code&gt; is discussed a couple of chapters ago as a more Arena-friendly collection type.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Prgm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    funcs: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SegmentedList&lt;&#x2F;span&gt;&lt;span&gt;(FuncDecl,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    body: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SegmentedList&lt;&#x2F;span&gt;&lt;span&gt;(BlockItem,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; BlockItem&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    D: Decl,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    S: Stmt,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Decl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    F: FuncDecl,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    V: VarDecl,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; FuncDecl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    params: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SegmentedList&lt;&#x2F;span&gt;&lt;span&gt;(Identifier,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    block:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt;Block,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; VarDecl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name: Identifier,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    init:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; ?*&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; snip --&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    func_call:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; { Identifier, std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SegmentedList&lt;&#x2F;span&gt;&lt;span&gt;(Expr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; This was implemented last chapter fixing the Segmentation Fault!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Identifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    idx: utils.StringInterner.Idx,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It is going to be annoying fixing all the type errors throughout. Nonetheless, the parsing grammar for these new node types are going to change significantly. Here is. This is the new, tentative, &lt;code&gt;parse_prgm&lt;&#x2F;code&gt;. I am not sure this is entirely correct yet.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; parse_prgm(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    arena: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ast.Prgm {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; funcs: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SegmentedList&lt;&#x2F;span&gt;&lt;span&gt;(ast.FuncDecl,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .{};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (tokens.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;next_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tokens.put_back(next_token);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; func_decl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_func_decl(arena, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; funcs.append(arena, func_decl);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .funcs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; funcs };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;parse_func_decl&lt;&#x2F;code&gt; is the same as the old &lt;code&gt;parse_func_def&lt;&#x2F;code&gt;, but with optional parameters and an optional body. Ok maybe not the same, it is a behemoth. And all this is going to get significantly more complex when adding different types than &lt;code&gt;int&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_func_decl(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    arena: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ast.FuncDecl {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; same old&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.type_int, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expect(.identifier, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; new stuff !!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; params: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SegmentedList&lt;&#x2F;span&gt;&lt;span&gt;(ast.Identifier,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .{};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; params&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; expect(.l_paren, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; next_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; labelled switch to loop over mutliple parameters.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        params:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (next_token.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F; old bahaviour is this:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .keyword_void&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expect(.r_paren, tokens),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F; new optional parameters&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .type_int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;                const&lt;&#x2F;span&gt;&lt;span&gt; ident&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expect(.identifier, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                try&lt;&#x2F;span&gt;&lt;span&gt; params.append(arena, .{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; ident });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;                const&lt;&#x2F;span&gt;&lt;span&gt; next_next&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;                &#x2F;&#x2F; loops back here. this would be sginifcantly more annoying&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;                &#x2F;&#x2F; to write without labeled switch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                switch&lt;&#x2F;span&gt;&lt;span&gt; (next_next.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    .comma&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                        try&lt;&#x2F;span&gt;&lt;span&gt; expect(.type_int, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                        continue&lt;&#x2F;span&gt;&lt;span&gt; :params .type_int;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    .r_paren&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;                    &#x2F;&#x2F; could just retunr here but where is the fun then?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; continue&lt;&#x2F;span&gt;&lt;span&gt; :params .invalid,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; block: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; peeked&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        switch&lt;&#x2F;span&gt;&lt;span&gt; (peeked.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .semicolon&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; break&lt;&#x2F;span&gt;&lt;span&gt; :block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .l_brace&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                tokens.put_back(peeked);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                break&lt;&#x2F;span&gt;&lt;span&gt; :block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_block(arena, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; name, .params&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; params, .block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; block };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There is one big item left, which is &lt;code&gt;BlockItem&lt;&#x2F;code&gt;, which can be a function declaration as well as a variable declaration, and it is not possible to know which is which from the token &lt;code&gt;type_int&lt;&#x2F;code&gt; as done before.&lt;&#x2F;p&gt;
&lt;p&gt;The most straightforward way to implement it in the current code base is as follows: look for an &lt;code&gt;type_int&lt;&#x2F;code&gt; token, verify there is an identifier token afterwards, &lt;em&gt;without&lt;&#x2F;em&gt; recording it, then see what the third token is. If it is a &lt;code&gt;semicolon&lt;&#x2F;code&gt; or an &lt;code&gt;equals&lt;&#x2F;code&gt;, it is a variable; if it is a parenthesis, it is a function; otherwise it is illegal. Then the parser is rewinded to the &lt;code&gt;int&lt;&#x2F;code&gt; and the correct function is called. In later chapters, with global variables, it will be apparent that the only place which only accepts one type of declarations is the &lt;code&gt;for&lt;&#x2F;code&gt; loop statement, but I will cross that bridge when I get to it.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_decl(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    arena: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ast.Decl {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; int_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.NotEnoughJunk;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (int_token.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span&gt; .type_int) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expect(.identifier, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; new_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.NotEnoughJunk;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens.put_back(int_token);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (new_token.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .semicolon, .equals&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; .{ .V&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_var_decl(arena, tokens) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .l_paren&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; .{ .F&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_func_decl(arena, tokens) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Parsing function calls is a new challenge. Previously, any identifier is immediately assumed to be a variable. But now, if the identifier is followed by parenthesis, it could be a function call with an arbitrary number of parameters. The new &lt;code&gt;identifier&lt;&#x2F;code&gt; case exhibits a serious case of rightward drift.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.identifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; next_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.NotEnoughJunk;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.buffer[current.loc.start..current.loc.end];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (next_token.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .l_paren&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; .{ .func_call&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; name },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; parse_args(arena, tokens),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        } },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tokens.put_back(next_token);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; .{ .@&amp;quot;var&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; name } };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; elsewhere:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_args(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    arena: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SegmentedList&lt;&#x2F;span&gt;&lt;span&gt;(ast.Expr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; assumes l_paren already consumed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; ret: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SegmentedList&lt;&#x2F;span&gt;&lt;span&gt;(ast.Expr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .{};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; current&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.NotEnoughJunk;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    args:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (current.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .r_paren&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; ret,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .comma&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; ret.append(arena, expr);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; n_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.NotEnoughJunk;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            continue&lt;&#x2F;span&gt;&lt;span&gt; :args n_token.tag;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; only actually relevant for the first argument.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tokens.put_back(current);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            continue&lt;&#x2F;span&gt;&lt;span&gt; :args .comma;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;semantic-analysis&quot;&gt;Semantic Analysis&lt;&#x2F;h2&gt;
&lt;p&gt;This is a bit more involved than usual this chapter. In addition to variable resolution, the compiler needs to do type checking! Do all declarations of functions (which &lt;em&gt;can&lt;&#x2F;em&gt; repeat), have the same number of parameters?&lt;&#x2F;p&gt;
&lt;p&gt;Starting with the easier stuff, the identifier resolution pass should handle the new function syntax. Start with function calls. Here is the added part in &lt;code&gt;resolve_expr&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.func_call&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (bp.variable_map.get(f.@&amp;quot;0&amp;quot;.name)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;entry&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        f.@&amp;quot;0&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; entry.name };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; f.@&amp;quot;1&amp;quot;.iterator(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(bp, item);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.Undeclaredfunction;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Resolving function declarations had me move the creation of the main variable map back into &lt;code&gt;resolve_prgm&lt;&#x2F;code&gt; instead, and create a new inner map for every function. Also, I need to update the &lt;code&gt;Entry&lt;&#x2F;code&gt; type of the variable map. This is the new &lt;code&gt;Entry&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Entry&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name: utils.StringInterner.Idx,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    scope:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; { local, parent } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .local,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    linkage:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; { none, external } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .none,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- new&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then this is &lt;code&gt;resolve_func_decl&lt;&#x2F;code&gt;, and the inner parameters resolution, which is really just a cheap copy of &lt;code&gt;resolve_var_decl&lt;&#x2F;code&gt; itself rebranded &lt;code&gt;resolve_decl&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; resolve_func_decl(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bp: Boilerplate,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    func_decl:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.FuncDecl,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (bp.variable_map.get(func_decl.name)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;prev&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (prev.scope&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .local&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; prev.linkage&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span&gt; .external)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.DuplicateFunctionDecl;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.variable_map.put(bp.gpa, func_decl.name, .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.strings.get_or_put(bp.gpa, func_decl.name),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .scope&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .local,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .linkage&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .external,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; variable_map&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.variable_map.clone(bp.gpa);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; variable_map.deinit(bp.gpa);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; variable_map.valueIterator();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        value.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value.name,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .scope&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .parent,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .linkage&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value.linkage,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; inner_bp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bp.into_ineer(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;variable_map);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; func_decl.params.iterator(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;param&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; a cheap imitation of `resolve_var_decl`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; should pribably be in its own function.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (inner_bp.variable_map.get(param.name)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;entry&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (entry.scope&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .local)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.DuplicateVariableDecl;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; unique_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; inner_bp.make_temporary(param.name);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; inner_bp.variable_map.put(inner_bp.gpa, param.name, .{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; unique_name });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        param.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .{ .idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; unique_name };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (func_decl.block) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt;|*&lt;&#x2F;span&gt;&lt;span&gt;block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; resolve_block(inner_bp,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;, block);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;One more thing, there is need to check that block level function declarations have no body. I am going to do that in &lt;code&gt;resolve_block&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; resolve_block(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bp: Boilerplate,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    current_label:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt;utils.StringInterner.Idx,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    block:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Block,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; block.body.iterator(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (item.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .S&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_stmt(bp, current_label, s),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .D&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (d.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .F&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (f.block) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;_&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.IllegalFuncDefinition&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                try&lt;&#x2F;span&gt;&lt;span&gt; resolve_func_decl(bp, f),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .V&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_var_decl(bp, v),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Before delving into type checking, the book suggests to run the test suite, but expect a number of failures. Thankfully, I can check the individual folders separately using the eye test, without running the test suite in the official manner, I can tell that the compiler is passing all the right files it should at this stage, even the ones in &lt;code&gt;invalid_types&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;type-checking&quot;&gt;Type checking&lt;&#x2F;h2&gt;
&lt;p&gt;The Book has the type checking done in its own pass. At first, I tried just stuffing the type checking logic right into the same identifier resolution pass. But the actual problem was that I needed a separate data structure anyway, since function declarations have to match even when they are in different scopes. So I am still doing it in the same run, but with a separate data structure.&lt;&#x2F;p&gt;
&lt;p&gt;The type checking consists mostly of the following: not using the same identifier for both &lt;code&gt;int&lt;&#x2F;code&gt;s and functions, making sure functions always have the same number of parameters in all declarations, and make sure a function is not defined (with a body) twice.&lt;&#x2F;p&gt;
&lt;p&gt;A new data structure would be needed to stuff this info, global throughout the whole file.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-linker-1&quot;&gt;&lt;a href=&quot;#fn-linker&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; A hashmap taking the unique identifiers as keys and their types as values. The type is either an integer or a function with defined arity (number of parameters). I also need to track whether a function has been defined or not.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; TypeMap&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;AutoHashMapUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;    u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Type,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    int,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    func:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        arity:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        defined:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then adding a pointer to it to &lt;code&gt;Boilerplate&lt;&#x2F;code&gt;, and adjusting &lt;code&gt;resolve_prgm&lt;&#x2F;code&gt; as follows.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; resolve_prgm(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    gpa: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    strings:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;utils.StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    prgm:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Prgm,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; variable_map: VariableMap&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .empty;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; variable_map.deinit(gpa);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; type_map: TypeMap&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .empty;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; type_map.deinit(gpa);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; bp: Boilerplate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .gpa&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; gpa,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .strings&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; strings,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .variable_map&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;variable_map,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .type_map&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;type_map,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; prgm.funcs.iterator(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; resolve_func_decl(bp, item);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;What follows next is lots of annoying boilerplate. I must make sure every time I add something to a &lt;code&gt;variable_map&lt;&#x2F;code&gt;, I am adding its new name (if any) to &lt;code&gt;type_map&lt;&#x2F;code&gt;. Hairier than usual logic, but should try to straighten it out before stuffing it in a &lt;code&gt;Boilerplate&lt;&#x2F;code&gt; method.&lt;&#x2F;p&gt;
&lt;p&gt;For example, in &lt;code&gt;resolve_finc_decl&lt;&#x2F;code&gt;, adding a name to &lt;code&gt;variable_map&lt;&#x2F;code&gt; and &lt;code&gt;type_map&lt;&#x2F;code&gt; is done as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; nname&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.strings.get_or_put(bp.gpa, func_decl.name);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.variable_map.put(bp.gpa, func_decl.name, .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nname,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .scope&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .local,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .linkage&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .external,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; gop&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.type_map.getOrPut(bp.gpa, nname.real_idx);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (gop.found_existing) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (gop.value_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator&quot;&gt;* !=&lt;&#x2F;span&gt;&lt;span&gt; .func&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; or&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            gop.value_ptr.func.arity&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span&gt; func_decl.params.count())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.TypeError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else if&lt;&#x2F;span&gt;&lt;span&gt; (gop.value_ptr.func.defined&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            func_decl.block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.DuplicateFunctionDef;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt; gop.value_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .{ .func&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .arity&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; func_decl.params.count(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .defined&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; func_decl.block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A similar thing to do in &lt;code&gt;resolve_var_decl&lt;&#x2F;code&gt;, and inside the small tidbit in &lt;code&gt;resolve_func_decl&lt;&#x2F;code&gt; that reeolves parameters. This is how it looks like.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; gop&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.type_map.getOrPut(bp.gpa, unique_name.real_idx);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (gop.found_existing) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (gop.value_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator&quot;&gt;* !=&lt;&#x2F;span&gt;&lt;span&gt; .int) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.TypeError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt; gop.value_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .int;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There does not seem enough shared logic right now to try and DRY these. Maybe later. What is left is checking these things in function calls and variable declarations. They are both very funny looking.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.@&amp;quot;var&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (bp.variable_map.get(name.name)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;un&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (bp.type_map.get(un.name.real_idx).&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;? ==&lt;&#x2F;span&gt;&lt;span&gt; .int) &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; unwrap optional&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            expr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .{ .@&amp;quot;var&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; un.name } }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.TypeError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.UndeclaredVariable;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.func_call&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (bp.variable_map.get(f.@&amp;quot;0&amp;quot;.name)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;entry&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bp.type_map.get(entry.name.real_idx).&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .func&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            t.func.arity&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; f.@&amp;quot;1&amp;quot;.count())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            f.@&amp;quot;0&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; entry.name };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; f.@&amp;quot;1&amp;quot;.iterator(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(bp, item);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.TypeError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.UndeclaredFunction;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I &lt;em&gt;think&lt;&#x2F;em&gt; this should be it. I checked for functions being defined twice&#x2F; I checked that functions should be functions and types should be types. I checked all functions with the same name should have the same arity. &lt;code&gt;zig build&lt;&#x2F;code&gt; returns no errors. What is left?&lt;&#x2F;p&gt;
&lt;p&gt;The proof of the pudding is in the test suite. Time to run the test suite. (which now applies &lt;code&gt;--latest-only&lt;&#x2F;code&gt; by default as not to take &lt;em&gt;too&lt;&#x2F;em&gt; long.)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; paella ❱ zig build submit&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -- --chapter 9 --stage&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; validate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;----------------------------------------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ran&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; tests in 157.089s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OK&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Phew&lt;&#x2F;em&gt;. Mind you this does not mean the logic is correct. It just means it is failing the ones it should fail and passing the ones it should pass. The full test suite passes as well, which is cool.&lt;&#x2F;p&gt;
&lt;p&gt;I took the time to refactor out the common logic between function parameters and variable declarations. Zig&#x27;s &lt;code&gt;comptime&lt;&#x2F;code&gt; allows some tricks that Rust would torture me for,&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-const-1&quot;&gt;&lt;a href=&quot;#fn-const&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; forcing me to use a trait or some weird amalgamation of const generics. It turned out most of the logic is for identifiers, except for initializers in variable declarations. The new function follows.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; resolve_var_decl(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;    comptime&lt;&#x2F;span&gt;&lt;span&gt; T:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; { param, @&amp;quot;var&amp;quot; },&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; anoynmous types yay&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bp: Boilerplate,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    item:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (T) { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; can simply be `if` but this is more readable i think&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .@&amp;quot;var&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.VarDecl,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .param&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Identifier,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; identifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (T) { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; pulling out the common logic&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .@&amp;quot;var&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;item.name,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .param&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; item,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (bp.variable_map.get(identifier.name)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;entry&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (entry.scope&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .local)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.DuplicateDecl;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; unique_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.make_temporary(identifier.name);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.variable_map.put(bp.gpa, identifier.name, .{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; unique_name });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; TYPE CHECKING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; gop&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.type_map.getOrPut(bp.gpa, unique_name.real_idx);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (gop.found_existing) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (gop.value_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator&quot;&gt;* !=&lt;&#x2F;span&gt;&lt;span&gt; .int)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.TypeError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt; gop.value_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .int;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    identifier.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .{ .idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; unique_name };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (T&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .@&amp;quot;var&amp;quot;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; logic unique to declarations&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (item.init) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(bp, expr);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; called like this, inside `resolve_func_decl`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;while&lt;&#x2F;span&gt;&lt;span&gt; (params.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;param&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; resolve_var_decl(.param, inner_bp, param);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I ran the test suite again (and the eye tests) after this and everything seems to work out.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;internal-represntation&quot;&gt;Internal Represntation&lt;&#x2F;h2&gt;
&lt;p&gt;After a long drought, finally time to update the IR syntax tree and generation. Which means new assembly stuff later. Couldn&#x27;t the Book stick to adding more control flow constructs for ever? Maybe function calls can be implemented by just jumping around. Is that a thing?&lt;&#x2F;p&gt;
&lt;p&gt;The syntax tree updatss mirror the AST&#x27;s.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Identifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; utils.StringInterner.Idx;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; type alias&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Prgm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    funcs: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(FuncDef),&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;--&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; FuncDef&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name: Identifier,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    params: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(Identifier),&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;--&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    instrs: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(Instr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Instr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    func_call:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        name: Identifier,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        args: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(Value),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        dst: Value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; rest of the owl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And the rest is pretty much the same, sans a few updates to the pretty printers and deinitializers. Note that there are no function declarations, as they are discarded in this stage after being done with the type checking.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;prgm_emit_ir&lt;&#x2F;code&gt; is simply a small update from the one-function version to the many-functions version, skipping over declarations without bodies&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; prgm_emit_ir(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    strings:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;utils.StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    prgm:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; ast.Prgm,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ir.Prgm {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; funcs: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(ir.FuncDef) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; .initCapacity(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        prgm.funcs.len,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; prgm.funcs.constIterator(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (f.block) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;_&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; skip empty declarations&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; fir&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; func_def_emit_ir(alloc, strings, f);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; funcs.append(alloc, fir);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .funcs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; funcs };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;func_def_emit_ir&lt;&#x2F;code&gt; is also almost exactly the same, except that the identifiers are moved over.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; func_def_emit_ir(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    strings:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;utils.StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    func_def:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; ast.FuncDecl,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ir.FuncDef {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; strings.get_or_put(alloc, func_def.name);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; params: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(utils.StringInterner.Idx) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; .initCapacity(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        func_def.params.count(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; func_def.params.constIterator(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;param&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; params.append(alloc, param.idx);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; instrs: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(ir.Instr) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .empty;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; bp: Boilerplate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .alloc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .strings&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; strings,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .instrs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;instrs,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; block_emit_ir(bp,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;func_def.block.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; instrs.append(alloc, .{ .ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; } });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; name, .params&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; params, .instrs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instrs };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Function call expressions are new, even though they follow the same pattern as all other expressions.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.func_call&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; args: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(ir.Value) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; .initCapacity(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        bp.alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        f.@&amp;quot;1&amp;quot;.count(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .variable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.make_temporary(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;fn&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;) };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; f.@&amp;quot;1&amp;quot;.constIterator(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(bp, e);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; args.append(bp.alloc, v);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .func_call&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; f.@&amp;quot;0&amp;quot;.idx,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; args,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dst,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; dst;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The last thing left to do here is to make sure that functon declaration as block items are skipped as well.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; block_emit_ir(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bp: Boilerplate,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    block:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; ast.Block,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; block.body.constIterator(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (item.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .S&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; stmt_emit_ir(bp, s),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .D&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .V) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt; var_decl_emit_ir(bp,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;d.V),&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;small-detour-back-to-type-checking&quot;&gt;Small Detour Back to Type Checking&lt;&#x2F;h3&gt;
&lt;p&gt;I am honestly not quite sure about some decisions up to now. For example, if function declarations are discarded, why are their parameters given unique identities at all? Maybe I should go back and simply check the count (and ideally the types, but there are no types in here). This would change the end of &lt;code&gt;resolve_func_decl&lt;&#x2F;code&gt; to the following, instead of the if statement only encasing the last line. Since the count is checked earlier&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (func_decl.block) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt;|*&lt;&#x2F;span&gt;&lt;span&gt;block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; params&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; func_decl.params.iterator(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (params.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;param&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; resolve_var_decl(.param, inner_bp, param);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; resolve_block(inner_bp,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;, block);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This passes all validations tests, except one.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;* Duplicate parameter names are illegal in function declarations&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment z-punctuation z-definition z-comment&quot;&gt;   as well as definitions *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; foo(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; a,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; a);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; foo(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; foo(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; a,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; b) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; b;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ah well. Amusingly, at least according to the LLM I asked, &lt;code&gt;int foo(int, int)&lt;&#x2F;code&gt; &lt;em&gt;is&lt;&#x2F;em&gt; a legal declaration. Anyway, this was a failed detour.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;assembly-generation&quot;&gt;Assembly Generation&lt;&#x2F;h2&gt;
&lt;p&gt;This is the first serious brush in the Book with the System V ABI, the most common binary interface for Unixes. As there are currently no types more complex than &lt;code&gt;int&lt;&#x2F;code&gt;, all the compiler needs to worry about is stuffing parameters in the right registers. (And for function bodies, retreiving them from the right registers). The IR has not concerned itself with this, relying on the surrounding passes to make sense out of it.&lt;&#x2F;p&gt;
&lt;p&gt;In my Rust implementation, I used clever iterator combinators to write the logic for this section. I am kind of curious to see how it will turn out in Zig.&lt;&#x2F;p&gt;
&lt;p&gt;The first step, as usual, is to update the assembly syntax tree. A program needs to be redefined as a list of functions, and there are new instructions and new registers. Some necessary refactorings should be timed now as well. This is &lt;code&gt;assembly.Prgm&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Prgm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    funcs: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(FuncDef),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span&gt; fixup(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt;@This&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (self.funcs.items) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt;|*&lt;&#x2F;span&gt;&lt;span&gt;func&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F; functions called here changed from taking *Prgm to *FuncDef&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F; ideally this should live under FuncDef, but this is fine for now&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; pass_pseudo.replace_pseudos(alloc, func);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; func.instrs.insert(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;, .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .allocate_stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @abs&lt;&#x2F;span&gt;&lt;span&gt;(depth),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; pass_fixup.fixup_instrs(alloc, func);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The new instructions are simple additions. However, I am using two type aliases here: &lt;code&gt;Depth&lt;&#x2F;code&gt; for an unsigned version of stack depth, and &lt;code&gt;Identifier&lt;&#x2F;code&gt; for &lt;code&gt;utils.StringInterner.Idx&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;allocate_stack: Depth,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; old&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dealloc_stack: Depth,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push: Operand,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;call: Identifier,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And aside from the new Registers, which I will not bore you with, this is pretty much it.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-honesty-1&quot;&gt;&lt;a href=&quot;#fn-honesty&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; Implementing the codegen is the next step. parameters in function definitions need to be taken from their correct register and stack positions; and function calls need to stuff them there. &lt;code&gt;prgm_to_asm&lt;&#x2F;code&gt;, the main entry point, is straightforward.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; prgm_to_asm(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    prgm: ir.Prgm,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;assembly.Prgm {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; funcs: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(assembly.FuncDef) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; .initCapacity(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        prgm.funcs.items.len,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; (prgm.funcs.items) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;func&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; funcs.append(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; func_def_to_asm(alloc, func),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .funcs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; funcs };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For functions, it is slightly different. The first six parameters should be passed in these registers in this specific order: &lt;code&gt;DI&lt;&#x2F;code&gt;, &lt;code&gt;SI&lt;&#x2F;code&gt;, &lt;code&gt;DX&lt;&#x2F;code&gt;, &lt;code&gt;CX&lt;&#x2F;code&gt;, &lt;code&gt;R8&lt;&#x2F;code&gt;, and &lt;code&gt;R9&lt;&#x2F;code&gt;. Remaining arguments are pushed into the stack in &lt;em&gt;reverse order&lt;&#x2F;em&gt;. So normally, I will just assign a constant for them registers.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; REGISTERS: [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;]assembly.Operand.Register&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ .DI, .SI, .DX, .CX, .R8, .R9 };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In &lt;code&gt;func_def_to_asm&lt;&#x2F;code&gt; itself, a zipped &lt;code&gt;for&lt;&#x2F;code&gt; loop is perhaps the most straightforward way of doing this. The first section is simple enough. And since the remaining paramters are pushed into the stack at function call in reverse order, they are in the correct order here. Starting from a 16 &lt;code&gt;stack&lt;&#x2F;code&gt; offset, they are moved one by one. Luckily, this same loop can be used!&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; (func_def.params.items,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;..) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;param, idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; REGISTERS.len)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; instrs.append(alloc, .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; REGISTERS[idx] },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .pseudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; param },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ) })&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; REGISTERS.len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; 16, 24, etc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; instrs.append(alloc, .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @intCast&lt;&#x2F;span&gt;&lt;span&gt;(offset) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .pseudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; param },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ) });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Implementing function calls is a lot more involved. First, the stack needs to be aligned properly at 16, as per the System V ABI. Copying the passed in expressions to the input registers is easy, but reversing the rest of them requires some shenanigans. First is to have a stack allocated array with the maximum possible size because it is unknown at the outset what the size of the returned slice could be.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; the return is of unknown size.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; maximum possible size is parameter count * 2 + 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;var&lt;&#x2F;span&gt;&lt;span&gt; ret: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(assembly.Instr) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; .initCapacity(alloc, c.args.items.len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then calculate the amount of arguments in the stack and the needed padding to 16. Zig has a saturating subtraction operator &lt;code&gt;-|&lt;&#x2F;code&gt; that is perfect for this.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; c.args.items.len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator&quot;&gt; -|&lt;&#x2F;span&gt;&lt;span&gt; REGISTERS.len;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; padding: assembly.Instr.Depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (padding&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; ret.append(alloc, .{ .allocate_stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; padding });&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The numbering in the comments is me keeping track of instructions that do not depend on parameters count. After that comes putting the values in their respective registers, and the stack.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-registers-1&quot;&gt;&lt;a href=&quot;#fn-registers&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; (c.args.items,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;..) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;arg, idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span&gt; REGISTERS.len) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; ret.append(alloc, .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; REGISTERS[idx] },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        value_to_asm(arg),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;..depth) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; v_ir&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; c.args.items[c.args.items.len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; idx];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; v_asm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value_to_asm(v_ir);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (v_asm) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .imm, .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; ret.append(alloc, .{ .push&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; v_asm }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; ret.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(v_asm, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .AX }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .push&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .AX } },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I think this should work. &lt;code&gt;0..depth&lt;&#x2F;code&gt; will be .. nothing, and the loop will not run. If it is larger, it starts from the last item (at index &lt;code&gt;len - , 1&lt;&#x2F;code&gt;), then subtracts the current index of the loop. And finally, dealing with the return value, and returning the slice.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; emit call instruction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt; ret.append(alloc, .{ .call&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; c.name });&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; bytes_to_remove&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; padding;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (bytes_to_remove&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; ret.append(alloc, .{ .dealloc_stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bytes_to_remove });&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt; ret.append(alloc, .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .AX },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    value_to_asm(c.dst),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) });&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt; ret.items;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Doing the eye test for codegen, I quickly noticed something stupid. I am moving the register&#x27;s value to an immutable. Oops.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; add(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; x,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; y);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; add(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 		allocate	4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 		allocate	8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 		mov	DI -&amp;gt; imm 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 		mov	SI -&amp;gt; imm 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 		call	.Ladd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 		deallocate	8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 		mov	AX -&amp;gt; stack -4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 		mov	stack -4 -&amp;gt; AX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 		ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 		mov	imm 0 -&amp;gt; AX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 		ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Fixing that by switching two lines, the eye test passes fine. The test suite does not hit any errors (and, as a reminder, does not test beyond success a nd failure).&lt;&#x2F;p&gt;
&lt;p&gt;After that comes the annoying fixup pass adjustments. The depth returned by &lt;code&gt;replace_pseudos&lt;&#x2F;code&gt; is adjusted to save the depth of each function in a field in the function definition. And also, when allocating, rounding that up to the nearest multiple of 16.&lt;&#x2F;p&gt;
&lt;p&gt;There is a neat trick to round up a number, &lt;code&gt;n&lt;&#x2F;code&gt;, to the nearest multiple of 16. Basically &lt;code&gt;(n + 15) &amp;amp; ~15&lt;&#x2F;code&gt;. Unfortunately, Zig makes this a pain to write because the integer type inference is not clever enough to understand &lt;code&gt;~15&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;There in the standard library is a helpful function to do that math: &lt;code&gt;std.mem.alignForward&lt;&#x2F;code&gt;. Kindly pointed to me by the Zig Discord. So I added this bit at the end of &lt;code&gt;replace_pseudos&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;func_def.depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @intCast&lt;&#x2F;span&gt;&lt;span&gt;(pseudo_map.count() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; aligned&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.mem.alignForward(assembly.Instr.Depth, func_def.depth,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt; func_def.instrs.insert(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;, .{ .allocate_stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; aligned });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So, time to actually emit the assembly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;code-emission&quot;&gt;Code Emission&lt;&#x2F;h2&gt;
&lt;p&gt;The changes here are pretty small. The new instructions are one thing, but there are new registers and new register sizes for &lt;code&gt;push&lt;&#x2F;code&gt;, which takes 8-width registers. The logic for printing registers got pretty large so I put it in its own function.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; emit_register(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    reg: Operand.Register,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    width:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    writer:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; anytype&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    p:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (width) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;        1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (reg) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .AX&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%al&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .DX&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%dl&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .CX&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%cl&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .DI&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%dil&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .SI&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%sil&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .R8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%r8b&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .R9&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%r9b&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .R10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%r10b&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .R11&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%r11b&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;        4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (reg) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .AX&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%eax&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .DX&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%edx&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .CX&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%ecx&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .DI&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%edi&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .SI&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%esi&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .R8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%r8d&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .R9&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%r9d&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .R10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%r10d&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .R11&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%r11d&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;        8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (reg) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .AX&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%rax&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .DX&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%rdx&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .CX&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%rcx&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .DI&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%rdi&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .SI&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%rsi&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .R8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%r8&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .R9&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%r9&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .R10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%r10&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .R11&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%r11&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; continue&lt;&#x2F;span&gt;&lt;span&gt; :p&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; default case&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And then in the format function just do the following. There is a bit of redundancy regarding the 4 as a default case. You are not paranoid if they &lt;em&gt;are&lt;&#x2F;em&gt; out to get you!&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; emit_register(r, options.width&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; orelse&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;, writer),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Running the test suite, I get into 16 failures. Oh come on.&lt;&#x2F;p&gt;
&lt;p&gt;Most of them seem to be &lt;code&gt;UnrecognizedFlag&lt;&#x2F;code&gt;, which is the error I have in the compiler driver for flags that are unrecognized. That is what I get for not reading the text and jumping straight to the tables. There is a tidbit there about recognizing a &lt;code&gt;-c&lt;&#x2F;code&gt; flag, which is the &lt;code&gt;gcc&lt;&#x2F;code&gt; flag for creating object files instead of executables.&lt;&#x2F;p&gt;
&lt;p&gt;This is a small change to the argument parser. That is the new one:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; parse_args() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;Args {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.process.args();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; args.skip();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; path:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt;[:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt; u8 =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; mode: Mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .compile;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; c_flag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-bool z-zig&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; new&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (args.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;arg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (arg[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;-&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (arg[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;c&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; new&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                c_flag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-bool z-zig&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.meta.stringToEnum(Mode, arg[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;..]) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.UnrecognizedFlag;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else if&lt;&#x2F;span&gt;&lt;span&gt; (path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; arg&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.PathDuplicated;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; orelse return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.PathNotFound,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; mode,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .c_flag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; c_flag,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; new&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And mugh below that, when calling the assembler, the &lt;code&gt;-c&lt;&#x2F;code&gt; flag is passed if &lt;code&gt;c_flag&lt;&#x2F;code&gt; is true. And changing the extension to &lt;code&gt;.o&lt;&#x2F;code&gt;. So it becomes the following (changing the extension itself is done elsewhere in a bit of rather annoying code). This is probably the nicest way of doing it.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; assembler&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; child&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.process.Child.init(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (args.c_flag)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;            &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;gcc&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;-c&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, asm_out,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;-o&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, obj }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;            &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;gcc&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, asm_out,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;-o&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, exe },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        gpa,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; term&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; child.spawnAndWait();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;std.meta.eql(term, .{ .Exited&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; }))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.AssemblerFail;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; std.fs.cwd().deleteFile(asm_out);&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; cleanup&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now running the test suite for real.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;debugging&quot;&gt;Debugging&lt;&#x2F;h2&gt;
&lt;p&gt;On the plud side, all the programs ar ecompiling and running. On the negative side, I got a lot of bad return codes. There are logic mistakes. Also 3 errors relating to unicode and timeouts? I do not get it. The test suite&#x27;s output is generally jumbled up and I find it hard to process. Having said that, the easiest way to attack the problem is to look at the individual files and compiles them myself.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;unicodedecodeerror&quot;&gt;UnicodeDecodeError&lt;&#x2F;h3&gt;
&lt;p&gt;This is one of the weird errors, Nora Sandler&#x27;s comments and all. The program should call the system&#x27;s &lt;code&gt;putchar&lt;&#x2F;code&gt;, which prints a character to standard out.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;#ifdef&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function z-preprocessor z-c&quot;&gt; SUPPRESS_WARNINGS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;#pragma&lt;&#x2F;span&gt;&lt;span&gt; GCC diagnostic ignored&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;-Wunused-parameter&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;#endif&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; putchar(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; c);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;* Make sure we can correctly manage calling conventions from the callee side&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * (by accessing parameters, including parameters on the stack) and the caller side&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt; * (by calling a standard library function) in the same function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; foo(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; a,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; b,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; c,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; d,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; e,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; f,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; g,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; h) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    putchar(h);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; g;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; foo(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 65&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is the output for each stage.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PARSING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION putchar c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION foo a b c d e f g h&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		(putchar h);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		RETURN (+ a g)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		RETURN (foo 1 2 3 4 5 6 7 65)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;================================&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VALIDATION&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION putchar c.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION foo a.1 b.2 c.3 d.4 e.5 f.6 g.7 h.8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		(putchar h.8);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		RETURN (+ a.1 g.7)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		RETURN (foo 1 2 3 4 5 6 7 65)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;================================&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;IR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION foo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		fn.9 &amp;lt;- putchar(h.8)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		add.10 &amp;lt;- a.1 + g.7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ret add.10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ret 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		fn.11 &amp;lt;- foo(1, 2, 3, 4, 5, 6, 7, 65)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ret fn.11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ret 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;================================&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;CODEGEN&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION foo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		allocate	48&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	DI -&amp;gt; stack -4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	SI -&amp;gt; stack -8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	DX -&amp;gt; stack -12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	CX -&amp;gt; stack -16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R8 -&amp;gt; stack -20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R9 -&amp;gt; stack -24&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack 16 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -28&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack 24 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		allocate	8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -32 -&amp;gt; DI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		call	.Lputchar&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		deallocate	8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	AX -&amp;gt; stack -36&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -4 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -40&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -28 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		add	R10 -&amp;gt; stack -40&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -40 -&amp;gt; AX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 0 -&amp;gt; AX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		allocate	16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		allocate	8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 1 -&amp;gt; DI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 2 -&amp;gt; SI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 3 -&amp;gt; DX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 4 -&amp;gt; CX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 5 -&amp;gt; R8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 6 -&amp;gt; R9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		push	imm 65&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		push	imm 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		call	.Lfoo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		deallocate	24&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	AX -&amp;gt; stack -4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -4 -&amp;gt; AX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 0 -&amp;gt; AX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Hold on, before going into assembly, I spot a weird thing here. Why is the call to &lt;code&gt;foo&lt;&#x2F;code&gt; is preceded by &lt;code&gt;.L&lt;&#x2F;code&gt;. This is probably a formatting error which does not matter. But more importantly, the numbers for deallocations seem weird. Why is it deallocating 24? Let&#x27;s review the logic in &lt;code&gt;instr_to_asm&lt;&#x2F;code&gt; in &lt;code&gt;.func_call&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; bytes_to_remove&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; padding;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (bytes_to_remove&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; ret.append(alloc, .{ .dealloc_stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bytes_to_remove });&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Eh, this makes sense. Counting the arguments passed on the stack there, there are 2. So why is there padding?&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; padding: assembly.Instr.Depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;--- here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (padding&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; ret.append(alloc, .{ .allocate_stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; padding });&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Oh I am assigning the padding in reverse. If the number of arguments is even, there should be no padding. Silly me.&lt;&#x2F;p&gt;
&lt;p&gt;This does not actually deal with the error I got for this file, which is this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;UnicodeDecodeError: &amp;#39;utf-8&amp;#39; codec can&amp;#39;t decode byte 0x90 in position 0: invalid start byte&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This might be the valued printed by &lt;code&gt;putchar&lt;&#x2F;code&gt; failing to read. However, only way to know is to run the test suit again.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; paella ❱ zig build submit&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; --release=safe  -- --chapter 9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;# many moths later&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;----------------------------------------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ran&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; tests in 60.822s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FAILED (failures=12)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Hey at least no weird UTF-8 errors. That&#x27;s 7 less failures than last time (which was 16 failures and 3 errors).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;assertionerror&quot;&gt;AssertionError&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: Please do not rad this section. It is embarrassing.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This is a more readable error than the last one.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;AssertionError:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; Incorrect behavior in chapter_9&#x2F;valid&#x2F;stack_arguments&#x2F;test_for_memory_leaks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; Bad return code: expected 1 and got 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I can work with this. This is the C file in question. These are a lot of arguments.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;* Make sure stack arguments are deallocated correctly after returning from a function call; also test passing variables as stack arguments *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;#ifdef&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function z-preprocessor z-c&quot;&gt; SUPPRESS_WARNINGS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;#pragma&lt;&#x2F;span&gt;&lt;span&gt; GCC diagnostic ignored&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;-Wunused-parameter&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;#endif&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; lots_of_args(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; a,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; b,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; c,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; d,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; e,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; f,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; g,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; h,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; i,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; j,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; k,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; l,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; m,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; n,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; o) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; l &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; o;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; ret &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10000000&lt;&#x2F;span&gt;&lt;span&gt;; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; lots_of_args(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;, ret,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; ret &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 150000000&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I will skip the whole parsing to IR thing and simply give you here the last codegen, with added comments. It is &lt;em&gt;huge&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION lots_of_args&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		allocate	64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	DI -&amp;gt; stack -4		; a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	SI -&amp;gt; stack -8		; b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	DX -&amp;gt; stack -12		; c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	CX -&amp;gt; stack -16		; d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R8 -&amp;gt; stack -20		; e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R9 -&amp;gt; stack -24		; f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack 16 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -28	; g&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack 24 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -32	; h&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack 32 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -36	; i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack 40 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -40	; j&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack 48 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -44	; k&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack 56 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -48	; l&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack 64 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -52	; m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack 72 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -56	; n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack 80 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -60	; o&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -48 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -64	; l&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -60 -&amp;gt; R10	; o&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		add	R10 -&amp;gt; stack -64	; l + o&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -64 -&amp;gt; AX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 0 -&amp;gt; AX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		allocate	32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 0 -&amp;gt; stack -4	; ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 0 -&amp;gt; stack -8	; i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		=&amp;gt; .Lst_for.16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		cmp	imm 10000000 -&amp;gt; stack -8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 0 -&amp;gt; stack -12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		setl	stack -12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		cmp	imm 0 -&amp;gt; stack -12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jmpe	.Lbr_for.16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		allocate	8	; odd number of arguments&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		; register arguments&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 1 -&amp;gt; DI	; a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 2 -&amp;gt; SI	; b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 3 -&amp;gt; DX	; c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 4 -&amp;gt; CX	; d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 5 -&amp;gt; R8	; e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 6 -&amp;gt; R9	; f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		; stack arguments&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		push	imm 15		; o&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		push	imm 14		; n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		push	imm 13		; m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -4 -&amp;gt; AX 	; ret into l&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		push	AX		; l&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		push	imm 11		; k&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		push	imm 10		; j&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		push	imm 9		; i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		push	imm 8		; h&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		push	imm 7		; g&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		call	lots_of_args&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		deallocate	80	; why is this 80? 9 pushes + padding&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	AX -&amp;gt; stack -16	; l + o here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -16 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -4	; assign to ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		=&amp;gt; .Lcn_for.16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -8 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		add	imm 1 -&amp;gt; stack -20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -20 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jmp	.Lst_for.16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		=&amp;gt; .Lbr_for.16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		cmp	imm 150000000 -&amp;gt; stack -4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 0 -&amp;gt; stack -24&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		sete	stack -24&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -24 -&amp;gt; AX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 0 -&amp;gt; AX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I am actually at a loss. All this seems to make sense. The generated asembly is more of the same. Let us see another failure:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;AssertionError:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; Incorrect behavior in chapter_9&#x2F;valid&#x2F;arguments_in_registers&#x2F;fibonacci&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; Bad return code: expected 8 and got -11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;How would you even &lt;em&gt;get&lt;&#x2F;em&gt; -11?&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; fib(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; n) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; n;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; fib(n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; fib(n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; fib(n);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is the assembly this time.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.globl _fib&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;_fib:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	pushq   %rbp		;; function prologue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movq    %rsp, %rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	subq    $48, %rsp	;; allocate 48&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    %edi, -4(%rsp)	;; n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	cmpl    $0, -4(%rsp)	;; does n equal 0?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    $0, -8(%rsp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	sete      -8(%rsp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	cmpl    $0, -8(%rsp)	;; is n == 0 true ?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	jne     .Ltrue_or.2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	cmpl    $1, -4(%rsp)	;; does n equal 1?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    $0, -12(%rsp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	sete      -12(%rsp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	cmpl    $0, -12(%rsp)	;; is n == 1 true?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	jne     .Ltrue_or.2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    $0, -16(%rsp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	jmp    .Lend_or.3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.Ltrue_or.2:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    $1, -16(%rsp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.Lend_or.3:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	cmpl    $0, -16(%rsp)	;; is the previous expresison false?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	je      .Lelse.7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -4(%rsp), %eax	;; if so just return n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movq    %rbp, %rsp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	popq    %rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	jmp    .Lend.8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.Lelse.7:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -4(%rsp), %r10d		;; if not ..&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    %r10d, -20(%rsp)	;; move n here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	subl    $1, -20(%rsp)		;; n - 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -20(%rsp), %edi		;; move n-1 to edi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	call    _fib			;; call fib&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    %eax, -24(%rsp)		;; stash result of fib(n-1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -4(%rsp), %r10d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    %r10d, -28(%rsp)	;; move n here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	subl    $2, -28(%rsp)		;; n - 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -28(%rsp), %edi		;; move n-1 to edi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	call    _fib			;; call fib&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    %eax, -32(%rsp)		;; stash result of fib(n-2)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -24(%rsp), %r10d	;; stashed result of fib(n-1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    %r10d, -36(%rsp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -32(%rsp), %r10d	;; stashed result of fib(n-2)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	addl    %r10d, -36(%rsp)	;; add two results together&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -36(%rsp), %eax		;; move result to proper place&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movq    %rbp, %rsp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	popq    %rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	ret				;; the end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.Lend.8:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    $0, %eax	;; this bit here is the useless return 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movq    %rbp, %rsp	;; added at the end of every function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	popq    %rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.globl _main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;_main:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	pushq   %rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movq    %rsp, %rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	subq    $16, %rsp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    $6, -4(%rsp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -4(%rsp), %edi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	call    _fib&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    %eax, -8(%rsp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -8(%rsp), %eax&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movq    %rbp, %rsp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	popq    %rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    $0, %eax&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movq    %rbp, %rsp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	popq    %rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The logic seems fine. I am not debugging the logic for &lt;code&gt;if&lt;&#x2F;code&gt;s and &lt;code&gt;for&lt;&#x2F;code&gt;s as those test cases pass fine already. This sample here has no stack arguments yet it is still failing. This definitely means there is a memory corruption somewhere, but &lt;em&gt;where&lt;&#x2F;em&gt;? I am sure the smart ones of you spotted it. I am not that smart.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-llm-1&quot;&gt;&lt;a href=&quot;#fn-llm&quot;&gt;5&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I figured maybe the mistake is from using the subshell. So I tried doing the test suite the manual way I did it previously. But nope, same result. The good news is that my subshell spell works perfectly.&lt;&#x2F;p&gt;
&lt;p&gt;On a whim, which is most likely wrong, I thought of changing the sign of the stack offset for function bodies. (So they start from -16 downwards rather than 16 upwards). And that would not affect the failure in the &lt;code&gt;fibonacci&lt;&#x2F;code&gt; example anyway. Surprisingly, that actually affected absolutely nothing: same number of failing cases. I am starting to think this is a &lt;code&gt;parking_lot&lt;&#x2F;code&gt; bug.&lt;&#x2F;p&gt;
&lt;p&gt;I moved to compare the codegen stage with my previous rust program, and it is &lt;em&gt;identical&lt;&#x2F;em&gt;. I moved on to comparing the assembly generated. Even using &lt;code&gt;diff&lt;&#x2F;code&gt; &lt;em&gt;with colors&lt;&#x2F;em&gt; to compare the two assemblies.&lt;&#x2F;p&gt;
&lt;p&gt;Then there I saw it. The logic is fine, but there is a typo: something I wrote many chapters ago.&lt;&#x2F;p&gt;
&lt;p&gt;Behold: stack offsets: &lt;code&gt;-8(%rsp)&lt;&#x2F;code&gt;. It should be from &lt;code&gt;%rbp&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Now all the tests pass. Wonder how any of them did in the first place.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Spell checking is important.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;diff --color&lt;&#x2F;code&gt; is a useful tool.&lt;&#x2F;li&gt;
&lt;li&gt;Unrelated to &lt;code&gt;paella&lt;&#x2F;code&gt; itself, but I made some improvements to the build script, and learned more abot &lt;code&gt;jj&lt;&#x2F;code&gt; and &lt;code&gt;git&lt;&#x2F;code&gt;. I think I will add &lt;code&gt;git&lt;&#x2F;code&gt; tags to commits that finish each chapter, which would make browsing them easier.&lt;&#x2F;li&gt;
&lt;li&gt;This week I instealled &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;llm.datasette.io&#x2F;en&#x2F;stable&#x2F;index.html&quot;&gt;&lt;code&gt;llm&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, and had it set up to talk to the free version of Github Copilot. Really convenient and useful, and I used to spell check the articles. I will try some local models next but I do not expect they will do much with my Macbook Air M2.&lt;&#x2F;li&gt;
&lt;li&gt;Can I have typed integer literals or slightly greedier type inference in Zig please? It is absurd that &lt;code&gt;~15&lt;&#x2F;code&gt; &lt;em&gt;just does not work&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;One chapter left for Part 1. Unsure what to do next.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-linker&quot;&gt;
&lt;p&gt;Type errors between different files is very pointedly a not-my-problem. It is a linker error, while this is a compiler. &lt;a href=&quot;#fr-linker-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-const&quot;&gt;
&lt;p&gt;When will Rust have enums as proper const generics? Please, Rust. &lt;a href=&quot;#fr-const-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-honesty&quot;&gt;
&lt;p&gt;To be honest, and for all chapters, I am skipping most of the reading and jumping through to the tables at the end of the section to implement the functions. I assume that is what the tables are for. &lt;a href=&quot;#fr-honesty-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-registers&quot;&gt;
&lt;p&gt;The Book&#x27;s pseudocode gives different instructions to add if the IR value is converted to an immediate value, register, or a pseudo value. The weird part here is that, well until chapter 15 (where I stopped last time), the IR value is never converted to a register at this stage. This could be something in preparation for the optimizations in Part 3. &lt;a href=&quot;#fr-registers-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-llm&quot;&gt;
&lt;p&gt;Gemini LLM told me this is fine. Though to be honest, Github Copilot pointed it out, but I missed it among the five useless things it also mentioned. &lt;a href=&quot;#fr-llm-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Chapter 8: Loops</title>
        <published>2025-05-27T00:00:00+00:00</published>
        <updated>2025-05-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/paella/c8/"/>
        <id>https://ar-ms.me/paella/c8/</id>
        
        <content type="html" xml:base="https://ar-ms.me/paella/c8/">&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;paella&#x2F;c7&#x2F;&quot;&gt;Seven&lt;&#x2F;a&gt; done of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;norasandler.com&#x2F;2022&#x2F;03&#x2F;29&#x2F;Write-a-C-Compiler-the-Book.html&quot;&gt;Writing a C Compiler&lt;&#x2F;a&gt;, a few more to go. Now is the time for loops.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lexer-ast-and-parser&quot;&gt;Lexer, AST and Parser&lt;&#x2F;h2&gt;
&lt;p&gt;The lexer is just a few new keywords. Been there, done that. Changes to the AST are more interesting. No less than five new statements, one for every new keyword. Here is the new &lt;code&gt;Stmt&lt;&#x2F;code&gt; without further ado:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Stmt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @&amp;quot;return&amp;quot;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    expr:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @&amp;quot;if&amp;quot;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; { cond:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr, then:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Stmt, @&amp;quot;else&amp;quot;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; ?*&lt;&#x2F;span&gt;&lt;span&gt;Stmt },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    compound: Block,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @&amp;quot;break&amp;quot;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt;[:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @&amp;quot;continue&amp;quot;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt;[:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @&amp;quot;while&amp;quot;: While,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    do_while: While,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @&amp;quot;for&amp;quot;: For,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt;    null&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; void&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; While&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cond:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        body:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Stmt,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        label:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt;[:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;    pub const&lt;&#x2F;span&gt;&lt;span&gt; For&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        label:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt;[:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        init: Init,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cond:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; ?*&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        post:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; ?*&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        body:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Stmt,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;        pub const&lt;&#x2F;span&gt;&lt;span&gt; Init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) { decl:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Decl, expr:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr, none },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A few notes. Each of these statements have an optional label argument. This label is used later to associate &lt;code&gt;break&lt;&#x2F;code&gt;s and &lt;code&gt;continue&lt;&#x2F;code&gt;s with their associated loops during semantic analysis. You cannot actually assign labels to loops in C as far as I know.&lt;&#x2F;p&gt;
&lt;p&gt;Also, usually for a one off subtype like &lt;code&gt;For&lt;&#x2F;code&gt; here, I put it inline. But this one is big and hairy and has a subtype of its own that it warrants the special treatment. &lt;code&gt;Init&lt;&#x2F;code&gt; itself is named because I am naming it later in the parser. To map the fields to the actually &lt;code&gt;for&lt;&#x2F;code&gt; loop in code, it is basically this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; (init, cond, post) body&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;All the three first fields are optional. The reason that &lt;code&gt;none&lt;&#x2F;code&gt; is a state of &lt;code&gt;init&lt;&#x2F;code&gt; instead of using an optional is to shave a few bytes from the size of &lt;code&gt;init&lt;&#x2F;code&gt; (and therefore the whole &lt;code&gt;For&lt;&#x2F;code&gt; type and then the whole &lt;code&gt;Stmt&lt;&#x2F;code&gt; type).&lt;&#x2F;p&gt;
&lt;p&gt;Parsing these is a bit more interesting. First, the straightforward &lt;code&gt;break&lt;&#x2F;code&gt; and &lt;code&gt;continue&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.keyword_break&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.semicolon, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .@&amp;quot;break&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt; };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.keyword_continue&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.semicolon, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .@&amp;quot;continue&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt; };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;while&lt;&#x2F;code&gt; and &lt;code&gt;do while&lt;&#x2F;code&gt; are slightly more interesting. They&#x27;re similar to &lt;code&gt;if&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.keyword_while&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.l_paren, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; cond_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(arena, cond);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.r_paren, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; body&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_stmt(arena, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; body_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(arena, body);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .@&amp;quot;while&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cond_ptr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .body&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; body_ptr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.keyword_do&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; body&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_stmt(arena, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; body_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(arena, body);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.keyword_while, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.l_paren, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; cond_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(arena, cond);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.r_paren, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.semicolon, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .do_while&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cond_ptr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .body&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; body_ptr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now time for the final boss. &lt;code&gt;for&lt;&#x2F;code&gt;. There is a funny complication here that I hit on my previous Rust implementation. The parsing code for variable declarations already expects a semicolon, but the one for expressions &lt;em&gt;does not&lt;&#x2F;em&gt;. So if I determine the &lt;code&gt;init&lt;&#x2F;code&gt; statement is a variable declaration, I need not check for a semicolon, whereas I do if it turns out to be empty or an expression.&lt;&#x2F;p&gt;
&lt;p&gt;There is another problem that&#x27;s perhaps unique to the current implementation, which is that, if you remember, when parsing statements divorced from parsing variable declarations, &lt;code&gt;parse_stmt&lt;&#x2F;code&gt; moved into its own home, while parsing declarations still clung to the old home of &lt;code&gt;parse_block_item&lt;&#x2F;code&gt;. Now that variable declarations have a new partner, they need to move to their own home. The divorce is finally complete.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_block_item(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    arena: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ast.BlockItem {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; current&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.NotEnoughJunk;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens.put_back(current);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (current.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .type_int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; .decl(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt; parse_var_decl(arena, tokens)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; .stmt(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt; parse_stmt(arena, tokens)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_var_decl(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    arena: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ast.Decl {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.type_int, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expect(.identifier, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; new_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.NotEnoughJunk;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; init:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; ?*&lt;&#x2F;span&gt;&lt;span&gt;ast.Expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (new_token.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .equals&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ret: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(arena, expr);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; expect(.semicolon, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            break&lt;&#x2F;span&gt;&lt;span&gt; :ret expr_ptr;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .semicolon&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; name, .init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; init };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now that I am properly equipped, time to take on &lt;code&gt;for&lt;&#x2F;code&gt;. After the left parenthesis, take it one piece at a time. First is &lt;code&gt;init&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; I needed the type here so I had to name it and make it pub in the AST&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; init: ast.Stmt.For.Init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; init: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; new_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.NotEnoughJunk;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (new_token.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .semicolon&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; break&lt;&#x2F;span&gt;&lt;span&gt; :init .none,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .type_int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tokens.put_back(new_token);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; decl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_var_decl(arena, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; decl_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(arena, decl);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            break&lt;&#x2F;span&gt;&lt;span&gt; :init .{ .decl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; decl_ptr };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tokens.put_back(new_token);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(arena, expr);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; expect(.semicolon, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            break&lt;&#x2F;span&gt;&lt;span&gt; :init .{ .expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; expr_ptr };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The other two are tamer beasts. A small difference between &lt;code&gt;cond&lt;&#x2F;code&gt; and &lt;code&gt;post&lt;&#x2F;code&gt; is the &lt;code&gt;post&lt;&#x2F;code&gt; does not require a semicolon to terminate it, so it is compared to the right parenthesis instead.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; cond:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; ?*&lt;&#x2F;span&gt;&lt;span&gt;ast.Expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cond: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; new_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.NotEnoughJunk;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (new_token.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .semicolon&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; break&lt;&#x2F;span&gt;&lt;span&gt; :cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tokens.put_back(new_token);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(arena, expr);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; expect(.semicolon, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            break&lt;&#x2F;span&gt;&lt;span&gt; :cond expr_ptr;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; post:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; ?*&lt;&#x2F;span&gt;&lt;span&gt;ast.Expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; post: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; new_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.NotEnoughJunk;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (new_token.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .r_paren&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; break&lt;&#x2F;span&gt;&lt;span&gt; :post&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tokens.put_back(new_token);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(arena, expr);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; expect(.r_paren, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            break&lt;&#x2F;span&gt;&lt;span&gt; :post expr_ptr;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then finally, the coup de grace:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; body&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_stmt(arena, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; body_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(arena, body);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt; .{ .@&amp;quot;for&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; init,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cond,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .post&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; post,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .body&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; body_ptr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;} };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This about covers it I think. One tiny complication remains: in implementing the pretty printer last chapter, I used the keyword &lt;code&gt;DO&lt;&#x2F;code&gt; for blocks. So instead of repeating myself, I am going to use a different keyword for &lt;code&gt;do while&lt;&#x2F;code&gt; loops: &lt;code&gt;UNTIL&lt;&#x2F;code&gt;. These look fine. Time to move on.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; sum &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            continue&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        sum &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; sum &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; i;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; sum;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 		int sum &amp;lt;- 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 		FOR int i &amp;lt;- 0; (&amp;lt; i 10); ---&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 			(i &amp;lt;- (+ i 1));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 			IF (% i 2)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 				CONTINUE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 			(sum &amp;lt;- (+ sum i));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 		RETURN sum&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    do&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; while&lt;&#x2F;span&gt;&lt;span&gt;(a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; a;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 		int a &amp;lt;- 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 		UNTIL (&amp;lt; a 11)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 			(a &amp;lt;- (* a 2));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 		RETURN a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;semantic-analysis&quot;&gt;Semantic Analysis&lt;&#x2F;h2&gt;
&lt;p&gt;In addition to variable resolution, this chapter will also do loop labelling, attaching each &lt;code&gt;break&lt;&#x2F;code&gt; and &lt;code&gt;continue&lt;&#x2F;code&gt; to their parent loops. While C does not have labelled loops, &lt;code&gt;goto&lt;&#x2F;code&gt; aside, this is still needed to generate the proper labels for IR and assembly &lt;code&gt;jump&lt;&#x2F;code&gt; instructions.&lt;&#x2F;p&gt;
&lt;p&gt;Resolving variables in &lt;code&gt;while&lt;&#x2F;code&gt; and &lt;code&gt;do while&lt;&#x2F;code&gt; is fairly simple, just like an &lt;code&gt;if&lt;&#x2F;code&gt; statement. &lt;code&gt;break&lt;&#x2F;code&gt; and &lt;code&gt;continue&lt;&#x2F;code&gt; have nothing to resolve. &lt;code&gt;for&lt;&#x2F;code&gt; loops, are, once again, more complicated. A new scope is introduced, similarly to compound statements, &lt;em&gt;on top of&lt;&#x2F;em&gt; the scope introduced by the inner compound statement. Instead of duplicating the boilerplate, I thought to combine &lt;code&gt;for&lt;&#x2F;code&gt; statements and &lt;code&gt;compound&lt;&#x2F;code&gt; statements into one branch as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.@&amp;quot;for&amp;quot;, .compound&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; variable_map&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.variable_map.clone(bp.gpa);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; variable_map.deinit(bp.gpa);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; variable_map.valueIterator();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        value.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value.name, .scope&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .parent };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; inner_bp: Boilerplate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .gpa&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bp.gpa,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .strings&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bp.strings,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .variable_map&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;variable_map,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (stmt.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .compound&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_block(inner_bp, b),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .@&amp;quot;for&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            switch&lt;&#x2F;span&gt;&lt;span&gt; (f.init) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .decl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_decl(inner_bp, d),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(inner_bp, e),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .none&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (f.cond) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(inner_bp, c);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (f.post) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(inner_bp, p);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; resolve_stmt(inner_bp, f.body);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-statement z-zig&quot;&gt; unreachable&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Regarding loop labelling, the Book does this in a separate pass from variable resolution. I do not particularly feel like creating yet another file (as I have each compiler pass in its own file), so I will try to do it within &lt;code&gt;resolve_stmt&lt;&#x2F;code&gt;. After all, all the related structures are statements.&lt;&#x2F;p&gt;
&lt;p&gt;Since it is being called recursively, an additional parameter is needed. I will pass it separately to avoid updating the &lt;code&gt;Boilerplate&lt;&#x2F;code&gt; struct for every time &lt;code&gt;resolve_stmt&lt;&#x2F;code&gt; is called, which would, ironically, increase the boilerplate.&lt;&#x2F;p&gt;
&lt;p&gt;This is the new &lt;code&gt;resolve_stmt&lt;&#x2F;code&gt; in all its glory.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; resolve_stmt(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bp: Boilerplate,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    current_label:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt;[:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    stmt:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Stmt,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (stmt.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt;null&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .@&amp;quot;break&amp;quot;, .@&amp;quot;continue&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;l&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; l.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; current_label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.BreakOutsideLoop,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .@&amp;quot;return&amp;quot;, .expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(bp, expr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .@&amp;quot;if&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(bp, i.cond);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; resolve_stmt(bp, current_label, i.then);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (i.@&amp;quot;else&amp;quot;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                try&lt;&#x2F;span&gt;&lt;span&gt; resolve_stmt(bp, current_label, e);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .@&amp;quot;while&amp;quot;, .do_while&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;w&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.make_temporary(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;while&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            w.label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; label;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; forgot this on the first pass!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(bp, w.cond);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; resolve_stmt(bp, label, w.body);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .@&amp;quot;for&amp;quot;, .compound&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            var&lt;&#x2F;span&gt;&lt;span&gt; variable_map&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.variable_map.clone(bp.gpa);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            defer&lt;&#x2F;span&gt;&lt;span&gt; variable_map.deinit(bp.gpa);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; variable_map.valueIterator();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                value.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value.name, .scope&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .parent };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; inner_bp: Boilerplate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .gpa&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bp.gpa,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .strings&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bp.strings,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .variable_map&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;variable_map,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            switch&lt;&#x2F;span&gt;&lt;span&gt; (stmt.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .compound&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_block(inner_bp, current_label, b),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .@&amp;quot;for&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;                    const&lt;&#x2F;span&gt;&lt;span&gt; label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.make_temporary(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;for&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    f.label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; label;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    switch&lt;&#x2F;span&gt;&lt;span&gt; (f.init) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        .decl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_decl(inner_bp, d),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        .expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(inner_bp, e),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        .none&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    if&lt;&#x2F;span&gt;&lt;span&gt; (f.cond) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(inner_bp, c);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    if&lt;&#x2F;span&gt;&lt;span&gt; (f.post) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(inner_bp, p);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    try&lt;&#x2F;span&gt;&lt;span&gt; resolve_stmt(inner_bp, label, f.body);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-statement z-zig&quot;&gt; unreachable&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With tiny related adjustments to &lt;code&gt;resolve_block&lt;&#x2F;code&gt;&#x27;s body and signature and &lt;code&gt;resolve_func_def&lt;&#x2F;code&gt;&#x27;s body, the code is good to go. The Eye Test I set up a couple of chapters earlier allowed me to catch that I was not &lt;em&gt;actually&lt;&#x2F;em&gt; assigning the labels to the blocks, a mistake I would not have caught otherwise until much later.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;ir-generation&quot;&gt;IR Generation&lt;&#x2F;h2&gt;
&lt;p&gt;All the new structures in this chapter can be implemented by the same IR instructions done in previous ones. Jumps and Labels. Who needs structured programming anyway?&lt;&#x2F;p&gt;
&lt;p&gt;Now, labels are needed for &lt;code&gt;break&lt;&#x2F;code&gt; and &lt;code&gt;continue&lt;&#x2F;code&gt; statements&#x27;s translation to jumps. To make sure the labels are consistent, they should be generated out of the loop labels constructed last section. So first I am adding another helper function to my &lt;code&gt;Boilerplate&lt;&#x2F;code&gt; struct, that creates new strings out of old ones.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; augment_label(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @This&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;    comptime&lt;&#x2F;span&gt;&lt;span&gt; prefix: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    label: [:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;[:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; cat&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; std.fmt.allocPrint(self.alloc, prefix&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; ++&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;_{s}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{label});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; self.alloc.free(cat);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; self.strings.get_or_put(self.alloc, cat);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; name.string;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;do while&lt;&#x2F;code&gt; loops are perhaps the easiest.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.do_while&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;w&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; st&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.augment_label(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;st&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, w.label.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; br&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.augment_label(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;br&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, w.label.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; cn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.augment_label(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;cn&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, w.label.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; st });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; stmt_emit_ir(bp, w.body);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cn });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(bp, w.cond);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bp.append(.{ .jump_nz&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(v, st) });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; br });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Everything else is, to be honest, just copied off the Book.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.@&amp;quot;while&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;w&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; br&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.augment_label(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;br&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, w.label.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; cn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.augment_label(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;cn&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, w.label.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cn });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(bp, w.cond);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .jump_z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(v, br) });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; stmt_emit_ir(bp, w.body);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .jump&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cn });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; br });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.@&amp;quot;for&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; st&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.augment_label(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;st&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, f.label.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; br&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.augment_label(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;br&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, f.label.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; cn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.augment_label(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;cn&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, f.label.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (f.init) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .decl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; decl_emit_ir(bp, d),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(bp, e),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .none&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; st });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (f.cond) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(bp, c);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .jump_z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(v, br) });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; stmt_emit_ir(bp, f.body);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cn });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (f.post) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(bp, p);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .jump&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; st });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; br });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.@&amp;quot;break&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;l&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .jump&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.augment_label(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;br&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, l.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.@&amp;quot;continue&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;l&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .jump&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.augment_label(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;cn&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, l.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;One fun detail here, the last two calls to &lt;code&gt;augment_label&lt;&#x2F;code&gt; will not allocate the string again. The string interner should just use the same string allocated previously. I&#x27;d perhaps test that to make sure, but eh.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;segmentation-faults-and-how-to-fix-them&quot;&gt;Segmentation Faults and How to Fix Them&lt;&#x2F;h2&gt;
&lt;p&gt;Running the eye test on Chapter 8&#x27;s valid code, I quickly hit a segmentation fault when printing the IR instructions for this code.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; acc &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 100&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (x) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;        int&lt;&#x2F;span&gt;&lt;span&gt; y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; y;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span&gt; (y) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            acc &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; acc &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; acc &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 100&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I am sure the smart ones of you figured out the problem back in chapter 3. When I figured out what caused it, I got amused it did not happen sooner.&lt;&#x2F;p&gt;
&lt;p&gt;The problem, my dear reader, is that my beloved string interner exceeded its capacity and reallocated its inner &lt;code&gt;ArrayList&lt;&#x2F;code&gt;, invalidating all the pointers I had around the codebase to its slices. Rust would&#x27;ve never!&lt;&#x2F;p&gt;
&lt;p&gt;Changing this is really trivial. All I need to do really is replace almost every occurrence of &lt;code&gt;[:0]const u8&lt;&#x2F;code&gt; in the code (which is usually the interned string), with &lt;code&gt;StringInterner.ID&lt;&#x2F;code&gt;. The actual problem, which is why I chose to put the string slices around in the first place, is that I cannot access the String Interner from the pretty printers. Allow me to demonstrate. This is &lt;code&gt;ir.FuncDef&lt;&#x2F;code&gt; in its entirety.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; FuncDef&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name: [:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    instrs: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(Instr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span&gt; deinit(self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt;@This&lt;&#x2F;span&gt;&lt;span&gt;(), alloc: std.mem.Allocator) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self.instrs.deinit(alloc);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span&gt; format(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @This&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;        comptime&lt;&#x2F;span&gt;&lt;span&gt; _: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        options: std.fmt.FormatOptions,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        writer:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; anytype&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; options.width&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; orelse&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; writer.writeByteNTimes(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;\t&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;, w);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;FUNCTION {s}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{self.name});&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;- printing name here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (self.instrs.items) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;instr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{:[1]}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                instr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                w&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I &lt;em&gt;could&lt;&#x2F;em&gt; store the numerical ID that is assigned to each string. But where else am I even using the strings, then? I am also using the same &lt;code&gt;format&lt;&#x2F;code&gt; mechanism to output the final assembly code.&lt;&#x2F;p&gt;
&lt;p&gt;The most straightforward, and annoying, solution is to add a pointer to the string interner for almost every single type in my program. The other solution is to have a global &lt;code&gt;StringInterner&lt;&#x2F;code&gt;, and I have avoided using globals in the program so far.&lt;&#x2F;p&gt;
&lt;p&gt;A completely insane solution would be to store the pointer to the &lt;code&gt;StringInterner&lt;&#x2F;code&gt; (&lt;em&gt;not&lt;&#x2F;em&gt; a pointer to its &lt;code&gt;bytes&lt;&#x2F;code&gt; array,) in the &lt;code&gt;Idx&lt;&#x2F;code&gt; object I&#x27;d use instead of &lt;code&gt;[:0]const u8&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;So first let&#x27;s do the easy part. &lt;code&gt;get_or_put&lt;&#x2F;code&gt; now returns a small struct with &lt;code&gt;Idx&lt;&#x2F;code&gt; and a string slice, and I can make it return only the &lt;code&gt;Idx&lt;&#x2F;code&gt;, and let the Zig compiler tell me where I need to fix the types.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; get_or_put(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    gpa: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    string: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) std.mem.Allocator.Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;Idx { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; &amp;lt;-- change here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; self.bytes.ensureUnusedCapacity(gpa, string.len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; self.map.ensureUnusedCapacityContext(gpa,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;, .{ .bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;self.bytes });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; adapter: std.hash_map.StringIndexAdapter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;self.bytes };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; gop&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; self.map.getOrPutAssumeCapacityAdapted(string, adapter);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (gop.found_existing)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; gop.key_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- and here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; new_id: Idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @intCast&lt;&#x2F;span&gt;&lt;span&gt;(self.bytes.items.len);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    self.bytes.appendSliceAssumeCapacity(string);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    self.bytes.appendAssumeCapacity(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    gop.key_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; new_id;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; new_id;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- and here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Simple enough. &lt;code&gt;zig build&lt;&#x2F;code&gt; tells me I am using this type in 4 places. All of them look like &lt;code&gt;name.string&lt;&#x2F;code&gt;. So I will just make them return &lt;code&gt;name&lt;&#x2F;code&gt; (which is really &lt;code&gt;Idx&lt;&#x2F;code&gt;), and fix the return types of their surrounding functions. One example is the one mentioned earlier, &lt;code&gt;augment_label&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; augment_label(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @This&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;    comptime&lt;&#x2F;span&gt;&lt;span&gt; prefix: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    label: utils.StringInterner.Idx,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- change here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;utils.StringInterner.Idx { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; &amp;lt;-- and here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; st_label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; self.strings.get_string(label).&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- addition&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; cat&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; std.fmt.allocPrint(self.alloc, prefix&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; ++&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;_{s}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{st_label});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; self.alloc.free(cat);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; self.strings.get_or_put(self.alloc, cat);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; name;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- and here.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So many errors!! Now we go over the types. A search for &lt;code&gt;[:0]const u8&lt;&#x2F;code&gt; is going to return a shitton of results, but persevere I must. The previously mentioned &lt;code&gt;ir.FuncDef&lt;&#x2F;code&gt; for example, becomes the following. Pretend the formatting problem is solved for now.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; FuncDef&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name: utils.StringInterner.Idx,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    instrs: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(Instr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span&gt; deinit(self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt;@This&lt;&#x2F;span&gt;&lt;span&gt;(), alloc: std.mem.Allocator) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self.instrs.deinit(alloc);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then the functions must ne changed. If I am not mistaken, all the functions dealing with the string interner actually live in &lt;code&gt;Boilerplate&lt;&#x2F;code&gt; structs. So time to check those. Here is the new &lt;code&gt;ir_gen.Boilerplate.make_temporary&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; make_temporary(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @This&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;    comptime&lt;&#x2F;span&gt;&lt;span&gt; prefix: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;utils.StringInterner.Idx { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; &amp;lt;- only here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return try&lt;&#x2F;span&gt;&lt;span&gt; self.strings.make_temporary(self.alloc, prefix);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There is a lot of leg work here that I will spare you the boring details of.&lt;&#x2F;p&gt;
&lt;p&gt;A few details that came up showing how deep the assumption is within the codebase. One of them is the different &lt;code&gt;StringHashMap&lt;&#x2F;code&gt;s around the code. They do not manage the strings, I do. And now they are all invalidated! What if I just solve this with a much bigger starting capacity for the string interner?[^branch]&lt;&#x2F;p&gt;
&lt;p&gt;The other big one is that in semantic analysis, I replaced the pointers to the old names (which are allocated from the source) with pointers within the string interner. It means, if I were to keep to the same structure of files, I need to replace the &lt;code&gt;name&lt;&#x2F;code&gt; fields in all AST types dealing with variables with an &lt;code&gt;Identifier&lt;&#x2F;code&gt; type, defined thus.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Identifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    idx: utils.StringInterner.Idx,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And now &lt;code&gt;ast.Decl&lt;&#x2F;code&gt; is like this.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Decl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name: Identifier,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    init:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; ?*&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After changing all the types, and fixing all the compilation errors, I wanted to make sure this thing works before trying to solve the formatting problem. So I took the C file mentioned above and sent it through all the stages up to codegen. First goes parsing:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION { 109, 97, 105, 110 }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		int ast.Identifier{ .name = { 97, 99, 99 } } &amp;lt;- 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		int ast.Identifier{ .name = { 120 } } &amp;lt;- 100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		WHILE ast.Identifier{ .name = { 120 } }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			int ast.Identifier{ .name = { 121 } } &amp;lt;- 10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			(ast.Identifier{ .name = { 120 } } &amp;lt;- (- ast.Identifier{ .name = { 120 } } ast.Identifier{ .name = { 121 } }));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			WHILE ast.Identifier{ .name = { 121 } }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;				(ast.Identifier{ .name = { 97, 99, 99 } } &amp;lt;- (+ ast.Identifier{ .name = { 97, 99, 99 } } 1));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;				(ast.Identifier{ .name = { 121 } } &amp;lt;- (- ast.Identifier{ .name = { 121 } } 1));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		RETURN (&amp;amp;&amp;amp; (== ast.Identifier{ .name = { 97, 99, 99 } } 100) (== ast.Identifier{ .name = { 120 } } 0))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Second is semantic analysis. Note how most of the numbers (outside of &lt;code&gt;ast.identifier.etc&lt;&#x2F;code&gt;) are actually variable names, or rather indices to variable names.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION { 109, 97, 105, 110 }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		int ast.Identifier{ .idx = 0 } &amp;lt;- 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		int ast.Identifier{ .idx = 6 } &amp;lt;- 100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		10: WHILE ast.Identifier{ .idx = 6 }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			int ast.Identifier{ .idx = 18 } &amp;lt;- 10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			(ast.Identifier{ .idx = 6 } &amp;lt;- (- ast.Identifier{ .idx = 6 } ast.Identifier{ .idx = 18 }));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			22: WHILE ast.Identifier{ .idx = 18 }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;				(ast.Identifier{ .idx = 0 } &amp;lt;- (+ ast.Identifier{ .idx = 0 } 1));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;				(ast.Identifier{ .idx = 18 } &amp;lt;- (- ast.Identifier{ .idx = 18 } 1));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		RETURN (&amp;amp;&amp;amp; (== ast.Identifier{ .idx = 0 } 100) (== ast.Identifier{ .idx = 6 } 0))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Following it up is the IR. &lt;code&gt;0 &amp;lt;- 0&lt;&#x2F;code&gt; is a funny one. Assigning a constant &lt;code&gt;0&lt;&#x2F;code&gt; to a variable whose name is at index &lt;code&gt;0&lt;&#x2F;code&gt;. &lt;code&gt;main&lt;&#x2F;code&gt; amusingly, is actually at index 30.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION 30&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		0 &amp;lt;- 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		6 &amp;lt;- 100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		=&amp;gt; 46&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jz  6 =&amp;gt; 35&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		18 &amp;lt;- 10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		57 &amp;lt;- 6 - 18&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		6 &amp;lt;- 57&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		=&amp;gt; 74&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jz  18 =&amp;gt; 63&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		85 &amp;lt;- 0 + 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		0 &amp;lt;- 85&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		91 &amp;lt;- 18 - 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		18 &amp;lt;- 91&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jump =&amp;gt; 74&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		=&amp;gt; 63&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jump =&amp;gt; 46&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		=&amp;gt; 35&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		130 &amp;lt;- 0 == 100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jz  130 =&amp;gt; 97&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		137 &amp;lt;- 6 == 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jz  137 =&amp;gt; 97&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		119 &amp;lt;- 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jump =&amp;gt; 109&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		=&amp;gt; 97&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		119 &amp;lt;- 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		=&amp;gt; 109&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ret 119&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ret 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And finally, codegen.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION 30&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		allocate	36&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 0 -&amp;gt; stack -4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 100 -&amp;gt; stack -8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		=&amp;gt; .L46&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		cmp	imm 0 -&amp;gt; stack -8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jmpe	.L35&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 10 -&amp;gt; stack -12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -8 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -12 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		sub	R10 -&amp;gt; stack -16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -16 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		=&amp;gt; .L74&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		cmp	imm 0 -&amp;gt; stack -12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jmpe	.L63&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -4 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		add	imm 1 -&amp;gt; stack -20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -20 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -12 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -24&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		sub	imm 1 -&amp;gt; stack -24&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -24 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jmp	.L74&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		=&amp;gt; .L63&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jmp	.L46&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		=&amp;gt; .L35&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		cmp	imm 100 -&amp;gt; stack -4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 0 -&amp;gt; stack -28&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		sete	stack -28&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		cmp	imm 0 -&amp;gt; stack -28&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jmpe	.L97&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		cmp	imm 0 -&amp;gt; stack -8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 0 -&amp;gt; stack -32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		sete	stack -32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		cmp	imm 0 -&amp;gt; stack -32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jmpe	.L97&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 1 -&amp;gt; stack -36&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jmp	.L109&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		=&amp;gt; .L97&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 0 -&amp;gt; stack -36&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		=&amp;gt; .L109&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -36 -&amp;gt; AX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 0 -&amp;gt; AX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It occurs to me looking at this last one is that only strings that survive to the final stage are labels and function names. (Only &lt;code&gt;main&lt;&#x2F;code&gt; for now). Even the labels can actually just be a &lt;code&gt;.L35&lt;&#x2F;code&gt;, or whatever number, which is a perfectly valid label identifier. So, now to get a working compiler all I need to actually fix in this stage is printing the function&#x27;s name. To test that theory, I added a &lt;code&gt;*utils.StringInterner&lt;&#x2F;code&gt; field to both &lt;code&gt;assembly.Prgm&lt;&#x2F;code&gt; and &lt;code&gt;assembly.FuncDef&lt;&#x2F;code&gt; to get the name of the function out. It is a fairly small change in both &lt;code&gt;assembly.zig&lt;&#x2F;code&gt; and &lt;code&gt;asm_gen.zig&lt;&#x2F;code&gt;. You get this final assembly.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.globl _main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;_main:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	pushq   %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	movq&lt;&#x2F;span&gt;&lt;span&gt;    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;, %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	subq    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$36&lt;&#x2F;span&gt;&lt;span&gt;, %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$0&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$100&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;L46:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	cmpl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$0&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	je&lt;&#x2F;span&gt;&lt;span&gt;      .L35&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$10&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;), %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r10d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r10d&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;), %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r10d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	subl    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r10d&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;), %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r10d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r10d&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;L74:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	cmpl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$0&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	je&lt;&#x2F;span&gt;&lt;span&gt;      .L63&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;), %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r10d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r10d&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	addl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$1&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;), %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r10d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r10d&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;), %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r10d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r10d&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;24&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	subl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$1&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;24&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;24&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;), %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r10d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r10d&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	jmp&lt;&#x2F;span&gt;&lt;span&gt;    .L74&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;L63:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	jmp&lt;&#x2F;span&gt;&lt;span&gt;    .L46&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;L35:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	cmpl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$100&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$0&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;28&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	sete&lt;&#x2F;span&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;28&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	cmpl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$0&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;28&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	je&lt;&#x2F;span&gt;&lt;span&gt;      .L97&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	cmpl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$0&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$0&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	sete&lt;&#x2F;span&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	cmpl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$0&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	je&lt;&#x2F;span&gt;&lt;span&gt;      .L97&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$1&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;36&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	jmp&lt;&#x2F;span&gt;&lt;span&gt;    .L109&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;L97:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$0&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;36&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;L109:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;36&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;), %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;eax&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	movq&lt;&#x2F;span&gt;&lt;span&gt;    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rbp&lt;&#x2F;span&gt;&lt;span&gt;, %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	popq    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$0&lt;&#x2F;span&gt;&lt;span&gt;, %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;eax&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	movq&lt;&#x2F;span&gt;&lt;span&gt;    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rbp&lt;&#x2F;span&gt;&lt;span&gt;, %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	popq    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I ran the program at its current stage through the test suite, and it passed all tests with flying colors. No segmentation faults!&lt;&#x2F;p&gt;
&lt;p&gt;Before actually tackling the printing problem, it would perhaps be better to change the &lt;code&gt;utils.StringInterner.Idx&lt;&#x2F;code&gt; type to be a wrapper around &lt;code&gt;u32&lt;&#x2F;code&gt; rather than a straight up &lt;code&gt;u32&lt;&#x2F;code&gt;. It makes types a little bit safer (no adding two indices together). The change in the declaration is as simple as the following.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-odin-1&quot;&gt;&lt;a href=&quot;#fn-odin&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span&gt; format(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @This&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;        comptime&lt;&#x2F;span&gt;&lt;span&gt; _: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _: std.fmt.FormatOptions,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        writer:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; anytype&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;[{d}]&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt;@intFromEnum&lt;&#x2F;span&gt;&lt;span&gt;(self)});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And inside &lt;code&gt;StringInterner&lt;&#x2F;code&gt;&#x27;s functions, the two builtin &lt;code&gt;@intFromEnum&lt;&#x2F;code&gt; and, you will never guess, &lt;code&gt;@enumFromInt&lt;&#x2F;code&gt;. Putting these in a few strategic places hides the &lt;code&gt;u32&lt;&#x2F;code&gt; implementation, (including the formatting as &lt;code&gt;.Lutils.StringInterner.Idx(28)&lt;&#x2F;code&gt; is not actually a valid label identifier), and the tests keep on passing.&lt;&#x2F;p&gt;
&lt;p&gt;Looking at &lt;code&gt;jj diff --stat&lt;&#x2F;code&gt;, all the changes are summarized in the following. Not bad.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c_files&#x2F;nested_loop        |  2 ++&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;src&#x2F;asm_gen.zig            |  5 ++++-&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;src&#x2F;asm_passes&#x2F;pseudos.zig |  5 ++++-&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;src&#x2F;assembly.zig           | 30 ++++++++++++++++--------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;src&#x2F;ast.zig                | 34 ++++++++++++++++++++--------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;src&#x2F;ir.zig                 | 24 ++++++++++++------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;src&#x2F;ir_gen.zig             | 17 +++++++++--------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;src&#x2F;main.zig               |  2 +-&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;src&#x2F;parser.zig             |  8 ++++----&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;src&#x2F;sema.zig               | 28 ++++++++++++++++------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;src&#x2F;utils.zig              | 44 ++++++++++++++++++++++----------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;11 files changed, 110 insertions(+), 89 deletions(-)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;fixing-the-formatting-problem&quot;&gt;Fixing the Formatting Problem&lt;&#x2F;h2&gt;
&lt;p&gt;As mentioned before, there are four options, on different levels of unhingedness.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Add a &lt;code&gt;*utils.StringInterner&lt;&#x2F;code&gt; field to every type that may contain a string (as done already in this example for &lt;code&gt;assembly.FuncDef&lt;&#x2F;code&gt;) and every function that generates them (a lot of them do already via the &lt;code&gt;Boilerplate&lt;&#x2F;code&gt; structs). Then when formatting, one just refers to the inner field.&lt;&#x2F;li&gt;
&lt;li&gt;Add a global &lt;code&gt;*utils.StringInterner&lt;&#x2F;code&gt;, and remove it from the &lt;code&gt;Boilerplate&lt;&#x2F;code&gt; structs. I do not like globals too much, but this is the least disruptive to the code.&lt;&#x2F;li&gt;
&lt;li&gt;Change the &lt;code&gt;Idx&lt;&#x2F;code&gt; type to hold its &lt;em&gt;own&lt;&#x2F;em&gt; pointer to the string interner. &lt;del&gt;I have no idea how this would even begin to look like and it is probably insane.&lt;&#x2F;del&gt; It works perfectly and it is definitely insane.&lt;&#x2F;li&gt;
&lt;li&gt;Just .. increase the starting buffer for interner to a large enough size that it never needs to reallocate. This is a &lt;em&gt;terrible&lt;&#x2F;em&gt; idea for a real program but this is not actually a real program.&lt;&#x2F;li&gt;
&lt;li&gt;Forgo pretty printing the middle stages entirely. The current status runs and passes fine as is.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;As insane as it sounds, I went with 3. The resulting type is no larger than a slice, which I already had. It keeps the relevant data where it is (in the &lt;code&gt;Idx&lt;&#x2F;code&gt;). I still think it is a totally insane idea. But the tests pass, the printer prints, things work.&lt;&#x2F;p&gt;
&lt;p&gt;And this wraps chapter 8.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Loops are interesting&lt;&#x2F;li&gt;
&lt;li&gt;Do not add a &lt;code&gt;for&lt;&#x2F;code&gt; loop to my language.&lt;&#x2F;li&gt;
&lt;li&gt;To love Rust more. Rust would &lt;em&gt;never&lt;&#x2F;em&gt; have let me segfault!&lt;&#x2F;li&gt;
&lt;li&gt;Er .. refactoring in Zig, I guess? The last section as a whole is a Lessons Learned, to be honest.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;hr &#x2F;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-odin&quot;&gt;
&lt;p&gt;Odin&#x27;s &lt;code&gt;distinct&lt;&#x2F;code&gt; types are so much better for this. &lt;a href=&quot;#fr-odin-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Chapter 7: Blocks</title>
        <published>2025-05-25T00:00:00+00:00</published>
        <updated>2025-05-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/paella/c7/"/>
        <id>https://ar-ms.me/paella/c7/</id>
        
        <content type="html" xml:base="https://ar-ms.me/paella/c7/">&lt;p&gt;Chapter 6 of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;norasandler.com&#x2F;2022&#x2F;03&#x2F;29&#x2F;Write-a-C-Compiler-the-Book.html&quot;&gt;Writing a C Compiler&lt;&#x2F;a&gt; was a short one. So will Chapter 7. Do not even bother to buckle up.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;syntax-tree-and-parsing&quot;&gt;Syntax Tree and Parsing&lt;&#x2F;h2&gt;
&lt;p&gt;See? Not even new tokens for lexer.&lt;&#x2F;p&gt;
&lt;p&gt;This chapter is all about implementing compound statements. To abstract the similarities between a function body and compound statements, a new &lt;code&gt;Block&lt;&#x2F;code&gt; AST node shall be created. Along with a tiny change in &lt;code&gt;FuncDef&lt;&#x2F;code&gt;, you get this beauty.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; FuncDef&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    body: Block,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    body: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SegmentedList&lt;&#x2F;span&gt;&lt;span&gt;(BlockItem,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And adding a new statement type in &lt;code&gt;Stmt&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Stmt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @&amp;quot;return&amp;quot;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    expr:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @&amp;quot;if&amp;quot;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; { cond:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr, then:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Stmt, @&amp;quot;else&amp;quot;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; ?*&lt;&#x2F;span&gt;&lt;span&gt;Stmt },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    compound: Block,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- this one&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt;    null&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; void&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I &lt;em&gt;think&lt;&#x2F;em&gt; it does not need a pointer. I will wait to see if the Zig compiler yells at me.&lt;&#x2F;p&gt;
&lt;p&gt;Updating the parser requires a new function: &lt;code&gt;parse_block&lt;&#x2F;code&gt;. It is simple enough and the implementation is copied over from &lt;code&gt;parse_func_def&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_block(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    arena: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ast.Block {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.l_brace, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; body: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SegmentedList&lt;&#x2F;span&gt;&lt;span&gt;(ast.BlockItem,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .{};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (tokens.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;next_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (next_token.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .r_brace) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tokens.put_back(next_token);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_block_item(arena, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; body.append(arena, item);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.NotEnoughJunk;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .body&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; body };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And &lt;code&gt;parse_func_def&lt;&#x2F;code&gt; is adjusted accordingly:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_func_def(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    arena: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ast.FuncDef {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.type_int, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expect(.identifier, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.l_paren, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.keyword_void, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.r_paren, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_block(arena, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; name, .block&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; block };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And that is it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pretty-printing-tricks&quot;&gt;Pretty Printing Tricks&lt;&#x2F;h2&gt;
&lt;p&gt;I encountered an interesting problem in the AST pretty printer. Because I am using an indentation based scheme, rather than braces, it makes it slightly difficult to know where blocks begin and end if I just, increase the indentation. So, for a regular block, I add the keyword &lt;code&gt;DO&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; b;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt;= -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;        int&lt;&#x2F;span&gt;&lt;span&gt; a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;== -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		int a &amp;lt;- 2;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		int b;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		DO&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			a &amp;lt;- (- 4);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			int a &amp;lt;- 7;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			b &amp;lt;- (+ a 1);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		RETURN (&amp;amp;&amp;amp; (== b 8) (== a (- 4)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But when the block is in the &lt;code&gt;if&lt;&#x2F;code&gt; statement, this would look something like this, which is .. eh, unseemly.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;IF a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	DO&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		int b &amp;lt;- 2;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		RETURN b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So instead I get rid of &lt;code&gt;DO&lt;&#x2F;code&gt; and just have indent immediately after &lt;code&gt;IF&lt;&#x2F;code&gt;. The thing is, the logic for compound statement printing does not know, normally, whether it is preceded by &lt;code&gt;IF&lt;&#x2F;code&gt; (and later &lt;code&gt;FOR&lt;&#x2F;code&gt; and &lt;code&gt;WHILE&lt;&#x2F;code&gt;), or if it is standing by its own. Doing the custom formatting when printing &lt;code&gt;IF&lt;&#x2F;code&gt; would lead to a lot of duplicated code for every new control flow statement. So time to abuse another feature of the formatter!&lt;&#x2F;p&gt;
&lt;p&gt;One of the options in &lt;code&gt;srd.fmt.FormatOptions&lt;&#x2F;code&gt; is &lt;code&gt;alignment&lt;&#x2F;code&gt;, which is normally used to align the printed items right, left, or center, within given padding. In the &lt;code&gt;fmt&lt;&#x2F;code&gt; string, &lt;code&gt;&amp;lt;&lt;&#x2F;code&gt; indicates left, &lt;code&gt;^&lt;&#x2F;code&gt; indicates center, and &lt;code&gt;&amp;gt;&lt;&#x2F;code&gt; indicates right, which is the default value.&lt;&#x2F;p&gt;
&lt;p&gt;In other words, when printing the statement following &lt;code&gt;IF&lt;&#x2F;code&gt;, all I need to do there is this, which sets the &lt;code&gt;alignment&lt;&#x2F;code&gt; option in the called function to &lt;code&gt;.center&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{:^[1]}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{ cs.then, w&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;                  ^ right here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And now I can do the check right within &lt;code&gt;.compound&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.compound&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.body.constIterator(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; cw:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt; usize =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; undefined&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (options.alignment&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span&gt; .center) { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; &amp;lt;-- here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; writer.writeAll(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;DO&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cw&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{item});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cw&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; w;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{:[1]}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            item,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            cw,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The other issue, which you might have noticed, is that the new line characters which separate the internal block items are printed before each statement. The reason for that is for the block not to end in a newline character, as the new line is usually taken care of by the &lt;em&gt;parent&lt;&#x2F;em&gt; block. This simply avoids an additional blank line after every block.&lt;&#x2F;p&gt;
&lt;p&gt;This prints the AST nicely, even for ridiculous C code.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; ten &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; twenty &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {{}}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; ten &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; twenty;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		int ten &amp;lt;- 10;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		DO&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		int twenty &amp;lt;- (* 10 2);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		DO&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			DO&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		RETURN (+ ten twenty)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I could just as well omit the empty blocks right here and then.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-python-1&quot;&gt;&lt;a href=&quot;#fn-python&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; Maybe I will do that if I ever write a real compiler.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;semantic-analysis&quot;&gt;Semantic Analysis&lt;&#x2F;h2&gt;
&lt;p&gt;I wish this were as easy as filling up the blanks, but that is actually where the meat of this chapter is. Because C allows shadowing in inner scopes. The following is perfectly valid C code.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;         &#x2F;&#x2F; &amp;lt;-- x0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;        int&lt;&#x2F;span&gt;&lt;span&gt; x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;     &#x2F;&#x2F; &amp;lt;-- x1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;   &#x2F;&#x2F; &amp;lt;-- x1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;     &#x2F;&#x2F; &amp;lt;-- x1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;            int&lt;&#x2F;span&gt;&lt;span&gt; x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- x2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; x  ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; &amp;lt;-- x1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; x;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;          &#x2F;&#x2F; &amp;lt;-- x0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;What this means in practice is that each new scope (read: new block), requires its own &lt;code&gt;variable_map&lt;&#x2F;code&gt;. Previously, the &lt;code&gt;variable_map&lt;&#x2F;code&gt; was defined at program scope in &lt;code&gt;resolve_prgm&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; resolve_prgm(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    gpa: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    strings:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;utils.StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    prgm:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Prgm,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; variable_map: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;StringHashMapUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;([:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .empty;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; variable_map.deinit(gpa);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; bp: Boilerplate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .gpa&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; gpa,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .strings&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; strings,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .variable_map&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;variable_map,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; resolve_func_def(bp, prgm.func_def);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;variable_map&lt;&#x2F;code&gt; is discarded by the end of this function because, by the time the function is done, all the user-supplied variable names have been given unique names. The scopes are identified and done at this point.&lt;&#x2F;p&gt;
&lt;p&gt;It does not serve to create a new &lt;em&gt;empty&lt;&#x2F;em&gt; &lt;code&gt;variable_map&lt;&#x2F;code&gt; for each new block, because blocks can use variables from parent blocks.[^global] So for every new block, or compound statement, a copy of the variable map is passed instead of the original, and existing keys are replaced by the bindings in the inner scope. However, to avoid double declarations, a marker is needed to note whether this variable belongs to the current scope (so it cannot be declared again), or a parent one, (so it can).&lt;&#x2F;p&gt;
&lt;p&gt;This is the part where double declarations are checked:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; resolve_decl(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bp: Boilerplate,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    decl:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Decl,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (bp.variable_map.contains(decl.name))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.DuplicateVariableDecl;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; snip --&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The data for whether this is shadowing a parent variable (legal) or repeating a local declaration (illegal) is not tracked yet. The simplest way to use a &lt;code&gt;Entry&lt;&#x2F;code&gt; type that has both the new name, and a little boolean toggle whether it is local. The data oriented way is perhaps to create a new map for each new scope, but this seems complicated when the scopes get too deep and you need to keep a stack of maps, etc. I will stick with a boolean, or at least an enum.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Entry&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    new_name: [:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    scope:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; { local, parent } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .local,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I really love anonymous types. Then change the variable map to a &lt;code&gt;std.StringHashMapUnmanaged(Entry)&lt;&#x2F;code&gt;. This currently needs a couple of call sites to update, but all very straightforward. The default value of &lt;code&gt;.local&lt;&#x2F;code&gt; makes initialization simpler, just a &lt;code&gt;.{ .name = unique_name }&lt;&#x2F;code&gt; when inserting into the map.&lt;&#x2F;p&gt;
&lt;p&gt;Now a small change to the duplicate declaration checking can be done. I need to check if it exists &lt;em&gt;and&lt;&#x2F;em&gt; if it is a &lt;code&gt;.local&lt;&#x2F;code&gt; scope. A cute zig syntactic trick makes this nicely terse. Who needs &lt;code&gt;if let&lt;&#x2F;code&gt; chains.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (bp.variable_map.get(decl.name)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;entry&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (entry.scope&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .local)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.DuplicateVariableDecl;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;All that is left is creating a new, duplicate, &lt;code&gt;variable_map&lt;&#x2F;code&gt; when resolving a compound statement. Before I do that, I will do some refactorings moving the old &lt;code&gt;variable_map&lt;&#x2F;code&gt; into &lt;code&gt;FuncDef&lt;&#x2F;code&gt; scope instead, and moving the old &lt;code&gt;resolve_func_def&lt;&#x2F;code&gt; logic into a new &lt;code&gt;resolve_block&lt;&#x2F;code&gt; that can be reused. This also simplifies later chapters when each function has its own scope as well.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; resolve_prgm(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    gpa: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    strings:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;utils.StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    prgm:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Prgm,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; resolve_func_def(gpa, strings, prgm.func_def);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; resolve_func_def(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    gpa: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    strings:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;utils.StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    func_def:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.FuncDef,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; variable_map: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;StringHashMapUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(Entry) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .empty;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; variable_map.deinit(gpa);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; bp: Boilerplate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .gpa&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; gpa,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .strings&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; strings,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .variable_map&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;variable_map,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; resolve_block(bp,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;func_def.block);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; resolve_block(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bp: Boilerplate,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    block:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Block,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; block.body.iterator(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (item.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .S&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_stmt(bp, s),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .D&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_decl(bp, d),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now back to compound statements. First the &lt;code&gt;variable_map&lt;&#x2F;code&gt; is copied into a new one, with all the &lt;code&gt;.local&lt;&#x2F;code&gt;s changes into &lt;code&gt;.parent&lt;&#x2F;code&gt;s. Zig helpfully has a &lt;code&gt;clone&lt;&#x2F;code&gt; method. then iterate over all the values and update the &lt;code&gt;scope&lt;&#x2F;code&gt; field.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; inside resolve_stmt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.compound&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; variable_map&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.variable_map.clone(bp.gpa);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; variable_map.deinit(bp.gpa);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; variable_map.valueIterator();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        value.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value.name, .scope&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .parent };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; inner_bp: Boilerplate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .gpa&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bp.gpa,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .strings&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bp.strings,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .variable_map&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;variable_map,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; resolve_block(inner_bp, b);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This compiles fine. The eye test passes on all C files in chapter 7&#x27;s tests in the test suite. Time to actually run the test suite, and thankfully all tests pass.&lt;&#x2F;p&gt;
&lt;p&gt;Now what? Almost nothing. No changes to IR (except handling the new statement) or any following stage necessary. Running the full tests, up to compilation, works fine. Time to move on to chapter 8.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;&#x2F;h2&gt;
&lt;p&gt;The most fun I had here was experimenting with the AST pretty printer. Cracking the nut of the duplicate new line problem.&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-python&quot;&gt;
&lt;p&gt;Or pull a Python and output &lt;code&gt;...&lt;&#x2F;code&gt; or &lt;code&gt;pass&lt;&#x2F;code&gt;. &lt;a href=&quot;#fr-python-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Chapter 6: Conditions</title>
        <published>2025-05-24T00:00:00+00:00</published>
        <updated>2025-05-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/paella/c6/"/>
        <id>https://ar-ms.me/paella/c6/</id>
        
        <content type="html" xml:base="https://ar-ms.me/paella/c6/">&lt;p&gt;This is chapter 6 of implementing &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;norasandler.com&#x2F;2022&#x2F;03&#x2F;29&#x2F;Write-a-C-Compiler-the-Book.html&quot;&gt;Writing a C Compiler&lt;&#x2F;a&gt; in Zig. So, without further ado, time to get on with &lt;code&gt;if&lt;&#x2F;code&gt; statements and conditional expressions.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lexer&quot;&gt;Lexer&lt;&#x2F;h2&gt;
&lt;p&gt;New keywords! &lt;code&gt;if&lt;&#x2F;code&gt; and &lt;code&gt;else&lt;&#x2F;code&gt;, and two new tokens &lt;code&gt;?&lt;&#x2F;code&gt; and &lt;code&gt;:&lt;&#x2F;code&gt;. Apparently the word &lt;code&gt;query&lt;&#x2F;code&gt; is an acceptable single word name for a question mark so I am going with that in the lexer.&lt;&#x2F;p&gt;
&lt;p&gt;The new keywords are simple, enough, but it requires updating the keyword map.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; keywords&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;StaticStringMap&lt;&#x2F;span&gt;&lt;span&gt;(Tag).initComptime(.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;int&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .type_int },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;return&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .keyword_return },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;void&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .keyword_void },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; new lines :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;if&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .keyword_if },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;else&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .keyword_else },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The two new tokens are trivial to add and require no new states in the lexer&#x27;s state machine. So onto AST and parsing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ast&quot;&gt;AST&lt;&#x2F;h2&gt;
&lt;p&gt;One new statement and one new expression today. Compound statements survive another day without being implemented.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Stmt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; snip --&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @&amp;quot;if&amp;quot;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; { cond:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr, then:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Stmt, @&amp;quot;else&amp;quot;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; ?*&lt;&#x2F;span&gt;&lt;span&gt;Stmt },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; snip --&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ternary:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; { &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And that is pretty much it for the AST. No revision of previous major design decisions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;parser&quot;&gt;Parser&lt;&#x2F;h2&gt;
&lt;p&gt;So how do you parse an expression like &lt;code&gt;c ? a : b&lt;&#x2F;code&gt;?. The rule for it is that it is right associative (not unlike the assignment operator &lt;code&gt;=&lt;&#x2F;code&gt;), &lt;em&gt;but&lt;&#x2F;em&gt; the expression in the middle is treated as it is part of the expression itself or between two parenthesis. In other words, think of &lt;code&gt;? a :&lt;&#x2F;code&gt; as an binary operator between &lt;code&gt;c&lt;&#x2F;code&gt; and &lt;code&gt;b&lt;&#x2F;code&gt; all by itself, only for parsing purposes. So first update the &lt;code&gt;binop_precedence&lt;&#x2F;code&gt; function&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; binop_precedence(self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @This&lt;&#x2F;span&gt;&lt;span&gt;()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; { &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt; } {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return switch&lt;&#x2F;span&gt;&lt;span&gt; (self) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .query&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; the rest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then update &lt;code&gt;parse_expr&lt;&#x2F;code&gt; to deal with it. This is slightly trickier than usual. The middle expression should be parsed before the right hand side is. Therefore this silly dance, before parsing &lt;code&gt;rhs&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; then_ptr:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; ?*&lt;&#x2F;span&gt;&lt;span&gt;ast.Expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (current.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .query) t: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; then&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.colon, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    break&lt;&#x2F;span&gt;&lt;span&gt; :t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(ast.Expr, arena, then);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;} &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then, in the big switch board, this tiny line is added.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.greater_equals&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .binop_ge&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bin_op },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.query&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .ternary&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ lhs_ptr, then_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;, rhs_ptr } },&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And voila. Ternary expressions are parsed now. This creates a very tiny bit of waste creating the boiler-plate reducing &lt;code&gt;bin_op&lt;&#x2F;code&gt; (which is shared between all the other expressions). But all is fair in the name of easier to write code.&lt;&#x2F;p&gt;
&lt;p&gt;For parsing the &lt;code&gt;if&lt;&#x2F;code&gt; statement, I hit upon a previous design decision. In adding declarations last chapter, I decided to forgo a separate &lt;code&gt;parse_stmt&lt;&#x2F;code&gt; in exchange for a simpler, at the time, single &lt;code&gt;parse_block_item&lt;&#x2F;code&gt;, and discriminating then between declarations and statements. Now, since the &lt;code&gt;then&lt;&#x2F;code&gt; argument of the &lt;code&gt;if&lt;&#x2F;code&gt; statement can only be a statement and not a declaration, this requires a divorce, and a separate &lt;code&gt;parse_stmt&lt;&#x2F;code&gt;. Declarations are not ready to leave the house yet and therefore will remain in &lt;code&gt;parse_block_item&lt;&#x2F;code&gt;. This is the trimmed &lt;code&gt;parse_block_item&lt;&#x2F;code&gt;, followed by &lt;code&gt;parse_stmt&lt;&#x2F;code&gt; building its own house.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_block_item(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    arena: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ast.BlockItem {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; current&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.NotEnoughJunk;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (current.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .type_int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expect(.identifier, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; new_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.NotEnoughJunk;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; init:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; ?*&lt;&#x2F;span&gt;&lt;span&gt;ast.Expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (new_token.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .equals&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ret: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;                    const&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;                    const&lt;&#x2F;span&gt;&lt;span&gt; expr_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(ast.Expr, arena, expr);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.semicolon, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    break&lt;&#x2F;span&gt;&lt;span&gt; :ret expr_ptr;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .semicolon&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; .decl(.{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; name, .init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; init });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tokens.put_back(current);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; stmt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_stmt(arena, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; .stmt(stmt);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_stmt(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    arena: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ast.Stmt {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; current&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.NotEnoughJunk;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (current.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .semicolon&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt;null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .keyword_return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(ast.Expr, arena, expr);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; expect(.semicolon, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; .{ .@&amp;quot;return&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; expr_ptr };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; if statement goes here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tokens.put_back(current);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(ast.Expr, arena, expr);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; expect(.semicolon, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; .{ .expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; expr_ptr };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;if&lt;&#x2F;code&gt; statement parsing is slightly more involved than usual. The condition is always an expression that is parenthesized, and the &lt;code&gt;then&lt;&#x2F;code&gt; statement always exists. The &lt;code&gt;else&lt;&#x2F;code&gt; statement&#x27;s existence depends on the existence of the keyword &lt;code&gt;else&lt;&#x2F;code&gt;, so I have to &lt;em&gt;peek&lt;&#x2F;em&gt;. But because of the way I implemented peeking, by &quot;putting back&quot; the consumed token, it makes for some weird looking code, making more than usual use of block expressions.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.keyword_if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.l_paren, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; cond_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(ast.Expr, arena, cond);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.r_paren, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; then&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_stmt(arena, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; then_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(ast.Stmt, arena, then);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; peek&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.NotEnoughJunk;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; weird looking code starts here.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; else_ptr:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; ?*&lt;&#x2F;span&gt;&lt;span&gt;ast.Stmt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (peek.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .keyword_else) s: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_stmt(arena, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        break&lt;&#x2F;span&gt;&lt;span&gt; :s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(ast.Stmt, arena, e);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt; n: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tokens.put_back(peek);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        break&lt;&#x2F;span&gt;&lt;span&gt; :n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .@&amp;quot;if&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cond_ptr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .then&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; then_ptr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .@&amp;quot;else&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; else_ptr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, before eating the pudding, the semantic analysis phase requires some tiny updates. There are no changes other than handling the new statements and expressions, and adding thoise is 11 lines total.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; resolve_stmt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.@&amp;quot;if&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(bp, i.cond);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; resolve_stmt(bp, i.then);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (i.@&amp;quot;else&amp;quot;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; resolve_stmt(bp, e);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; resolve_expr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.ternary&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(bp, t.@&amp;quot;0&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(bp, t.@&amp;quot;1&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(bp, t.@&amp;quot;2&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And that is it, really. Back to proving the pudding. Testing it on this lovely and non-confusing C file:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; a;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Gives me this result, which judging by the formatting is probably parsed correctly.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		int a &amp;lt;- 0;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		IF (! a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			IF (&#x2F; 3 4)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;				a &amp;lt;- 3;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			ELSE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;				a &amp;lt;- (&#x2F; 8 2);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		RETURN a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;All parsing and semantic analysis are succeeding and failing where they should. That&#x27;s good news.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;the-eye-test&quot;&gt;The Eye Test&lt;&#x2F;h2&gt;
&lt;p&gt;Since I implemented all this nice pretty parsing, I would like to inspect on all the valid test files of the chapter. At least, visually confirm that there is nothing out of the ordinary. Same as I have been doing for C files in each chapter, but instead of copying a couple of interesting ones and running my app on them, I can do a batch comparison between each C file and the visual result of parsing it or validation or whatever.&lt;&#x2F;p&gt;
&lt;p&gt;The first thought was to do it with a shell script. But shell is voodoo to me.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-ai-1&quot;&gt;&lt;a href=&quot;#fn-ai&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; &lt;code&gt;build.zig&lt;&#x2F;code&gt; is right there, so maybe I can use it to that effect.&lt;&#x2F;p&gt;
&lt;p&gt;The new command would need two arguments: the stage, which is then passed directly to the executable, and the target folder. I cannot just pass the target chapter because not all chapters have the same structure.&lt;&#x2F;p&gt;
&lt;p&gt;What followed was one of the most aggravating and annoying parts of this series.&lt;&#x2F;p&gt;
&lt;p&gt;The first hurdle was navigating Zig&#x27;s standard library&#x27;s file system API. The docs are not very clear and the different APIs are organized in weird places, and how does any of that tie back in the build system?&lt;&#x2F;p&gt;
&lt;p&gt;There is a &lt;code&gt;walk&lt;&#x2F;code&gt; function.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-recursive-1&quot;&gt;&lt;a href=&quot;#fn-recursive&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; Excellent, but it needs a &lt;code&gt;std.fs.Dir&lt;&#x2F;code&gt; object. All I have is a &lt;code&gt;std.Build.LazyPath&lt;&#x2F;code&gt;. How do I make one into the other?&lt;&#x2F;p&gt;
&lt;p&gt;Turns out &lt;code&gt;LazyPath&lt;&#x2F;code&gt; has a &lt;code&gt;getPath3&lt;&#x2F;code&gt; method (&lt;code&gt;getPath&lt;&#x2F;code&gt; and &lt;code&gt;getPath2&lt;&#x2F;code&gt; are deprecated) that gives you a &lt;code&gt;std.Build.Cache.Path&lt;&#x2F;code&gt; object. And &lt;em&gt;that&lt;&#x2F;em&gt; in its turn has an &lt;code&gt;openDir&lt;&#x2F;code&gt; method that gives you a &lt;code&gt;std.fs.Dir&lt;&#x2F;code&gt; that then you can &lt;code&gt;walk&lt;&#x2F;code&gt;. Try figuring that out only from the docs.&lt;&#x2F;p&gt;
&lt;p&gt;The document traversal afterwards was simple enough. Basic Zig code.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;while&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt; walker.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;entry&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (entry.kind&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .file&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    std.mem.endsWith(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, entry.basename,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.c&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; not to do .s files&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; insert entry handling here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The second hurdle, and if you actually know what I know now this will all seem very stupid, is a bit more involved. At first I passed the arguments as I did for the other previous commands. So like this&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;zig&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; build eye&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; --&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; path&#x2F;to&#x2F;test&#x2F;folder&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; --parse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And I desugared the arguments accordingly.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; args: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt; u8 =&lt;&#x2F;span&gt;&lt;span&gt; b.args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;    &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;.&#x2F;c_files&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;--lex&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; };&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; least harmful default;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So this way, if I don&#x27;t pass anything, these would pass and the tree would be walked properly. Now &lt;code&gt;zig build eye&lt;&#x2F;code&gt; worked fine.&lt;&#x2F;p&gt;
&lt;p&gt;The problem is, if I run &lt;em&gt;another&lt;&#x2F;em&gt; command than &lt;code&gt;eye&lt;&#x2F;code&gt;, (say .. &lt;code&gt;run&lt;&#x2F;code&gt;), the directory walk would run anyway and then the build script would fail because the first argument is not a valid directory or whatever.&lt;&#x2F;p&gt;
&lt;p&gt;I did know that, btw.&lt;&#x2F;p&gt;
&lt;p&gt;Looking for help again someone suggested that the solution is to create a custom step, and even provided helpful code to do so. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;layneson&#x2F;e0ed54f9e14da878dd0ba102da41e2c3&quot;&gt;Here was a nice Gist I found on Google&lt;&#x2F;a&gt;. This seems perfect. So I do this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; std&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @import&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;std&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; build(b:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;std.Build) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; stuff unchanged&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; `zig build eye` command&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; eye_step&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.step(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;eye&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;eye test all the files in a given directory&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        var&lt;&#x2F;span&gt;&lt;span&gt; closure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.allocator.create(Closure) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-keyword z-statement z-zig&quot;&gt;catch unreachable&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        closure.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .{ .exe&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; exe, .step&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.Build.Step.init(.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .custom,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;inner_eye&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .makeFn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; make_eye_step,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }) };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        eye_step.dependOn(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;closure.step);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Closure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    exe:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;std.Build.Step.Compile,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    step: std.Build.Step,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; make_eye_step(step:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;std.Build.Step, _: std.Build.Step.MakeOptions) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; step.owner;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; closure:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Closure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @fieldParentPtr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;step&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, step);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; exe&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; closure.exe;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; args: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt; u8 =&lt;&#x2F;span&gt;&lt;span&gt; b.args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;        &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;.&#x2F;c_files&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;--lex&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; };&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; least harmful default;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; directory api boilerplate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; lazy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.path(args[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; lazy.getPath3(b,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; dir&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; path.openDir(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{ .access_sub_paths&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-bool z-zig&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt; });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; walker&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; dir.walk(b.allocator);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; walker.deinit();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; prev_run_cmd:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; ?*&lt;&#x2F;span&gt;&lt;span&gt;std.Build.Step.Run&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt; walker.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;entry&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (entry.kind&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .file&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; std.mem.endsWith(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, entry.basename,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.c&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; file&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; entry.path;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; bat&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.addSystemCommand(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;bat&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, file });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            bat.setCwd(lazy);&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; I am proud of myself for finding this&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            bat.stdio&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .inherit;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F; each invokation of `bat` depends on the previous run step so they&amp;#39;re sequential&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (prev_run_cmd) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                bat.step.dependOn(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;c.step);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; run_cmd&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.addRunArtifact(exe);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            run_cmd.setCwd(lazy);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            run_cmd.addArg(file);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            run_cmd.addArgs(args[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;..]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            run_cmd.stdio&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .inherit;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F; exactly what the default for `zig build run` does.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            run_cmd.step.dependOn(b.getInstallStep());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F; keeping the squence&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            run_cmd.step.dependOn(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;bat.step);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            prev_run_cmd&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; run_cmd;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; making sure the OG step depends on the tail of the chain.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    step.dependOn(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;prev_run_cmd.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;.step);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The way I see it, I am doing all the right things. All the steps depend on the proper steps, and best of all, the other &lt;code&gt;zig build&lt;&#x2F;code&gt; commands like &lt;code&gt;run&lt;&#x2F;code&gt; and &lt;code&gt;test&lt;&#x2F;code&gt; and what have you, all work fine.&lt;&#x2F;p&gt;
&lt;p&gt;Except this does not work. And I could not figure out.&lt;&#x2F;p&gt;
&lt;p&gt;Running this would dutifully go through the loop properly, as I was able to verify by inserting a few &lt;code&gt;prints&lt;&#x2F;code&gt;, but the commands do not run. And asking for help on the Discord only led me into StackOverflow-esque answers that I am not interested in repeating.&lt;&#x2F;p&gt;
&lt;p&gt;Asking for help on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ziggit.dev&quot;&gt;Ziggit&lt;&#x2F;a&gt; actually gave me enough info to understand the real problem. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ziggit.dev&#x2F;t&#x2F;a-custom-build-zig-command-to-run-system-commands-and-see-their-output&#x2F;10212&#x2F;4?u=asibahi&quot;&gt;This reply in particular&lt;&#x2F;a&gt; answered the dilemma for me.&lt;&#x2F;p&gt;
&lt;p&gt;Do you know where the two phases of the build system are mentioned in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ziglang.org&#x2F;learn&#x2F;build-system&#x2F;&quot;&gt;Official Build System Documentation and Intro&lt;&#x2F;a&gt;? Because I cannot find it. It is mentioned in passing in the documentation of some methods like &lt;code&gt;getPath3&lt;&#x2F;code&gt; and &lt;code&gt;run&lt;&#x2F;code&gt;, but with no proper explanation.&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, it clicked, and I was able to use the user provided options to insert the needed details.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; `zig build eye` command&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; eye_step&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.step(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;eye&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Eye test all the files in a given directory&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (b.option(std.Build.LazyPath,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;folder&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Path to eye&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;lazy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; same logic as before, more or less&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; walk_tree(b, exe, eye_step, lazy);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; *this* step, and only this one would fail&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; if the `folder` option is not set, because it&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; depends on `fail` only if the path does not exist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; fail&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.addFail(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;folder needed for eye&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        eye_step.dependOn(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;fail.step);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;b.option&lt;&#x2F;code&gt; creates a new argument for the user of the build system. This way, if the argument is present, the directory tree is walked and the proper dependencies are added to the &lt;code&gt;eye&lt;&#x2F;code&gt; command. If it is not, then the &lt;code&gt;eye&lt;&#x2F;code&gt; command will fail.&lt;&#x2F;p&gt;
&lt;p&gt;Other commands are unchanged and unaffected. The only difference from my first envisioning it is the way it is called, which I am not happy with, but eh. Pick your battles.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;zig&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; build eye&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -Dfolder=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;.&#x2F;c_files&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -- --parse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And it works exactly like I wanted. It calls &lt;code&gt;bat&lt;&#x2F;code&gt; on every file in a given directory followed by &lt;code&gt;paella&lt;&#x2F;code&gt; at the given stage, allowing for a quick eye test between the two. I&#x27;d paste the whole output here but I will settle for one file.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;File:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; multiple_if.c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; int main&lt;&#x2F;span&gt;&lt;span&gt;(void)&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;     int a =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;     int b =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;     if&lt;&#x2F;span&gt;&lt;span&gt; (a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;         a =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;     else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;         a =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;10&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;     if&lt;&#x2F;span&gt;&lt;span&gt; (b)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;11&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;         b =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;12&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;     else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;13&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;         b =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;14&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;15&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;     return a + b&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;16&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		int&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		int&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		IF&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ELSE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		IF&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ELSE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		RETURN (+&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a b&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;================================&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;automatic-formatting&quot;&gt;Automatic Formatting&lt;&#x2F;h2&gt;
&lt;p&gt;While mucking around in the documentation I discovered a nice &lt;code&gt;addFmt&lt;&#x2F;code&gt; method that is there to check for proper formatting in CI, but can just format the code for you. Adding these two lines pretty much anywhere in the file formatted everything every time I &lt;code&gt;zig build&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; fmt_step&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.addFmt(.{ .paths&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;.&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;} });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;exe.step.dependOn(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;fmt_step.step);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;internal-representation&quot;&gt;Internal Representation&lt;&#x2F;h2&gt;
&lt;p&gt;Now is the time to get on with new IR generation. Similarly to lat chapter, no new instructions need be appended. So after the IR generation stage, it is done. Short chapter all around.&lt;&#x2F;p&gt;
&lt;p&gt;Generating the IR for &lt;code&gt;if&lt;&#x2F;code&gt; statements is straightforward, with a slight complication around the optional &lt;code&gt;else&lt;&#x2F;code&gt; statement.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.@&amp;quot;if&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(bp, c.cond);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; else_label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.make_temporary(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;else&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .jump_z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cond, .target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; else_label } });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; stmt_emit_ir(bp, c.then);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (c.@&amp;quot;else&amp;quot;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;@&amp;quot;else&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; end_label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.make_temporary(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;end&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .jump&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; end_label });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; else_label });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; stmt_emit_ir(bp, @&amp;quot;else&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; end_label });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; else_label });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For conditional expressions, it is much of the same, except &lt;code&gt;expr_emit_ir&lt;&#x2F;code&gt; is called instead and its value is returned, and there is no optional &lt;code&gt;else&lt;&#x2F;code&gt; clause.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.ternary&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; else_label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.make_temporary(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;else&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; end_label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.make_temporary(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;end&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; dst_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.make_temporary(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;ter&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; dst: ir.Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .variable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dst_name };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(bp, t.@&amp;quot;0&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .jump_z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cond, .target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; else_label } });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; then&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(bp, t.@&amp;quot;1&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .copy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(then, dst) });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .jump&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; end_label });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; else_label });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; else_&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(bp, t.@&amp;quot;2&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .copy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(else_, dst) });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; end_label });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; dst;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And that&#x27;s it. I do not even have to run the intermediate codepaths as no changes to instructions or assembly generation this chapter. There is a small extra credit of implementing &lt;code&gt;goto&lt;&#x2F;code&gt;, but I am skipping extra credit this time.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;&#x2F;h2&gt;
&lt;p&gt;Not to repeat ranting at Zig&#x27;s documentation, but I definitely now understand Zig&#x27;s build system at a deeper level than before.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-ai&quot;&gt;
&lt;p&gt;If all else fails I can get some LLM to generate it for me. It would work fine. &lt;a href=&quot;#fr-ai-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-recursive&quot;&gt;
&lt;p&gt;Turns out it is recursive and I actually wanted &lt;code&gt;iterate()&lt;&#x2F;code&gt;. But that is on me, it is clearly written. &lt;a href=&quot;#fr-recursive-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Chapter 5: Variables</title>
        <published>2025-05-21T00:00:00+00:00</published>
        <updated>2025-05-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/paella/c5/"/>
        <id>https://ar-ms.me/paella/c5/</id>
        
        <content type="html" xml:base="https://ar-ms.me/paella/c5/">&lt;p&gt;Reflecting on the &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;paella&#x2F;c4&#x2F;&quot;&gt;past chapters so far&lt;&#x2F;a&gt;, I am starting to think that this project is perhaps the perfect vehicle to explore new languages. Right off the bat, one deals with file systems, cross compiling, data structures, memory management, pretty formatting, and what have you.&lt;&#x2F;p&gt;
&lt;p&gt;But as the project goes on, especially if you are familiar with the problem (read: have done it before in a previous language), most of the tasks become purely mechanical. Refactoring, updating requirements, satisfying compiler errors. It shows you how the language handles churn, and whether it is pleasant or not. It also shows how helpful the community around the language when you inevitably have to debug your language knowledge and hit weird snags.&lt;&#x2F;p&gt;
&lt;p&gt;So, yeah. If you want to learn a new programming language, get yourself &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;norasandler.com&#x2F;2022&#x2F;03&#x2F;29&#x2F;Write-a-C-Compiler-the-Book.html&quot;&gt;Writing a C Compiler&lt;&#x2F;a&gt;, do it once (at least halfway) with your favorite language. Then you can do it with any language as a test run. Way less math than a ray tracer.&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, now is Chapter 5. Chapter 5 is about, let me look, local variables. Oh &lt;em&gt;finally&lt;&#x2F;em&gt; some new statements.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lexer-and-parser&quot;&gt;Lexer and Parser&lt;&#x2F;h2&gt;
&lt;p&gt;One new token, &lt;code&gt;=&lt;&#x2F;code&gt;. Adding this is trivial so I am sparing you the details. There is one thing to update that, while belongs to the parser, is placed in &lt;code&gt;lexer.zig&lt;&#x2F;code&gt;. The precedence chart.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;operator-associativity&quot;&gt;Operator Associativity&lt;&#x2F;h3&gt;
&lt;p&gt;Previously, all operators were left associative. This one, however, is &lt;em&gt;right&lt;&#x2F;em&gt; associative. One could make a special case for it, but another upcoming operators&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-ternary-1&quot;&gt;&lt;a href=&quot;#fn-ternary&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; are right associative as well. So care must be taken.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;binop_precedence&lt;&#x2F;code&gt; function is implemented as a method in &lt;code&gt;Token.Tag&lt;&#x2F;code&gt;, and this is how it looks after adding &lt;code&gt;=&lt;&#x2F;code&gt;. It returns a tuple now instead of just a &lt;code&gt;u8&lt;&#x2F;code&gt;. The reason &lt;code&gt;left&lt;&#x2F;code&gt; is a &lt;code&gt;u8&lt;&#x2F;code&gt; as well is because the two numbers are added later and changing from &lt;code&gt;bool&lt;&#x2F;code&gt; to &lt;code&gt;u8&lt;&#x2F;code&gt; in Zig is a torture. Even &lt;code&gt;if (left) 1 else 0&lt;&#x2F;code&gt; does not work as it actually returns a &lt;code&gt;comptime int&lt;&#x2F;code&gt; ....&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; binop_precedence(self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @This&lt;&#x2F;span&gt;&lt;span&gt;()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; { &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt; } {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return switch&lt;&#x2F;span&gt;&lt;span&gt; (self) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .asterisk,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .f_slash,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .percent,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; %&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt;        =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;50&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .hyphen,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; -&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .plus,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt;        =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;45&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .lesser_than,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .lesser_equals,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .greater_than,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .greater_equals,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt;        =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;35&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .double_equals,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .bang_equals,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt;        =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;30&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .double_ambersand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .double_pipe&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .equals&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It would be perhaps more idiomatic to a create a proper struct and give the fields proper name and have a proper enum for left vs right associativity but, eh. Too much boilerplate for a one use function.&lt;&#x2F;p&gt;
&lt;p&gt;In &lt;code&gt;parse_expr&lt;&#x2F;code&gt;, the rules are slightly amended. Instead of this &lt;code&gt;while&lt;&#x2F;code&gt; loop:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;while&lt;&#x2F;span&gt;&lt;span&gt; (next_token.tag.binop_precedence()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;prec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (prec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; min_prec) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; rhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(alloc, tokens, prec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; etc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It now becomes this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;while&lt;&#x2F;span&gt;&lt;span&gt; (next_token.tag.binop_precedence()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; prec,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; const&lt;&#x2F;span&gt;&lt;span&gt; left&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; r;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; destructuring yay&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (prec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; min_prec) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; rhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(alloc, tokens, prec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; left);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; etc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And that .. is pretty much it. Just map the new operator to the new expression that I have not written yet.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;new-statements-and-expressions&quot;&gt;New Statements and Expressions!&lt;&#x2F;h3&gt;
&lt;p&gt;Two new expressions:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    constant:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @&amp;quot;var&amp;quot;: [:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    assignment: BinOp,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; etc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And two new statements, finally. This is the entire &lt;code&gt;Stmt&lt;&#x2F;code&gt; type, with its formatter, too.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Stmt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @&amp;quot;return&amp;quot;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    expr:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt;    null&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; void&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span&gt; format(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @This&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;        comptime&lt;&#x2F;span&gt;&lt;span&gt; _: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        options: std.fmt.FormatOptions,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        writer:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; anytype&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; options.width&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; orelse&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; writer.writeByteNTimes(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;\t&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;, w);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        switch&lt;&#x2F;span&gt;&lt;span&gt; (self) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .@&amp;quot;return&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;RETURN {}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{expr}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{};&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{expr}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt;null&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There is a new AST node, too! &lt;code&gt;Decl&lt;&#x2F;code&gt; is a variable declaration. (Maybe it should be &lt;code&gt;VarDecl&lt;&#x2F;code&gt; considering what is to come?) It is a simple one.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Decl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; no type because there is only one type so far: int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    expr:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; ?*&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here is a fun note. In the AST proper, all the strings are backed by the source code. So they are &lt;em&gt;not&lt;&#x2F;em&gt; null-terminated (&lt;code&gt;[]const u8&lt;&#x2F;code&gt;). However, in the following stages, the strings are backed by &lt;code&gt;StringInterner&lt;&#x2F;code&gt;, so they &lt;em&gt;are&lt;&#x2F;em&gt; null-terminated (&lt;code&gt;[:0]const u8&lt;&#x2F;code&gt;). I could use normal slices or null-terminated &lt;em&gt;pointers&lt;&#x2F;em&gt; (&lt;code&gt;[*:0]const u8&lt;&#x2F;code&gt;) in the second case just as well, but extra safety does not hurt a toy compiler like this one.&lt;&#x2F;p&gt;
&lt;p&gt;Also, since function bodies can include either declarations or statements, there is a need for a simple &lt;code&gt;BlockItem&lt;&#x2F;code&gt; union. Here it is with its formatter that just delegates to the sub type. I will probably never have to touch this again.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; BlockItem&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    D: Decl,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    S: Stmt,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span&gt; format(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @This&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;        comptime&lt;&#x2F;span&gt;&lt;span&gt; fmt: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        options: std.fmt.FormatOptions,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        writer:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; anytype&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        switch&lt;&#x2F;span&gt;&lt;span&gt; (self) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            inline else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; i.format(fmt, options, writer),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And then update &lt;code&gt;FuncDef&lt;&#x2F;code&gt; to have an collection of &lt;code&gt;BlockItem&lt;&#x2F;code&gt;s, rather than a pointer to one &lt;code&gt;Stmt&lt;&#x2F;code&gt;.Since these pointers are arena backed, it makes little sense for it to be an &lt;code&gt;ArrayList&lt;&#x2F;code&gt;, because this collection reallocates a lot. A better idea is either a linked list, or a segmented list which is a halfway between the two. The main downside is that I cannot just take a slice from either of these two collections. I will cross that bridge when I come to it.&lt;&#x2F;p&gt;
&lt;p&gt;The Zig&#x27;s &lt;code&gt;SinglyLinkedList&lt;&#x2F;code&gt; type has an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.openmymind.net&#x2F;Zigs-New-LinkedList-API&#x2F;&quot;&gt;api change on the master&lt;&#x2F;a&gt;. So to avoid potential future churn in a future where I upgrade Zig&#x27;s version, I am going to go with &lt;code&gt;SegmentedList&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Here I also revise an earlier design decision. Previously, every parsing structure returns a pointer to its result. But the new &lt;code&gt;FuncDef&lt;&#x2F;code&gt; makes no use of pointers, as they are added to the &lt;code&gt;SegmentedList&lt;&#x2F;code&gt;. So I rewrote all the functions to remove the allocation on the return value, and place instead on where it is actually needed at assignment. Plenty of refactoring.&lt;&#x2F;p&gt;
&lt;p&gt;Because of extensive changes throughout almost every function in &lt;code&gt;parser.zig&lt;&#x2F;code&gt;, here is the entire file in its current state. I have not tried compiling it yet, so beware of typos.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; std&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @import&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;std&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; ast&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @import&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;ast.zig&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; lexer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @import&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;lexer.zig&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; utils&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @import&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;utils.zig&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; parse_prgm(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    arena: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ast.Prgm {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; func_def&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_func_def(arena, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; func_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(ast.FuncDef, arena, func_def);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; now that we are done, check the tokenizer is empty.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (tokens.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;_&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.ExtraJunk;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .func_def&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; func_ptr };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_func_def(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    arena: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ast.FuncDef {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.type_int, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expect(.identifier, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.l_paren, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.keyword_void, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.r_paren, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.l_brace, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; body: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SegmentedList&lt;&#x2F;span&gt;&lt;span&gt;(ast.BlockItem,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .{};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-bool z-zig&quot;&gt;true&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; next_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (next_token.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .r_brace) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tokens.put_back(next_token);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_block_item(arena, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; body.append(arena, item);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; name, .body&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; body };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_block_item(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    arena: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ast.BlockItem {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; next_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (next_token.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .type_int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expect(.identifier, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; new_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; ?*&lt;&#x2F;span&gt;&lt;span&gt;ast.Expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (new_token.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .equals&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ret: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;                    const&lt;&#x2F;span&gt;&lt;span&gt; res&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;                    const&lt;&#x2F;span&gt;&lt;span&gt; expr_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(ast.Expr, arena, res);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.semicolon, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    break&lt;&#x2F;span&gt;&lt;span&gt; :ret expr_ptr;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .semicolon&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; .{ .D&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; name, .expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; expr } };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; statements&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .semicolon&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; .{ .S&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt;null&lt;&#x2F;span&gt;&lt;span&gt; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .keyword_return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(ast.Expr, arena, expr);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; expect(.semicolon, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; .{ .S&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .@&amp;quot;return&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; expr_ptr } };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tokens.put_back(next_token);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; expr_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(ast.Expr, arena, expr);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; expect(.semicolon, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; .{ .S&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; expr_ptr } };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    arena: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    min_prec:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ast.Expr {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_factor(arena, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; lhs_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(ast.Expr, arena, lhs);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; next_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (next_token.tag.binop_precedence()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; prec,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; const&lt;&#x2F;span&gt;&lt;span&gt; left&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; r;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (prec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; min_prec) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; rhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens, prec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; left);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; rhs_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(ast.Expr, arena, rhs);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; bin_op: ast.Expr.BinOp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ lhs_ptr, rhs_ptr };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (next_token.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .plus&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .binop_add&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bin_op },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .hyphen&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .binop_sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bin_op },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .asterisk&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .binop_mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bin_op },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .f_slash&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .binop_div&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bin_op },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .percent&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .binop_rem&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bin_op },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .equals&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .assignment&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bin_op },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .double_ambersand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .binop_and&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bin_op },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .double_pipe&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .binop_or&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bin_op },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .double_equals&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .binop_eql&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bin_op },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .bang_equals&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .binop_neq&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bin_op },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .lesser_than&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .binop_lt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bin_op },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .greater_than&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .binop_gt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bin_op },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .lesser_equals&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .binop_le&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bin_op },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .greater_equals&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .binop_ge&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bin_op },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-statement z-zig&quot;&gt; unreachable&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        next_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens.put_back(next_token);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; lhs;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_factor(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    arena: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ast.Expr {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; current&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (current.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .identifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .@&amp;quot;var&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.buffer[current.loc.start..current.loc.end],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .number_literal&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; lit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.buffer[current.loc.start..current.loc.end];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; res&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.fmt.parseInt(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;u64&lt;&#x2F;span&gt;&lt;span&gt;, lit,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;catch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.InvalidInt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; .{ .constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; res };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .hyphen&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; inner_exp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_factor(arena, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; .{ .unop_neg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(ast.Expr, arena, inner_exp) };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .tilde&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; inner_exp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_factor(arena, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; .{ .unop_not&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(ast.Expr, arena, inner_exp) };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .bang&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; inner_exp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_factor(arena, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; .{ .unop_lnot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(ast.Expr, arena, inner_exp) };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .l_paren&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; inner_exp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; expect(.r_paren, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; inner_exp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;inline fn&lt;&#x2F;span&gt;&lt;span&gt; expect(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;    comptime&lt;&#x2F;span&gt;&lt;span&gt; expected: lexer.Token.Tag,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ExpectResult&lt;&#x2F;span&gt;&lt;span&gt;(expected) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (tokens.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;actual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (actual.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span&gt; expected)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        switch&lt;&#x2F;span&gt;&lt;span&gt; (expected) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .identifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; tokens.buffer[actual.loc.start..actual.loc.end],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ExpectResult&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;comptime&lt;&#x2F;span&gt;&lt;span&gt; expected: lexer.Token.Tag) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (expected) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .identifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; void&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    std.mem.Allocator.Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        SyntaxError,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        InvalidInt,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ExtraJunk,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;test&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;precedence&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.testing;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; a_a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.heap.ArenaAllocator.init(t.allocator);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; a_a.deinit();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; a_a.allocator();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;3 * 4 + 5;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        var&lt;&#x2F;span&gt;&lt;span&gt; tokens&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; lexer.Tokenizer.init(src);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(a,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;tokens,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; t.expect(result.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator&quot;&gt;* ==&lt;&#x2F;span&gt;&lt;span&gt; .binop_add);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; t.expectFmt(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;(+ (* 3 4) 5)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;{}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{result});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;4 + 3 &amp;amp;&amp;amp; -17 * 4 &amp;lt; 5;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        var&lt;&#x2F;span&gt;&lt;span&gt; tokens&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; lexer.Tokenizer.init(src);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(a,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;tokens,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; t.expect(result.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator&quot;&gt;* ==&lt;&#x2F;span&gt;&lt;span&gt; .binop_and);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; t.expectFmt(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;(&amp;amp;&amp;amp; (+ 4 3) (&amp;lt; (* (- 17) 4) 5))&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;{}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{result});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Well, that was a trip. The &lt;code&gt;ir_gen&lt;&#x2F;code&gt; functions are broken too so they were replaced by a stub for now.&lt;&#x2F;p&gt;
&lt;p&gt;Here is the C file I am using as my science mouse this chapter:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2147483646&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; c &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-logical&quot;&gt; + !&lt;&#x2F;span&gt;&lt;span&gt;b;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; c &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1431655762&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And this is the parser output. It oviously does not cover every path the code can take but that&#x27;s what a test suite is for. Which they all pass, so hooray.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		int a &amp;lt;- 2147483646;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		int b &amp;lt;- 0;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		int c &amp;lt;- (+ a (! b));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		RETURN (== c (- a 1431655762))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It is important to keep in mind that the test suite at this stage does not check for correct logic, but for whether the compilers fails the programs it should. Correct logic is checked either by custom unit tests (which I discussed last chapter) and testing the final compiler output.&lt;&#x2F;p&gt;
&lt;p&gt;Wait hold on. Where did the &lt;code&gt;a&#x2F;6&lt;&#x2F;code&gt; go?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;unit-testing-considered-useful&quot;&gt;Unit Testing Considered Useful&lt;&#x2F;h3&gt;
&lt;p&gt;Checking the unit tests I did last chapter, they are failing too. What gives? The code is all up there. Can you spot the error?&lt;&#x2F;p&gt;
&lt;p&gt;Poking around, I realized the error happened when I changed all functions to return the nodes immediately rather than pointers to them. It is this pair of lines in the beginning of &lt;code&gt;parse_expr&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;var&lt;&#x2F;span&gt;&lt;span&gt; lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_factor(arena, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; lhs_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(ast.Expr, arena, lhs);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And then I keep the first and only &lt;code&gt;lhs_ptr&lt;&#x2F;code&gt; around assigning to the left side of all following expressions. Bah. Running the fix on the C code snippet above gets me this result now.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		int a &amp;lt;- 2147483646;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		int b &amp;lt;- 0;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		int c &amp;lt;- (+ (&#x2F; a 6) (! b));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		RETURN (== (* c 2) (- a 1431655762))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is the new and improved &lt;code&gt;parse_expr&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    arena: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    min_prec:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ast.Expr {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_factor(arena, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; next_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; tokens.put_back(next_token);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (next_token.tag.binop_precedence()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; prec,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; const&lt;&#x2F;span&gt;&lt;span&gt; left&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; r;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (prec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; min_prec) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; lhs_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(ast.Expr, arena, lhs);&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;  &#x2F;&#x2F; &amp;lt;-- fix&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; rhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens, prec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; left);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; rhs_ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(ast.Expr, arena, rhs);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; bin_op: ast.Expr.BinOp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ lhs_ptr, rhs_ptr };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (next_token.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F; same as before&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        next_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; lhs;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;semantic-analysis&quot;&gt;Semantic Analysis&lt;&#x2F;h2&gt;
&lt;p&gt;Oh that&#x27;s a new one. This is where things like &lt;code&gt;2 = a * 3&lt;&#x2F;code&gt; are rejected. Other compilers seem to call this pass &lt;code&gt;sema&lt;&#x2F;code&gt;, so I am adding a &lt;code&gt;sema.zig&lt;&#x2F;code&gt;. This file is concerned with transforming and checking the AST: double declarations, no declarations, shadowing, scoping, what have you.&lt;&#x2F;p&gt;
&lt;p&gt;The pseudocode functions in the Book have a &lt;code&gt;variable_map&lt;&#x2F;code&gt; input. it maps each name, apparently, to a unique name (that I assume will be interned later?). I am unsure how this would look eventually, but for now I will be naive and use a &lt;code&gt;std.StringHashMap([]const u8)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Here is the Book&#x27;s &lt;code&gt;resolve_decl&lt;&#x2F;code&gt; pseudocode into Zig-ish pseudocode:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; resolve_decl(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    decl:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Decl,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    variable_map: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;StringHashMap&lt;&#x2F;span&gt;&lt;span&gt;([]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (variable_map.contains(decl.name))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.DuplicateVariableDecl;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; unique_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; make_temporary();&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; todo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; variable_map.put(decl.name, unique_name);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; init:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; ?*&lt;&#x2F;span&gt;&lt;span&gt;Expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (decl.init) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt;|*&lt;&#x2F;span&gt;&lt;span&gt;expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(expr, variable_map) &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; todo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt;        null&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; where is the expr allocated?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; unique_name, .init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; init };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So many todos and questions. This requires filling up piece by piece.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;new-names-for-old-variables&quot;&gt;New Names for Old Variables&lt;&#x2F;h3&gt;
&lt;p&gt;First of all, the new &lt;code&gt;unique_name&lt;&#x2F;code&gt;. This is going to be used, as is, in the next compiler passes. So it makes sense for it to be on the StringInterner. Which means, the StringInterner &lt;em&gt;and&lt;&#x2F;em&gt; its backing allocator should be passed into the function. I am going to save myself some trouble and just go ahead and create a &lt;code&gt;Boilerplate&lt;&#x2F;code&gt; struct like I did in &lt;code&gt;ir_gen&lt;&#x2F;code&gt; previously.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; first pass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Boilerplate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    gpa: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    strings:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;utils.StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    variable_map:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;StringHashMapUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;([:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span&gt; make_temporary(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @This&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;        comptime&lt;&#x2F;span&gt;&lt;span&gt; prefix: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;[:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; todo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The next problem is that, to make sure the variable is unique in future compiler passes, it should use the counter. The counter is currently self contained within &lt;code&gt;ir_gen&lt;&#x2F;code&gt;&#x27;s &lt;code&gt;make_temporary&lt;&#x2F;code&gt;, but now it has to be elevated into its own thing. So, I am changing it to make it a method of &lt;code&gt;StringInterner&lt;&#x2F;code&gt;, and have both new and old &lt;code&gt;make_temporary&lt;&#x2F;code&gt; functions use that one.&lt;&#x2F;p&gt;
&lt;p&gt;This is the new method on &lt;code&gt;StringInterner&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; make_temporary(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    gpa: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    prefix: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;[:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; zig static variables&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; static&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        var&lt;&#x2F;span&gt;&lt;span&gt; counter:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt; usize =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; buf: [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt;u8 =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; undefined&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; name_buf&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; std.fmt.bufPrint(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;        &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;buf,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;quot;{s}.{}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .{ (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (prefix.len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;tmp&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; prefix), static.counter },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; self.get_or_put(gpa, name_buf);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    static.counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; name.string;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;One change from the previous function: &lt;code&gt;prefix&lt;&#x2F;code&gt; is not &lt;code&gt;comptime&lt;&#x2F;code&gt; known any more as it can be a user-specified variable. I am not quite sure, to be honest, if this code compiles, but I will find out by the end of this section. This is the new &lt;code&gt;make_temporary&lt;&#x2F;code&gt; in both &lt;code&gt;ir_gen&lt;&#x2F;code&gt; and the new &lt;code&gt;sema&lt;&#x2F;code&gt;. Note that &lt;code&gt;self&lt;&#x2F;code&gt; (and &lt;code&gt;Error&lt;&#x2F;code&gt; for that matter) are different types for both functions, but it has the same interface.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; make_temporary(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @This&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    prefix: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;[:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return try&lt;&#x2F;span&gt;&lt;span&gt; self.strings.make_temporary(self.alloc, prefix);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;resolutions&quot;&gt;Resolutions&lt;&#x2F;h3&gt;
&lt;p&gt;This is the new &lt;code&gt;resolve_decl&lt;&#x2F;code&gt; after the nip and tuck and adjusting to change the &lt;code&gt;Decl&lt;&#x2F;code&gt; in place:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; resolve_decl(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bp: Boilerplate,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    decl:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Decl,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (bp.variable_map.contains(decl.name))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.DuplicateVariableDecl;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; unique_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.make_temporary(decl.name);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.variable_map.put(bp.gpa, decl.name, unique_name);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (decl.init) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(bp, expr);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Only &lt;code&gt;resolve_expr&lt;&#x2F;code&gt; remains a stub. So naturally the next step is the relatively simple &lt;code&gt;resolve_stmt&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; resolve_stmt(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bp: Boilerplate,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    stmt:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Stmt,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (stmt.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .@&amp;quot;return&amp;quot;, .expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(bp, expr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt;null&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And now this is &lt;code&gt;resolve_expr&lt;&#x2F;code&gt;. To be frank I am not quite sure I still have the right incantations regarding &lt;code&gt;*&lt;&#x2F;code&gt; and &lt;code&gt;.*&lt;&#x2F;code&gt; and &lt;code&gt;&amp;amp;&lt;&#x2F;code&gt;. I trust the compiler will correct me when it comes to it.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-compiler-1&quot;&gt;&lt;a href=&quot;#fn-compiler&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bp: Boilerplate,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    expr:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (expr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .assignment&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (b.@&amp;quot;0&amp;quot;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator&quot;&gt;* !=&lt;&#x2F;span&gt;&lt;span&gt; .@&amp;quot;var&amp;quot;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.InvalidLValue;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(bp, b.@&amp;quot;0&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(bp, b.@&amp;quot;1&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .@&amp;quot;var&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; expr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (bp.variable_map.get(name)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;un&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .@&amp;quot;var&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; un }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.UndeclaredVariable,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .unop_neg,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .unop_not,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .unop_lnot,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt;        =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(bp, u),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .binop_add,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .binop_sub,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .binop_mul,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .binop_div,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .binop_rem,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .binop_and,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .binop_or,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .binop_eql,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .binop_neq,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .binop_ge,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .binop_gt,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .binop_le,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .binop_lt,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt;        =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(bp, b.@&amp;quot;0&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; resolve_expr(bp, b.@&amp;quot;1&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This leaves &lt;code&gt;resolve_prgm&lt;&#x2F;code&gt; and &lt;code&gt;resolve_func_def&lt;&#x2F;code&gt; which are barely interesting, if not for setting up the &lt;code&gt;Boilerplate&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; resolve_prgm(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    gpa: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    strings:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;utils.StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    prgm:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Prgm,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; variable_map: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;StringHashMapUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;([:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .empty;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; bp: Boilerplate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .gpa&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; gpa,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .strings&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; strings,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .variable_map&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;variable_map,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; resolve_func_def(bp, prgm.func_def);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; resolve_func_def(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bp: Boilerplate,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    func_def:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.FuncDef,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; func_def.body.iterator(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (item.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .S&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_stmt(bp, s),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .D&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; resolve_decl(bp, d),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, the proof of the pudding is in the eating. Let&#x27;s wire it in the compiler driver (with an all new &lt;code&gt;validate&lt;&#x2F;code&gt; option), and see the results.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;nospaceleft&quot;&gt;NoSpaceLeft&lt;&#x2F;h3&gt;
&lt;p&gt;Running the test suite came up with odd and confusing errors and long info dumps. Time to investigate.&lt;&#x2F;p&gt;
&lt;p&gt;First of all, run the new code against the sample C program from before. and it fails with a .. memory leak? Turning off the memory leak detection (which is simple enough with Zig&#x27;s &lt;code&gt;DebugAllocator&lt;&#x2F;code&gt;) It passes fine, but the variable names seem unchanged. Hmm.&lt;&#x2F;p&gt;
&lt;p&gt;Trying the test suite again with the turned off leak checking (just to see if it passes), however, is also failing with &lt;code&gt;NoSpaceLeft&lt;&#x2F;code&gt;. One file seems to fail, and it is following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; first_variable &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; second_variable &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; first_variable &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; second_variable;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Looks simple enough. Running it through, the zig compilers gives me a very helpful, and very very long, stack tarce. It fails in &lt;code&gt;make_temporary&lt;&#x2F;code&gt;. Oh the &lt;em&gt;buffer&lt;&#x2F;em&gt; does not have enough space. I made a 16 byte buffer to avoid a heap allocation. Silly me. Let&#x27;s change it to a 64 byte buffer.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-buffer-1&quot;&gt;&lt;a href=&quot;#fn-buffer&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; was&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;var&lt;&#x2F;span&gt;&lt;span&gt; buf: [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt;u8 =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; undefined&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; name_buf&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; std.fmt.bufPrint(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;    &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;buf,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;{s}.{}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (prefix.len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;tmp&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; prefix), static.counter },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; becomes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;var&lt;&#x2F;span&gt;&lt;span&gt; buf: [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt;u8 =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; undefined&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; name_buf&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; std.fmt.bufPrint(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;    &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;buf,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;{s}.{}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (prefix.len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;tmp&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; prefix), static.counter },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Well, this fixes the issue at least. This is the output of &lt;code&gt;--validate&lt;&#x2F;code&gt; on that file now:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		int first_variable &amp;lt;- 1;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		int second_variable &amp;lt;- 2;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		RETURN (+ first_variable.0 second_variable.1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As you can see, the names are updated alright, but apparently not in &lt;code&gt;Decl&lt;&#x2F;code&gt;&#x27;s &lt;code&gt;name&lt;&#x2F;code&gt; field. That&#x27;s a silly oversight. Let&#x27;s fix that now.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; end of resolve_decl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    decl.name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; unique_name;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- new line&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Well this takes care of that. Now let me figure out the memory leak.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;leak&quot;&gt;Leak&lt;&#x2F;h3&gt;
&lt;p&gt;Let&#x27;s run the same program again and look through the call trace the zig compiler very helpfully provides.&lt;&#x2F;p&gt;
&lt;p&gt;Oh I forgot to deinit &lt;code&gt;variable_map&lt;&#x2F;code&gt;. Silly me. This would happen in &lt;code&gt;resolve_prgm&lt;&#x2F;code&gt; because I have no use for it afterwards right now.&lt;&#x2F;p&gt;
&lt;p&gt;Yay no memory leaks. That ws easy.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;ir-generation&quot;&gt;IR Generation&lt;&#x2F;h2&gt;
&lt;p&gt;No changes to the IR syntax tree today. Only generating IR for the new AST nodes. This also means there are no assembly changes either. Almost there to a stable IR backend.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-ir-1&quot;&gt;&lt;a href=&quot;#fn-ir&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The most interesting thing in here is that variable declarations are simply discarded. They have done their job in semantic analysis, and now they are shown the door. But let&#x27;s go backwards.&lt;&#x2F;p&gt;
&lt;p&gt;The new expressions emitting IR are just &lt;code&gt;@&quot;var&quot;&lt;&#x2F;code&gt; and &lt;code&gt;assignment&lt;&#x2F;code&gt;. &lt;code&gt;var&lt;&#x2F;code&gt; is cast to a null terminated pointer but that is it. It is already backed by the interner from the semantic analysis phase. &lt;code&gt;assignment&lt;&#x2F;code&gt; puts the items in a weird bizarro order, where &lt;code&gt;dst&lt;&#x2F;code&gt; is the first item.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.@&amp;quot;var&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; .{ .variable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @ptrCast&lt;&#x2F;span&gt;&lt;span&gt;(v) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.assignment&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; bizarro order&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(bp, b.@&amp;quot;0&amp;quot;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; guaranteed to be a var&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(bp, b.@&amp;quot;1&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .copy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(src, dst) });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; dst;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The new statements just pass through:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; stmt_emit_ir(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bp: Boilerplate,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    stmt:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; ast.Stmt,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (stmt.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt;null&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .@&amp;quot;return&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(bp, e),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(bp, e),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The interesting new part is &lt;code&gt;func_def_emit_ir&lt;&#x2F;code&gt;. Since &lt;code&gt;body&lt;&#x2F;code&gt; is now a list of stuff rather than just one statement, I need to iterate over it and generate IR from each item. But there is no &lt;code&gt;decl_emit_ir&lt;&#x2F;code&gt; yet, so I will do that first. If there is no initialization expression, do nothing. If there is, evaluate the expression and copy it to the variable&#x27;s name.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; decl_emit_ir(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bp: Boilerplate,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    decl:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; ast.Decl,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (decl.init) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(bp, e);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .copy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(src, .{ .variable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @ptrCast&lt;&#x2F;span&gt;&lt;span&gt;(decl.name) }) });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now &lt;code&gt;func_def_emit_ir&lt;&#x2F;code&gt; has to construct the IR instructions in a body. So a loop over the block items to process them one at a time is the simplest way to do it. The Book recommends adding a simple &lt;code&gt;return 0;&lt;&#x2F;code&gt; instruction to the end as an edgecase for functions written without a return value. This is the C standard for &lt;code&gt;main&lt;&#x2F;code&gt;, but as omitting a return value is undefined behaviour for other functions, I can just do whatever, so adding a &lt;code&gt;return 0&lt;&#x2F;code&gt; is entirely within the spec. It would not get processed if the code author did not forget their &lt;code&gt;return&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; func_def_emit_ir(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    strings:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;utils.StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    func_def:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; ast.FuncDef,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ir.FuncDef {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; strings.get_or_put(alloc, func_def.name);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; instrs: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(ir.Instr) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .empty;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; bp: Boilerplate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .alloc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .strings&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; strings,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .instrs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;instrs,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; func_def.body.constIterator(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (item.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .S&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; stmt_emit_ir(bp, s),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .D&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; decl_emit_ir(bp, d),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; instrs.append(alloc, .{ .ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; } });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; name.string, .instrs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instrs };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And that&#x27;s it. There is no new assembly generation because there are no new IR instructions. So time to test the whole shebang, which it all passes. So Hurray.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lessons-learned-rant-about-zig&quot;&gt;&lt;del&gt;Lessons Learned&lt;&#x2F;del&gt; Rant About Zig&lt;&#x2F;h2&gt;
&lt;p&gt;How much I hate Zig&#x27;s unergonomic optionals, for one, and how unergonomic integer literals are, for two.&lt;&#x2F;p&gt;
&lt;p&gt;For all the good Zig has, some things are just way, way harder than they have any right to be. Take for example &lt;code&gt;parse_expr&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;while&lt;&#x2F;span&gt;&lt;span&gt; (current.tag.binop_precedence()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; prec,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; const&lt;&#x2F;span&gt;&lt;span&gt; left&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; r;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (prec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; min_prec) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; rhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens, prec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; left);&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;- look here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; snip --&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The reason I made &lt;code&gt;binop_precedence&lt;&#x2F;code&gt; return a &lt;code&gt;u8&lt;&#x2F;code&gt; for left-associativity, is how absurdly difficult it is and ugly it is to work with otherwise.&lt;&#x2F;p&gt;
&lt;p&gt;The natural way of modeling this is to use either a &lt;code&gt;bool&lt;&#x2F;code&gt; or an enum. But if &lt;code&gt;left&lt;&#x2F;code&gt; was a bool, this very normal looking, perfectly readable code would not compile:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; rhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens, prec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (left) &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The reason for that is integer literals (&lt;code&gt;1&lt;&#x2F;code&gt; and &lt;code&gt;0&lt;&#x2F;code&gt; in this snippet) are of type &lt;code&gt;comptime_int&lt;&#x2F;code&gt;. The type inference is not smart enough to get there.&lt;&#x2F;p&gt;
&lt;p&gt;Which is like, fine, whatever. That would not be an issue if it was not for the fact you literally &lt;strong&gt;cannot&lt;&#x2F;strong&gt; create typed literals. &lt;code&gt;1u8&lt;&#x2F;code&gt;, like Rust or Odin would do, is not the Zig way. It is not &lt;em&gt;explicit&lt;&#x2F;em&gt; enough. The way to do it is &lt;code&gt;@as(u8, 1)&lt;&#x2F;code&gt;. No joke.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; rhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(arena, tokens, prec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (left) &lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt;@as&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At least the type inference is smart enough to infer the &lt;code&gt;0&lt;&#x2F;code&gt;, thank god.&lt;&#x2F;p&gt;
&lt;p&gt;Wait, you say, you can cast. So why not cast the &lt;code&gt;bool&lt;&#x2F;code&gt; to a &lt;code&gt;u8&lt;&#x2F;code&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;Haha you fool. Casting a &lt;code&gt;bool&lt;&#x2F;code&gt; to an integer makes no sense! There is a special builtin for that, called &lt;code&gt;@intFromBool&lt;&#x2F;code&gt;. Why not use that, you ask? Because this built in returns a &lt;code&gt;u1&lt;&#x2F;code&gt;. Which is really a &lt;code&gt;u8&lt;&#x2F;code&gt; in memory but the type system will not automatically cast it to the wider integer because ... fuck if I know.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-niche-1&quot;&gt;&lt;a href=&quot;#fn-niche&quot;&gt;5&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; So you end up with this beauty: &lt;code&gt;@as(u8, @intFromBool(left))&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Absolutely inane design decisions that all they do is annoy and frustrate the user. So I just returned a &lt;code&gt;u8&lt;&#x2F;code&gt; from &lt;code&gt;binop_precedence&lt;&#x2F;code&gt;. Incorrect, but less fuss.&lt;&#x2F;p&gt;
&lt;p&gt;I will leave the optionals rant for later. Meanwhile, enjoy this contraption that should have been in the core language. (Yes it does work.)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; compare_optional(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    opt:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; anytype&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    value:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @typeInfo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt;        @typeInfo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt;@TypeOf&lt;&#x2F;span&gt;&lt;span&gt;(opt)).optional.child,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ).@&amp;quot;union&amp;quot;.tag_type.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; ((opt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; orelse return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-bool z-zig&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; value);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-ternary&quot;&gt;
&lt;p&gt;I speak, of course, of the beloved ternary operator. &lt;a href=&quot;#fr-ternary-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-compiler&quot;&gt;
&lt;p&gt;I will have you know I went back and corrected things as the compiler bid me, so now it looks like I got it right the first time. &lt;a href=&quot;#fr-compiler-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-buffer&quot;&gt;
&lt;p&gt;I looked it up, and the maximum length for internal C identifirs is 63 bytes, and anything afterwards is discarded. This is tighter, as it does not account for the added stuff, but whatever. &lt;a href=&quot;#fr-buffer-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-ir&quot;&gt;
&lt;p&gt;Not even close. &lt;a href=&quot;#fr-ir-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-niche&quot;&gt;
&lt;p&gt;To add insult to injury, &lt;code&gt;?u1&lt;&#x2F;code&gt; is not niche optimized and has a size of two bytes, despite it being only two bits of info. &lt;a href=&quot;#fr-niche-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Chapter 4: Logic</title>
        <published>2025-05-19T00:00:00+00:00</published>
        <updated>2025-05-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/paella/c4/"/>
        <id>https://ar-ms.me/paella/c4/</id>
        
        <content type="html" xml:base="https://ar-ms.me/paella/c4/">&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;paella&#x2F;c3&#x2F;&quot;&gt;Three chapters&lt;&#x2F;a&gt; out of who knows from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;norasandler.com&#x2F;2022&#x2F;03&#x2F;29&#x2F;Write-a-C-Compiler-the-Book.html&quot;&gt;Writing a C Compiler&lt;&#x2F;a&gt;. Time onto Chapter 4. Chapter 4 is about, let me check, &quot;logical and relational operators&quot;. Great. More operators.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lexer&quot;&gt;Lexer&lt;&#x2F;h2&gt;
&lt;p&gt;You would expect the lexer by now to be a boring done deal, and you would be right. However, this is &lt;em&gt;slightly&lt;&#x2F;em&gt; more interesting because I get to add more states to the state machine!&lt;&#x2F;p&gt;
&lt;p&gt;The tokens for today are the following: &lt;code&gt;!&lt;&#x2F;code&gt;, &lt;code&gt;&amp;amp;&amp;amp;&lt;&#x2F;code&gt;, &lt;code&gt;||&lt;&#x2F;code&gt;, &lt;code&gt;==&lt;&#x2F;code&gt;, &lt;code&gt;!=&lt;&#x2F;code&gt;, &lt;code&gt;&amp;lt;&lt;&#x2F;code&gt;, &lt;code&gt;&amp;gt;&lt;&#x2F;code&gt;, &lt;code&gt;&amp;lt;=&lt;&#x2F;code&gt;, and &lt;code&gt;&amp;gt;=&lt;&#x2F;code&gt;. As I am not supporting bitshift operations, I will consider those tokens (specifically &lt;code&gt;&amp;amp;&lt;&#x2F;code&gt; and &lt;code&gt;|&lt;&#x2F;code&gt;) a failure state. The tests will not have them, either way.&lt;&#x2F;p&gt;
&lt;p&gt;Adding the token tags is straightforward. The &lt;code&gt;State&lt;&#x2F;code&gt; enum however, should have a new state for every partial application. This is the new &lt;code&gt;State&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; State&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    start,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    identifier,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    int,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    hyphen,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; new&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bang,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ambersand,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pipe,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    equals,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    lesser_than,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    greater_than,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The character in which the tokenizer enters these states is, I think, self explanatory. This, for example, is &lt;code&gt;pipe&lt;&#x2F;code&gt;, and &lt;code&gt;lesser_than&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.start&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (self.buffer[self.index]) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; snip --&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;#39;|&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; continue&lt;&#x2F;span&gt;&lt;span&gt; :state .pipe,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;#39;&amp;lt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; continue&lt;&#x2F;span&gt;&lt;span&gt; :state .lesser_than,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; snip --&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.pipe&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    self.index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (self.buffer[self.index]) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;#39;|&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            self.index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            result.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .double_pipe;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; result.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .invalid,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.lesser_than&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    self.index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (self.buffer[self.index]) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;#39;=&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            self.index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            result.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .lesser_equals;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; result.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .lesser_then,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;parser&quot;&gt;Parser&lt;&#x2F;h2&gt;
&lt;p&gt;The parser is a relatively simpler affair. More binary operations with different precedence levels. None of them are right associative, so nothing but updating the AST and the various &lt;code&gt;switch&lt;&#x2F;code&gt; statements. Nothing much to write about.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;unit-tests&quot;&gt;Unit Tests&lt;&#x2F;h2&gt;
&lt;p&gt;To spice up this section, I have decided to take on writing unit tests for the parser. Zig has first class support for unit tests. Make a block titled &lt;code&gt;test&lt;&#x2F;code&gt; and the compiler sees it. The only problem is hooking it in the build system.&lt;&#x2F;p&gt;
&lt;p&gt;Back in chapter 2, I think, I rejigged the &lt;code&gt;zig build test&lt;&#x2F;code&gt; command to run the Book&#x27;s test suite. As in, it just compiles and installs the binary as normal, then runs a shell command. Zig&#x27;s built in testing support requires a different kind of wiring.&lt;&#x2F;p&gt;
&lt;p&gt;Thankfully, the default output with &lt;code&gt;zig init&lt;&#x2F;code&gt; contains all the necessary pieces, I can reuse those. One question remains is whether to tie them to the suit&#x27;s test suite, so both run with &lt;code&gt;zig build test&lt;&#x2F;code&gt;, or have it a separate command. I believe having it a separate command is best, to cut down on the, already slow, testing time.&lt;&#x2F;p&gt;
&lt;p&gt;I shall change the existing &lt;code&gt;test&lt;&#x2F;code&gt; command to &lt;code&gt;submit&lt;&#x2F;code&gt; (so I&#x27;d type &lt;code&gt;zig build submit&lt;&#x2F;code&gt;), and have the &lt;code&gt;test&lt;&#x2F;code&gt; command for unit tests. For reference, this is the old step after changing the name. (The block is organizational).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; `zig build submit` command&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; test_step&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.step(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;submit&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Run the Book&amp;#39;s test suite&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; subshells. how do they work.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; inner_command&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; std.mem.join(b.allocator,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;quot;..&#x2F;writing-a-c-compiler-tests&#x2F;test_compiler&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        b.pathJoin(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{ b.exe_dir,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;paella&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; std.mem.join(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            b.allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            b.args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; orelse&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; does this work like i think it does?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; test_command&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.addSystemCommand(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;        &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;arch&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;-x86_64&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;zsh&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;-c&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, inner_command },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    test_command.step.dependOn(b.getInstallStep());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    test_step.dependOn(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;test_command.step);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Copying from the default &lt;code&gt;build.zig&lt;&#x2F;code&gt; and trimming unnecessary things, I get this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; `zig build test` command&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; test_step&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.step(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;test&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Run unit tests&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; exe_unit_tests&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.addTest(.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .root_module&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; exe_mod,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; run_exe_unit_tests&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.addRunArtifact(exe_unit_tests);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    test_step.dependOn(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;run_exe_unit_tests.step);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And .. that should be it? To test whether the test command run, I shall write a &lt;code&gt;test&lt;&#x2F;code&gt; to test whether 2 + 2 equals 4 in &lt;code&gt;main.zig&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;test&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;test the test&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; std.testing.expect(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ok &lt;code&gt;zig build test&lt;&#x2F;code&gt; comes and goes and says nothing. Let&#x27;s see if it can detect a failure. I shall expect 2 + 2 does not equal 4.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;test&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;test the test&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; std.testing.expect(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And it fails. So our tests work! Putting it &lt;code&gt;parser.zig&lt;&#x2F;code&gt; however, does not seem to work. Tests pass no matter what I expect. What gives?&lt;&#x2F;p&gt;
&lt;p&gt;After asking around in the Zig discord, this is a known thing. Zig&#x27;s compiler is lazy, and does not look at functions not referenced from &lt;code&gt;main.zig&lt;&#x2F;code&gt;. But because the test executable does &lt;em&gt;not&lt;&#x2F;em&gt; run &lt;code&gt;fn main&lt;&#x2F;code&gt;, it does &lt;em&gt;not&lt;&#x2F;em&gt; see any modules that are referenced within &lt;code&gt;main.zig&lt;&#x2F;code&gt; but not referenced in &lt;code&gt;main.zig&lt;&#x2F;code&gt;&#x27;s &lt;em&gt;tests&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It is dumb as fuck, if you ask me. And honestly I cannot tell if this is a deliberate design decision or just a known bug. The solution is, well, to write a &lt;code&gt;test&lt;&#x2F;code&gt; block in &lt;code&gt;main.zig&lt;&#x2F;code&gt; that references the files in which I&#x27;d like to run tests.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-language-1&quot;&gt;&lt;a href=&quot;#fn-language&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; The most straightforward way to do this is this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;test&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  std.testing.refAllDeclsRecursive(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt;@This&lt;&#x2F;span&gt;&lt;span&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And now the tests in &lt;code&gt;parse.zig&lt;&#x2F;code&gt; pass and fail as expected. This is apparently a hack and not recommended. The recommended way is even more stupid looking, which only imports &lt;code&gt;parser.zig&lt;&#x2F;code&gt;, and I&#x27;d have to do it for every file and every sub import.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;test&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; parser;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Having gone that far, let&#x27;s actually write our unit test in &lt;code&gt;parse.zig&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;test&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;precedence 1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.testing;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;3 * 4 + 5;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; tokens&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; lexer.Tokenizer.init(src);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; a_a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.heap.ArenaAllocator.init(t.allocator);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; a_a.deinit();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; a_a.allocator();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(a,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;tokens,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; t.expect(result.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator&quot;&gt;* ==&lt;&#x2F;span&gt;&lt;span&gt; .binop_add);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; t.expectFmt(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;(+ (* 3 4) 5)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;{}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{result});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;My first drafts of the test failed because I was leaking memory, hence the adding an arena ceremony. It is a bit more ceremony than I expected, but it is fine. Who needs unit testing anyway? End to end testing is where it is at.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;internal-representation&quot;&gt;Internal Representation&lt;&#x2F;h2&gt;
&lt;p&gt;The IR this chapter is a lot more interesting than usual. Since &lt;code&gt;&amp;amp;&amp;amp;&lt;&#x2F;code&gt; and &lt;code&gt;||&lt;&#x2F;code&gt; are short circuting operators, it means now is the time have jumps and labels and &lt;code&gt;goto&lt;&#x2F;code&gt;s and jump-if-zeros. With conditionals, anything is possible.&lt;&#x2F;p&gt;
&lt;p&gt;the new instructions are a lot. Here is the new &lt;code&gt;ir.Instr&lt;&#x2F;code&gt;. You will note that there are no direct instructions for &lt;code&gt;and&lt;&#x2F;code&gt; and &lt;code&gt;or&lt;&#x2F;code&gt;.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-tacky-1&quot;&gt;&lt;a href=&quot;#fn-tacky&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Instr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ret: Value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    copy: Unary,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    jump: [:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    jump_z: JumpIf,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    jump_nz: JumpIf,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    label: [:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    unop_neg: Unary,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    unop_not: Unary,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    unop_lnot: Unary,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- new&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    binop_add: Binary,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    binop_sub: Binary,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    binop_mul: Binary,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    binop_div: Binary,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    binop_rem: Binary,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    binop_eql: Binary,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    binop_neq: Binary,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    binop_lt: Binary,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    binop_le: Binary,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    binop_gt: Binary,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    binop_ge: Binary,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;    pub const&lt;&#x2F;span&gt;&lt;span&gt; Unary&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        src: Value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        dst: Value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;        pub fn&lt;&#x2F;span&gt;&lt;span&gt; init(src: Value, dst: Value) &lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt;@This&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; .{ .src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; src, .dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dst };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;    pub const&lt;&#x2F;span&gt;&lt;span&gt; Binary&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        src1: Value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        src2: Value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        dst: Value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;        pub fn&lt;&#x2F;span&gt;&lt;span&gt; init(src1: Value, src2: Value, dst: Value) &lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt;@This&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; .{ .src1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; src1, .src2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; src2, .dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dst };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;    pub const&lt;&#x2F;span&gt;&lt;span&gt; JumpIf&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cond: Value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        target: [:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;        pub fn&lt;&#x2F;span&gt;&lt;span&gt; init(cond: Value, target: [:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt;@This&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; .{ .cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cond, .target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; target };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;jump&lt;&#x2F;code&gt; instruction is straight up &lt;code&gt;goto&lt;&#x2F;code&gt;. &lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-goto-1&quot;&gt;&lt;a href=&quot;#fn-goto&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; The two conditional jumps simply evaluate their &lt;code&gt;cond&lt;&#x2F;code&gt; operand, and act accordingly. One of them is enough, but it is apparently simpler to do it this way. These conditional jumps are the backbone of &lt;code&gt;&amp;amp;&amp;amp;&lt;&#x2F;code&gt; and &lt;code&gt;||&lt;&#x2F;code&gt;, and the ternary operator come chapter 6.&lt;&#x2F;p&gt;
&lt;p&gt;The operations other than &lt;code&gt;&amp;amp;&amp;amp;&lt;&#x2F;code&gt; and &lt;code&gt;||&lt;&#x2F;code&gt; have a straightforward impl similar to the previous ones. It is &lt;code&gt;&amp;amp;&amp;amp;&lt;&#x2F;code&gt; and &lt;code&gt;||&lt;&#x2F;code&gt; that depend on the new instructions. This is the implementation of &lt;code&gt;&amp;amp;&amp;amp;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.binop_and&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; false_label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.make_temporary(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;false_and&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; end_label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.make_temporary(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;end_and&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.make_temporary(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;dst_and&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; src1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(bp, b.@&amp;quot;0&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .jump_z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(src1, false_label) });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; src2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(bp, b.@&amp;quot;1&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .jump_z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(src2, false_label) });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; dst : ir.Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .variable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; result };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .copy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; },dst ) });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .jump&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; end_label });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; false_label });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .copy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; }, dst) });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; end_label });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; dst;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let me walk this one bit by bit, just to make sure I understand it. &lt;code&gt;&amp;amp;&amp;amp;&lt;&#x2F;code&gt; short circuits if the first operand is false, or zero.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;evaluate &lt;code&gt;src1&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;if &lt;code&gt;src1&lt;&#x2F;code&gt; is zero, the result is zero, and we jump to where &lt;code&gt;result&lt;&#x2F;code&gt; is set to zero.&lt;&#x2F;li&gt;
&lt;li&gt;if not, then we evaluate &lt;code&gt;src2&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;if &lt;code&gt;src2&lt;&#x2F;code&gt; is zero, the result is zero, and we jump to where &lt;code&gt;result&lt;&#x2F;code&gt; is set to zero.&lt;&#x2F;li&gt;
&lt;li&gt;if not, then the result is one, and we jump to where the &lt;code&gt;result&lt;&#x2F;code&gt; is set to one.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;For &lt;code&gt;||&lt;&#x2F;code&gt; this would be the following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;evaluate &lt;code&gt;src1&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;if &lt;code&gt;src1&lt;&#x2F;code&gt; is one, the result is one, and we jump to where &lt;code&gt;result&lt;&#x2F;code&gt; is set to one.&lt;&#x2F;li&gt;
&lt;li&gt;if not, then we evaluate &lt;code&gt;src2&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;if &lt;code&gt;src2&lt;&#x2F;code&gt; is one, the result is one, and we jump to where &lt;code&gt;result&lt;&#x2F;code&gt; is set to one.&lt;&#x2F;li&gt;
&lt;li&gt;if not, then the result is zero, and we jump to where the &lt;code&gt;result&lt;&#x2F;code&gt; is set to zero.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Which means this should be our &lt;code&gt;||&lt;&#x2F;code&gt; IR generation.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.binop_or&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; true_label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.make_temporary(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;true_or&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; end_label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.make_temporary(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;end_or&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.make_temporary(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;dst_or&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; src1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(bp, b.@&amp;quot;0&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .jump_nz&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(src1, true_label) });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; src2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(bp, b.@&amp;quot;1&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .jump_nz&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(src2, true_label) });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; dst : ir.Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .variable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; result };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .copy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; }, dst) });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .jump&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; end_label });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; true_label });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .copy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; }, dst) });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{ .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; end_label });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; dst;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This should work.&lt;&#x2F;p&gt;
&lt;p&gt;This is the C file I am experimenting with this evening:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And this is the generated IR:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jnz 0 =&amp;gt; true_or.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jz  0 =&amp;gt; false_and.3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		div.6 &amp;lt;- 1 &#x2F; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jz  div.6 =&amp;gt; false_and.3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		dst_and.5 &amp;lt;- 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jump =&amp;gt; end_and.4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		=&amp;gt; false_and.3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		dst_and.5 &amp;lt;- 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		=&amp;gt; end_and.4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jnz dst_and.5 =&amp;gt; true_or.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		dst_or.2 &amp;lt;- 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		jump =&amp;gt; end_or.1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		=&amp;gt; true_or.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		dst_or.2 &amp;lt;- 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		=&amp;gt; end_or.1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ret dst_or.2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Eh. This looks wrong at first glance, but working through it, it seems to be .. fine? The division by 0 is immediately jumped over to greener pastures and the function returns 0.&lt;&#x2F;p&gt;
&lt;p&gt;The tests pass, which means I have corrected all the typos and exhausted all the switches and there are no panics. Verification of the logic will come later.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;assembly-generation&quot;&gt;Assembly Generation&lt;&#x2F;h2&gt;
&lt;p&gt;The Book goes into a lengthy explanation of the &quot;flags&quot; mechanism in c86 assembly, in addition with the first brush with Undefined Behaviour. No point in repeating that here, go read the book. I just want to write code.&lt;&#x2F;p&gt;
&lt;p&gt;The new Assembly AST includes new assembly instructions, as well as &lt;code&gt;cond_code&lt;&#x2F;code&gt;s: the various flags that will be set and unset depending on given comparisons. These are kinda free floating right now. Maybe I will stuff them within the &lt;code&gt;Instr&lt;&#x2F;code&gt; namespace later.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; CondCode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; { e, ne, g, ge, l, le };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s it. The rest comes when adding doubles and floats and nasty other stuff. And here are the new instructions:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Instr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; snip --&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cmp: Mov,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    jmp: [:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    jmp_cc:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; { CondCode, [:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    set_cc:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; { CondCode, Operand },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    label: [:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; snip --&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;cmp&lt;&#x2F;code&gt; just uses the &lt;code&gt;Mov&lt;&#x2F;code&gt; struct, which is really an &lt;code&gt;Operand&lt;&#x2F;code&gt; tuple. The other tuples are not reused enough for me to give them a name (yet?).&lt;&#x2F;p&gt;
&lt;p&gt;Then comes the conversion between the IR and the Assembly.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; instr_to_asm(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    instr: ir.Instr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;[]assembly.Instr {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (instr) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; snip==&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .unop_lnot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value_to_asm(u.src);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value_to_asm(u.dst);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return try&lt;&#x2F;span&gt;&lt;span&gt; alloc.dupe(assembly.Instr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .cmp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .imm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; }, src) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .imm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; }, dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .set_cc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .e, dst } },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; snip --&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .binop_eql, .binop_neq, .binop_lt, .binop_le, .binop_gt, .binop_ge&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; src1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value_to_asm(b.src1);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; src2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value_to_asm(b.src2);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value_to_asm(b.dst);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; cc: assembly.Instr.CondCode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (instr) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .binop_eql&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .e,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .binop_neq&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .ne,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .binop_lt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .l,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .binop_le&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .le,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .binop_gt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .g,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .binop_ge&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .ge,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-statement z-zig&quot;&gt; unreachable&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return try&lt;&#x2F;span&gt;&lt;span&gt; alloc.dupe(assembly.Instr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .cmp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(src2, src1) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .imm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; }, dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .set_cc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ cc, dst } },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return try&lt;&#x2F;span&gt;&lt;span&gt; alloc.dupe(assembly.Instr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .label&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; s },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .jump&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return try&lt;&#x2F;span&gt;&lt;span&gt; alloc.dupe(assembly.Instr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .jmp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; s },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .jump_z, .jump_nz&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;j&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return try&lt;&#x2F;span&gt;&lt;span&gt; alloc.dupe(assembly.Instr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .cmp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .imm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; }, value_to_asm(j.cond)) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .jmp_cc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (instr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .jump_z) .e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; .ne, j.target } },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .copy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return try&lt;&#x2F;span&gt;&lt;span&gt; alloc.dupe(assembly.Instr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                value_to_asm(u.src),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                value_to_asm(u.dst),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            ) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The rest of replacing pseudo registers is fairly mechanical and boring and I hate it. Here is the current &lt;code&gt;fixup_instrs&lt;&#x2F;code&gt;, just to see what it has grown into in three short chapters.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; fixup_instrs(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    prgm:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;assembly.Prgm,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; out: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(assembly.Instr) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; .initCapacity(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        prgm.func_def.instrs.capacity,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        std.mem.swap(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(assembly.Instr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;            &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;out,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;            &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;prgm.func_def.instrs,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        out.deinit(alloc);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; State&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        start,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mov_stack_stack,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cmp_stack_stack,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cmp_to_imm,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        add_stack_stack,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        sub_stack_stack,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mul_to_stack,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        idiv_const,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; (prgm.func_def.instrs.items) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;instr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        state:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (State.start) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .start&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (instr) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (m.src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; m.dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .stack)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .mov_stack_stack&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .cmp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (m.src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; m.dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .stack)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .cmp_stack_stack&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else if&lt;&#x2F;span&gt;&lt;span&gt; (m.dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .imm)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .cmp_to_imm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .add&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (m.src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; m.dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .stack)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .add_stack_stack&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (m.src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; m.dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .stack)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .sub_stack_stack&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (m.dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .stack)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .mul_to_stack&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .idiv&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (o&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .imm)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .idiv_const&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .mov_stack_stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.mov.src, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }, instr.mov.dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .cmp_stack_stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.cmp.src, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .cmp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }, instr.cmp.dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .cmp_to_imm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.cmp.dst, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R11 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .cmp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.cmp.src, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R11 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .add_stack_stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.add.src, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .add&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }, instr.add.dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .sub_stack_stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.sub.src, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }, instr.sub.dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .mul_to_stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.mul.dst, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R11 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.mul.src, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R11 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R11 }, instr.mul.dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .idiv_const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.idiv, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R11 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .idiv&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R11 } },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .legal&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.append(alloc, instr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I kind of like how it looks, in that there is a clear listing of each illegal state, and a direct transformation from a legal form to the other, and the discovery code is split up from the replacement code. It might even be easier to review? I do not know.&lt;&#x2F;p&gt;
&lt;p&gt;All tests pass. Even the earlier dividng by zero one. If you are curious, here is the generated final assembly.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.globl _main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;_main:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	pushq   %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	movq&lt;&#x2F;span&gt;&lt;span&gt;    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;, %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	subq    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$12&lt;&#x2F;span&gt;&lt;span&gt;, %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$0&lt;&#x2F;span&gt;&lt;span&gt;, %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r11d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	cmpl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$0&lt;&#x2F;span&gt;&lt;span&gt;, %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r11d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	jne&lt;&#x2F;span&gt;&lt;span&gt;     .Ltrue_or&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$0&lt;&#x2F;span&gt;&lt;span&gt;, %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r11d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	cmpl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$0&lt;&#x2F;span&gt;&lt;span&gt;, %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r11d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	je&lt;&#x2F;span&gt;&lt;span&gt;      .Lfalse_and&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$1&lt;&#x2F;span&gt;&lt;span&gt;, %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;eax&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	cdq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$0&lt;&#x2F;span&gt;&lt;span&gt;, %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r11d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	idivl   %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r11d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;eax&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	cmpl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$0&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	je&lt;&#x2F;span&gt;&lt;span&gt;      .Lfalse_and&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$1&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	jmp&lt;&#x2F;span&gt;&lt;span&gt;    .Lend_and&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Lfalse_and.3:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$0&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Lend_and.4:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	cmpl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$0&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	jne&lt;&#x2F;span&gt;&lt;span&gt;     .Ltrue_or&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$0&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	jmp&lt;&#x2F;span&gt;&lt;span&gt;    .Lend_or&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Ltrue_or.0:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$1&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Lend_or.1:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;), %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;eax&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	movq&lt;&#x2F;span&gt;&lt;span&gt;    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rbp&lt;&#x2F;span&gt;&lt;span&gt;, %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	popq    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There is one complication. Even tho the tests passed, while reviewing through the book I realized I am supposed to emit different names for the registers when they are in the &lt;code&gt;set_cc&lt;&#x2F;code&gt; instruction. Since the tests passed I can just .. ignore this? But let&#x27;s do it.&lt;&#x2F;p&gt;
&lt;p&gt;I am going to abuse the &lt;code&gt;width&lt;&#x2F;code&gt; property (same one I used to get indentation) to pass in the register&#x27;s width. For reference, this the current emission&#x2F;printing code for &lt;code&gt;set_cc&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.set_cc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;set{s:&amp;lt;7}{gen}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt;@tagName&lt;&#x2F;span&gt;&lt;span&gt;(s.@&amp;quot;0&amp;quot;), s.@&amp;quot;1&amp;quot; }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Fairly straightforward and avoids special formatting logic for &lt;code&gt;CondCode&lt;&#x2F;code&gt;: just use the tag name! The &lt;code&gt;:_&amp;lt;7&lt;&#x2F;code&gt; syntax is how you&#x27;re &lt;em&gt;supposed&lt;&#x2F;em&gt; to use the &lt;code&gt;width&lt;&#x2F;code&gt; property, by passing optional padding.&lt;&#x2F;p&gt;
&lt;p&gt;For the Operand, all the change needed here is to change &lt;code&gt;{gen}&lt;&#x2F;code&gt; to &lt;code&gt;{gen:1}&lt;&#x2F;code&gt;, passing a width of &lt;code&gt;1&lt;&#x2F;code&gt; into the downstream formatter.&lt;&#x2F;p&gt;
&lt;p&gt;In the &lt;code&gt;Operand&lt;&#x2F;code&gt; formatter, this is the Register printing code:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (r) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .AX&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%eax&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .DX&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%edx&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .R10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%r10d&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .R11&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%r11d&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And this is when a conditional for &lt;code&gt;width == 1&lt;&#x2F;code&gt; is added. I am treating the default value as before.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (options.width&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;switch&lt;&#x2F;span&gt;&lt;span&gt; (r) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .AX&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%a1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .DX&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%d1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .R10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%r10b&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .R11&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%r11b&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;} &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else switch&lt;&#x2F;span&gt;&lt;span&gt; (r) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .AX&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%eax&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .DX&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%edx&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .R10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%r10d&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .R11&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;%r11d&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;All tests continue to pass. So that is nice I guess.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;&#x2F;h2&gt;
&lt;p&gt;Not much really. This is a fairly mechanical chapter. The new info I had already learned when going through the Book the first time. Maybe I learned not to target x86 assembly directly for my own language. Why not target &lt;code&gt;wasm&lt;&#x2F;code&gt;? It does not have &lt;code&gt;goto&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-language&quot;&gt;
&lt;p&gt;Yet another point for debugging your language knowledge. And do not tell me this is not actually part of the language. &lt;a href=&quot;#fr-language-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-tacky&quot;&gt;
&lt;p&gt;If I were developing a compiler for a language other than C, say &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;odin-lang.org&quot;&gt;Odin&lt;&#x2F;a&gt;, this is probably where I&#x27;d diverge from this Book on the IR. So early. But it seems annoying to me to encode the &lt;code&gt;goto&lt;&#x2F;code&gt; logic straight in my implementation. I guess it depends on the backend. &lt;a href=&quot;#fr-tacky-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-goto&quot;&gt;
&lt;p&gt;This is necessary because C, and x86 assembly for that matter, has &lt;code&gt;goto&lt;&#x2F;code&gt;, which is implemented later in the book, and it fits the C semantics of &lt;code&gt;switch&lt;&#x2F;code&gt;. So implementing &lt;code&gt;goto&lt;&#x2F;code&gt; is the least friction option. &lt;code&gt;wasm&lt;&#x2F;code&gt;, however, does not have &lt;code&gt;goto&lt;&#x2F;code&gt;, and uses structured code instead with &lt;code&gt;break&lt;&#x2F;code&gt; out of blocks. I am not actually sure how C&#x27;s &lt;code&gt;goto&lt;&#x2F;code&gt; compiles to &lt;code&gt;wasm&lt;&#x2F;code&gt;. Investigation is required. &lt;a href=&quot;#fr-goto-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Chapter 3: Binary</title>
        <published>2025-05-17T00:00:00+00:00</published>
        <updated>2025-05-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/paella/c3/"/>
        <id>https://ar-ms.me/paella/c3/</id>
        
        <content type="html" xml:base="https://ar-ms.me/paella/c3/">&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;paella&#x2F;c2&#x2F;&quot;&gt;Two chapters&lt;&#x2F;a&gt; of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;norasandler.com&#x2F;2022&#x2F;03&#x2F;29&#x2F;Write-a-C-Compiler-the-Book.html&quot;&gt;Writing a C Compiler&lt;&#x2F;a&gt; done, many more to go, and it is time to implement binary expressions. But before I get into that, let me rant a bit about Zig.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-war-against-tabs&quot;&gt;The War Against Tabs&lt;&#x2F;h2&gt;
&lt;p&gt;Zig&#x27;s grammar does not tolerate the tab character anywhere in the file. This is unfortunate, as I like tabs. With source code, it is whatever, as &lt;code&gt;zig fmt&lt;&#x2F;code&gt; takes care of it, but can I please type my tabs in multiline string literals please?&lt;&#x2F;p&gt;
&lt;p&gt;I like to indent the output, whether it is the parser&#x27;s debugging output or the final assembly output, with tabs. It just makes sense. It is simpler conceptually to type one tab twice for the second level of indentation than to type a space 4 or 8 or 16 times. Put a tab, and let the user choose the preferred tab width.&lt;&#x2F;p&gt;
&lt;p&gt;But Zig&#x27;s grammar will have none of it. There can be no tab characters in the file (albeit it is tolerated a bit at indentation before &lt;code&gt;zig fmt&lt;&#x2F;code&gt; gets rid of it all.) This puts me in a dilemma. Consider this piece of code for emitting the &lt;code&gt;ret&lt;&#x2F;code&gt; instruction.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.writeAll(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;movq    %rbp, %rsp&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; ++&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;popq    %rbp&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; ++&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ret&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Reasonable, right? But &lt;code&gt;zig fmt&lt;&#x2F;code&gt; takes a machete to it, and they no longer nicely align.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.writeAll(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;movq    %rbp, %rsp&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; ++&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;popq    %rbp&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; ++&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ret&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The next reasonable solution is Zig&#x27;s rather clever and very nice multiline string literals. It is literally my favorite piece of syntax in Zig. So much more ergonomic and grokkable and understandable than Swift&#x27;s &lt;code&gt;&quot;&quot;&quot;&lt;&#x2F;code&gt; or Rust&#x27;s .. nothing. So naturally, I&#x27;d type it like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.writeAll(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    \\	movq    %rbp, %rsp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    \\	popq    %rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    \\	ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;    ^^ tab character here.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But this does not compile. Just does not. No tab characters allowed. One could argue that this decision reduces confusion over a variable width character like tab and hides the true intentions of whatever. &lt;strong&gt;I do not care&lt;&#x2F;strong&gt;. I want my tabs, goddammit. I would be ok with escaping tabs &lt;code&gt;&#x27;\t&#x27;&lt;&#x2F;code&gt;, but escapes do not work in multiline string literals. I could use &lt;code&gt;std.fmt.comptimePrint&lt;&#x2F;code&gt;, but that adds too much obfuscation and makes using the literals as the &lt;code&gt;fmt&lt;&#x2F;code&gt; arguments in &lt;code&gt;print&lt;&#x2F;code&gt; statements a lot more complicated. It is just annoying all around.&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, with some magic of &lt;code&gt;comptime&lt;&#x2F;code&gt;, and trial and error of Zig&#x27;s comptime rules, I came up with this &lt;del&gt;macro&lt;&#x2F;del&gt; function:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;inline fn&lt;&#x2F;span&gt;&lt;span&gt; indent(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;    comptime&lt;&#x2F;span&gt;&lt;span&gt; text: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;    comptime&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        var&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.mem.splitScalar(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, text,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;\n&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        var&lt;&#x2F;span&gt;&lt;span&gt; res: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt; u8 =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span&gt; (iter.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;line&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            res&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (line.len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; line[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;_&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                res&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; ++&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; ++&lt;&#x2F;span&gt;&lt;span&gt; line&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; ++&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                res&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; ++&lt;&#x2F;span&gt;&lt;span&gt; line&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; ++&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; res[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt; .. res.len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;inline fn&lt;&#x2F;code&gt; and the &lt;code&gt;comptime&lt;&#x2F;code&gt; block conspire together to make sure the body of this function always ever runs at &lt;code&gt;comptime&lt;&#x2F;code&gt; and never at run time, with no ceremony at the calling site.&lt;&#x2F;p&gt;
&lt;p&gt;The code itself is fairly straightforward: it separates the input by lines; adds a new line to all lines; and indents (with tabs!) any line that is not empty and does not start with &lt;code&gt;_&lt;&#x2F;code&gt;, for label and function names. This is specific to my use case, but it is fine. It is used like this.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.writeAll(indent(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    \\movq    %rbp, %rsp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    \\popq    %rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    \\ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Almost invisible, What&#x27;s better is that, since it returns a &lt;code&gt;comptime&lt;&#x2F;code&gt; known string, it can be used as the &lt;code&gt;fmt&lt;&#x2F;code&gt; argument in print functions, like the following snippet for the function&#x27;s prelude (which also showcases the &lt;code&gt;_&lt;&#x2F;code&gt; and the empty line rules).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(indent(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    \\.globl _{0s}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    \\_{0s}:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    \\pushq   %rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    \\movq    %rsp, %rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    \\&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;), .{self.name});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This prints, for name &lt;code&gt;&quot;main&quot;&lt;&#x2F;code&gt;, as intended, as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.globl _main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;_main:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	pushq   %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	movq&lt;&#x2F;span&gt;&lt;span&gt;    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;, %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So much pain would have been avoided if I could just type the damn byte. Now, back to business.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lexer&quot;&gt;Lexer&lt;&#x2F;h2&gt;
&lt;p&gt;Updating the lexer requires adding four new tokens, &lt;code&gt;+&lt;&#x2F;code&gt;, &lt;code&gt;*&lt;&#x2F;code&gt;, &lt;code&gt;&#x2F;&lt;&#x2F;code&gt;, and &lt;code&gt;%&lt;&#x2F;code&gt;. Where is subtraction, you say? We already lex it, dummy. A failure mode for &lt;code&gt;++&lt;&#x2F;code&gt;, like done in Chapter 2, is not necessary, because &lt;code&gt;1 ++ 2&lt;&#x2F;code&gt; would be rejected by the parser later anyway. And there is no ambiguity about prefix operators, as the &lt;code&gt;+&lt;&#x2F;code&gt; unary prefix operator is not implemented either. This makes things so considerably simple that I will not bother writing the update down. On to parsing, which is way more interesting.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;parser&quot;&gt;Parser&lt;&#x2F;h2&gt;
&lt;p&gt;As I am not using a parser combinator library this time, I have to actually get down and implement the legendary precedence claimbing&#x2F;pratt parsing algorithm. So, sleeves rolled. First to update the &lt;code&gt;Expr&lt;&#x2F;code&gt; type, splatting operations as before. &lt;code&gt;BinOp&lt;&#x2F;code&gt; is just a helper tuple alias.&lt;&#x2F;p&gt;
&lt;p&gt;One note: due to this helper type, the formatting for these is a bit more interesting than usual. Instead of creating an anonymous struct literal as second argument for &lt;code&gt;print&lt;&#x2F;code&gt; (as usual), I can just pass the &lt;code&gt;BinOp&lt;&#x2F;code&gt; payload, and it works.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    constant:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    unop_negate:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    unop_complement:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    binop_add: BinOp,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    binop_sub: BinOp,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    binop_mul: BinOp,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    binop_div: BinOp,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    binop_rem: BinOp,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;    pub const&lt;&#x2F;span&gt;&lt;span&gt; BinOp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; { &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span&gt; format(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @This&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;        comptime&lt;&#x2F;span&gt;&lt;span&gt; _: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _: std.fmt.FormatOptions,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        writer:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; anytype&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        switch&lt;&#x2F;span&gt;&lt;span&gt; (self) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{d}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{c}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F; RPN&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .unop_negate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{} --&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{e}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .unop_complement&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{} ~&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{e}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .binop_add&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{} {} +&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, b),&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- NOT `.{b}`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .binop_sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{} {} -&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, b),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .binop_mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{} {} *&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, b),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .binop_div&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{} {} &#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, b),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .binop_rem&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{} {} %&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, b),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is an article about me writing Zig, so I will not bore with yet another explanation of precedence climbing. Plenty of those online, and they are described in literally every compiler book.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-yard-1&quot;&gt;&lt;a href=&quot;#fn-yard&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; I am trying to write code here! Most of the work will be in the function &lt;code&gt;parse_expr&lt;&#x2F;code&gt;. Here is the current version.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt;!*&lt;&#x2F;span&gt;&lt;span&gt;ast.Expr {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; current&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (current.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; literal&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .number_literal&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; lit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.buffer[current.loc.start..current.loc.end];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; res&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; std.fmt.parseInt(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;u64&lt;&#x2F;span&gt;&lt;span&gt;, lit,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return try&lt;&#x2F;span&gt;&lt;span&gt; create(ast.Expr, alloc, .{ .constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; res });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; unary operations&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .hyphen&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; inner_exp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(alloc, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return try&lt;&#x2F;span&gt;&lt;span&gt; create(ast.Expr, alloc, .{ .unop_negate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; inner_exp });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .tilde&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; inner_exp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(alloc, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return try&lt;&#x2F;span&gt;&lt;span&gt; create(ast.Expr, alloc, .{ .unop_complement&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; inner_exp });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; groups&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .l_paren&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; inner_exp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(alloc, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; expect(.r_paren, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; inner_exp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.ExpectExpr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Well the first step is to rename this to &lt;code&gt;parse_factor&lt;&#x2F;code&gt; (as the book calls it, or &lt;code&gt;atom&lt;&#x2F;code&gt; is fine.). This is possible because unary operators have, almost, the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.cppreference.com&#x2F;w&#x2F;c&#x2F;language&#x2F;operator_precedence&quot;&gt;highest precedence in C&lt;&#x2F;a&gt;, and can &lt;em&gt;almost&lt;&#x2F;em&gt; be assumed to be part of the literal. In fact the only operators with higher precedence are postfix, so the grammar works out naturally. Updating the recursive calls it in order to, except that whatever is between the parenthesis is a full expression, and not just a factor, so it becomes this.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_factor(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt;!*&lt;&#x2F;span&gt;&lt;span&gt;ast.Expr {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; current&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (current.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .number_literal&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F; snip --&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .hyphen&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; inner_exp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_factor(alloc, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return try&lt;&#x2F;span&gt;&lt;span&gt; create(ast.Expr, alloc, .{ .unop_negate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; inner_exp });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .tilde&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; inner_exp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_factor(alloc, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return try&lt;&#x2F;span&gt;&lt;span&gt; create(ast.Expr, alloc, .{ .unop_complement&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; inner_exp });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .l_paren&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; inner_exp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(alloc, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; expect(.r_paren, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; inner_exp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.ExpectFactor,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The new &lt;code&gt;parse_expr&lt;&#x2F;code&gt; is where the magic happens. This is a first draft with no precedence for addition and subtraction:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt;!*&lt;&#x2F;span&gt;&lt;span&gt;ast.Expr {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_factor(alloc, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; next_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (next_token.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .plus&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; or&lt;&#x2F;span&gt;&lt;span&gt; next_token.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .hyphen) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; rhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_factor(alloc, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; new_lhs: ast.Expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (next_token.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .plus&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .binop_add&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ lhs, rhs } },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .hyphen&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .binop_sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ lhs, rhs } },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-statement z-zig&quot;&gt; unreachable&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; utils.create(ast.Expr, alloc, new_lhs);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        next_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; unwrapping is probably correct.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; lhs;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I was about to go on, but I realized there is a bug in this implementation: It always consumes one more token than needed. The book uses a helper function called &lt;code&gt;peek&lt;&#x2F;code&gt; that does &lt;em&gt;not&lt;&#x2F;em&gt; consume the token stream. This is fine as long as it is parsed in the same function, but it is &lt;em&gt;not&lt;&#x2F;em&gt; fine when it is used as a signal to &lt;em&gt;stop&lt;&#x2F;em&gt; parsing, and the next parser is expected to see it. Some sort of cache is required.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-zig_lexer-1&quot;&gt;&lt;a href=&quot;#fn-zig_lexer&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; Either in the tokenizer itself or external to it.&lt;&#x2F;p&gt;
&lt;p&gt;The tokenizer has two fields: &lt;code&gt;buffer&lt;&#x2F;code&gt;, which is the source code; and &lt;code&gt;index&lt;&#x2F;code&gt; which is a cursor over the source code. The simplest way to do a cache is to add a third field: &lt;code&gt;peeked&lt;&#x2F;code&gt; which would hold an optional token. But there is a funnier way: a &lt;code&gt;put_back&lt;&#x2F;code&gt; method.&lt;&#x2F;p&gt;
&lt;p&gt;See, every token has its span in the source code attached. So all I need to do, in theory, is just reset the index to that span&#x27;s start. This is more work for the tokenizer as it has to run the tokenizing state machine over it again, but it is funny enough and simple enough and does-not-change-how-the-rest-of-the-code-works enough that I am going to try it. It probably doesn&#x27;t even need to be a method, so &lt;code&gt;inline&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub inline fn&lt;&#x2F;span&gt;&lt;span&gt; put_back(self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Tokenizer, token: Token) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    self.index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; token.loc.start;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Done. I will put that in &lt;code&gt;parse_expr&lt;&#x2F;code&gt;. It probably works.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; snip --&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens.put_back(next_token);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; lhs;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;precedence&quot;&gt;Precedence&lt;&#x2F;h3&gt;
&lt;p&gt;The previous function parses only left-associative expressions with a single level of precedence. To parse proper PEMDAS, the precedence climbing algorithm should only parse expressions that are higher than a given, starting precedence, that is passed in as a parameter. Also, a precedence table is needed, which could be just baked into the binary.&lt;&#x2F;p&gt;
&lt;p&gt;This requires a small helper method on the &lt;code&gt;Tag&lt;&#x2F;code&gt; type to determine the precedence of each tag (and whether it is a binary operator to begin with). However, the changes to &lt;code&gt;parse_expr&lt;&#x2F;code&gt; are minimal, aside from adding a new parameter.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    min_prec:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- new parameter&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt;!*&lt;&#x2F;span&gt;&lt;span&gt;ast.Expr {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_factor(alloc, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; next_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (next_token.tag.binop_precedence()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;prec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; &amp;lt;- helper function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (prec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; min_prec) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; rhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(alloc, tokens, prec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; bin_op: ast.Expr.BinOp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ lhs, rhs };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; new_lhs: ast.Expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (next_token.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .plus&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .binop_add&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bin_op},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .hyphen&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .binop_sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bin_op},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .asterisk&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .binop_mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bin_op },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .f_slash&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .binop_div&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bin_op },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .percent&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .binop_rem&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bin_op },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-statement z-zig&quot;&gt; unreachable&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; utils.create(ast.Expr, alloc, new_lhs);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        next_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens.put_back(next_token);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; lhs;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And since everything is left associative, that&#x27;s it. It is done. Aside from Zig being unable to infer the error union type, which means annotating an actual error type.&lt;&#x2F;p&gt;
&lt;p&gt;This is the C file I am using as a scratch board this chapter:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; + -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And this is parsing output. I think I have come up with a better C syntax, don&#x27;t you think? RPN is great.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		RETURN 3 4 5 * + 4 -- +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Playing around a bit, let&#x27;s see how it looks as S-expressions. Much fun can be had.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		RETURN (+ (+ 3 (* 4 5)) (- 4))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Anyway, all chapter 3 parsing tests pass. So the cute &lt;code&gt;put_back&lt;&#x2F;code&gt; function works!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;having-fun-with-closures&quot;&gt;Having Fun with Closures&lt;&#x2F;h2&gt;
&lt;p&gt;Zig does not have closures or anonymous functions. If you want to build something of the sort, well, don&#x27;t. The language will fight you. But if you insist, it is a bit of fun.&lt;&#x2F;p&gt;
&lt;p&gt;Consider these couple of lines from &lt;code&gt;parse_expr&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;while&lt;&#x2F;span&gt;&lt;span&gt; (next_token.tag.binop_precedence()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;prec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (prec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; min_prec) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; snip --&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you have ever done functional programming, or just used Rust, you can immediately tell this is an &lt;code&gt;Option::filter&lt;&#x2F;code&gt;! (Maybe the Haskellers have another name for it.) So I figured I will try doing something similar here in Zig. I did not commit this code, as it replaces these two lines by two function definitions and one struct definition. It is a fun attempt and it worked and passed the tests as well. Might even compile to the same code, too.&lt;&#x2F;p&gt;
&lt;p&gt;So we need to define a filter over optionals. It basically checks if the payload satisfies a predicate. The most straightforward way to do it that&#x27;s generic enough is this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; filter(T:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;, opt:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt;T, closure:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; anytype&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;T {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; inner&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; opt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; orelse return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (closure.filter(inner)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt; opt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;closure&lt;&#x2F;code&gt; here is an &lt;code&gt;anytype&lt;&#x2F;code&gt; that has a &lt;code&gt;filter&lt;&#x2F;code&gt; method (which takes a &lt;code&gt;T&lt;&#x2F;code&gt; and returns &lt;code&gt;bool&lt;&#x2F;code&gt;). I do not like &lt;code&gt;anytype&lt;&#x2F;code&gt; but I am not committed enough to this bit to find a better abstraction. Now inside our function, or file, we define a &lt;code&gt;Closure&lt;&#x2F;code&gt; struct (or any other name, w&#x2F;e) like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Closure&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    min_prec:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span&gt; filter(self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @This&lt;&#x2F;span&gt;&lt;span&gt;(), item:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span&gt; self.min_prec;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then replace our &lt;code&gt;while&lt;&#x2F;code&gt; loop invocation with this beauty:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;                      here is the part that makes it a closure vv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;while&lt;&#x2F;span&gt;&lt;span&gt; (filter(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, next_token.tag.binop_precedence(), Closure{ .min_prec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; min_prec })) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;prec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; snip --&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And it works! This is almost how closures work in languages that have them. Now back to boring imperative code.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;intermediate-representation&quot;&gt;Intermediate Representation&lt;&#x2F;h2&gt;
&lt;p&gt;The IR pass here is fairly straightforward, and is a direct 1 to 1 translation from the AST. The code is short and very similar to the previousc chapter&#x27;s implementation of unary instructions that it is entirely uninteresting to write about again. Seriously, much of the same. The only difference is that the container type, &lt;code&gt;Binary&lt;&#x2F;code&gt;, has two &lt;code&gt;src&lt;&#x2F;code&gt; fields. Here it is next to chapter 2&#x27;s champion &lt;code&gt;Unary&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Unary&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    src: Value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    dst: Value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span&gt; init(src: Value, dst: Value) &lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt;@This&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; .{ .src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; src, .dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dst };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Binary&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    src1: Value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    src2: Value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    dst: Value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span&gt; init(src1: Value, src2: Value, dst: Value) &lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt;@This&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; .{ .src1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; src1, .src2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; src2, .dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dst };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Another thing I did to reduce the boilerplate in &lt;code&gt;ir_gen.zig&lt;&#x2F;code&gt;, which was to create a &lt;code&gt;Boilerplate&lt;&#x2F;code&gt; type, that holds all the pointers used in every function. This is the full type definition as of now.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Boilerplate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    strings:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;utils.StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    instrs:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(ir.Instr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; helper for everywhere&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span&gt; append(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @This&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        instr: ir.Instr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; self.instrs.append(self.alloc, instr);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; helpers for `expr_emit_ir`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span&gt; unary(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @This&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        e:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;        comptime&lt;&#x2F;span&gt;&lt;span&gt; prefix: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ir.Instr.Unary {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(self, e);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; dst_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; make_temporary(self.alloc, self.strings, prefix);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; dst: ir.Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .variable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dst_name };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; .init(src, dst);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span&gt; binary(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @This&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        b: ast.Expr.BinOp,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;        comptime&lt;&#x2F;span&gt;&lt;span&gt; prefix: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ir.Instr.Binary {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; src1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(self, b.@&amp;quot;0&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; src2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(self, b.@&amp;quot;1&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; dst_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; make_temporary(self.alloc, self.strings, prefix);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; dst: ir.Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .variable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dst_name };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; .init(src1, src2, dst);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And here is an example of it being used in the tiny &lt;code&gt;stmt_emit_ir&lt;&#x2F;code&gt;, which saved on so much parameter space!&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; stmt_emit_ir(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bp: Boilerplate,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    stmt:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Stmt,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (stmt.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .@&amp;quot;return&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; bp.append(.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(bp, e),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As a bonus, here is the IR generated for the sample C program above.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mul.0 &amp;lt;- 4 + 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		add.1 &amp;lt;- 3 + mul.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		neg.2 &amp;lt;- - 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		add.3 &amp;lt;- add.1 + neg.2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ret add.3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;assembly&quot;&gt;Assembly&lt;&#x2F;h2&gt;
&lt;p&gt;Addition, subtraction, and multiplication are straightforward implementations, as they have their corresponding assembly instructions. Integer division .. is not. The first task, as usual, is to update the assembly syntax tree to include all the new instructions, and two new registers.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Instr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mov: Mov,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ret:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; void&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; unary operations&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    neg: Operand,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    not: Operand,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; binary operations &#x2F;&#x2F; NEW&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    add: Mov,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    sub: Mov,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mul: Mov,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    idiv: Operand,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cdq:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; void&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; sign extension, don&amp;#39;t ask.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    allocate_stack:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; Mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; just a pair of operands&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        src: Operand,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        dst: Operand,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;        pub fn&lt;&#x2F;span&gt;&lt;span&gt; init(src: Operand, dst: Operand) &lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt;@This&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; .{ .src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; src, .dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dst };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Operand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    imm:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    reg: Register,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pseudo: [:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    stack:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; i64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;    pub const&lt;&#x2F;span&gt;&lt;span&gt; Register&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; { AX, DX, R10, R11 };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As it turned out, I did the basic work correctly last chapter. So the rest of this code turned out to be mechanical as well. These are the new cases in &lt;code&gt;instr_to_asm&lt;&#x2F;code&gt;. Since these commands have similar structure, they are implemented the same, with another internal &lt;code&gt;switch&lt;&#x2F;code&gt; for where they differ. It makes separating them easier later on.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.binop_add, .binop_sub, .binop_mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; src1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value_to_asm(b.src1);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; src2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value_to_asm(b.src2);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value_to_asm(b.dst);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return try&lt;&#x2F;span&gt;&lt;span&gt; alloc.dupe(assembly.Instr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(src1, dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        switch&lt;&#x2F;span&gt;&lt;span&gt; (instr) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .binop_add&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .add&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(src2, dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .binop_sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(src2, dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .binop_mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .{ .mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(src2, dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-statement z-zig&quot;&gt; unreachable&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.binop_div, .binop_rem&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; src1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value_to_asm(b.src1);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; src2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value_to_asm(b.src2);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value_to_asm(b.dst);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; dst_reg: assembly.Operand.Register&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (instr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .binop_div) .AX&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; .DX;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return try&lt;&#x2F;span&gt;&lt;span&gt; alloc.dupe(assembly.Instr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(src1, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .AX }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .cdq,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .{ .idiv&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; src2 },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dst_reg }, dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Replacing pseudo registers turned out to be straightforward too. I just had to add the &lt;code&gt;.add, .sub. .mul&lt;&#x2F;code&gt; to the &lt;code&gt;.mov&lt;&#x2F;code&gt; case (because they similarly take two operands); and &lt;code&gt;.idiv&lt;&#x2F;code&gt; to the unaries. This is the full function now.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; replace_pseudos(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    prgm:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;assembly.Prgm,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;assembly.Instr.Depth {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; pseudo_map: PseudoMap&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(alloc);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; pseudo_map.deinit();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; (prgm.func_def.instrs.items) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt;|*&lt;&#x2F;span&gt;&lt;span&gt;instr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        switch&lt;&#x2F;span&gt;&lt;span&gt; (instr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .mov, .add, .sub,.mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; m.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .init(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                try&lt;&#x2F;span&gt;&lt;span&gt; pseudo_to_stack(m.src,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;pseudo_map),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                try&lt;&#x2F;span&gt;&lt;span&gt; pseudo_to_stack(m.dst,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;pseudo_map),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .neg, .not , .idiv&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt;=&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; v.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; pseudo_to_stack(v.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;pseudo_map),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .ret, .cdq, .allocate_stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @intCast&lt;&#x2F;span&gt;&lt;span&gt;(pseudo_map.count() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Fixing illegal instructions is, perhaps, the most annoying part of the book. &lt;code&gt;idiv&lt;&#x2F;code&gt; cannot take a constand and the binaries cannot between two stac locations or whatever. It is a terribly unintresting part of the process and a hell to debug. Since I modeled it as a state machine, it might prove to be a bit more interesting than my Rust implementation. Here are the new fixups:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;idiv&lt;&#x2F;code&gt; cannot tak a constant. Change it to &lt;code&gt;mov&lt;&#x2F;code&gt; to &lt;code&gt;r10d&lt;&#x2F;code&gt; then &lt;code&gt;idiv r10d&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;add&lt;&#x2F;code&gt; and &lt;code&gt;sub&lt;&#x2F;code&gt; cannot be between two stack places. Change to &lt;code&gt;mov&lt;&#x2F;code&gt; then `add.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;imul&lt;&#x2F;code&gt; cannot have its destination be a stack place. Change to &lt;code&gt;mov&lt;&#x2F;code&gt; to &lt;code&gt;r11d&lt;&#x2F;code&gt;, then &lt;code&gt;imul&lt;&#x2F;code&gt;, then &lt;code&gt;mov&lt;&#x2F;code&gt; &lt;em&gt;back&lt;&#x2F;em&gt; from &lt;code&gt;r11d&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Do you see how mind numbing this is? Thankfully the state machine idea made copying and pasting previous code slightly trivial. I can perhaps even refactor it later, or not.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; State&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        start,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mov_stack_stack,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; new states&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        add_stack_stack,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        sub_stack_stack,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mul_to_stack,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        idiv_const,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; (prgm.func_def.instrs.items) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;instr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        state:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (State.start) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .start&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (instr) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (m.src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; m.dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .stack)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .mov_stack_stack&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;                &#x2F;&#x2F; new code starts here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .add&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (m.src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; m.dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .stack)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .add_stack_stack&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (m.src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; m.dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .stack)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .sub_stack_stack&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (m.dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .stack)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .mul_to_stack&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .idiv&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (o&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .imm)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .idiv_const&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .mov_stack_stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.mov.src, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }, instr.mov.dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F; new code starts Here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .add_stack_stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.add.src, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .add&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }, instr.add.dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .sub_stack_stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.sub.src, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }, instr.sub.dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .mul_to_stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.mul.dst, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R11 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.mul.src, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R11 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R11 }, instr.mul.dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .idiv_const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.idiv, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R11 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .idiv&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R11 } },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .legal&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.append(alloc, instr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Lots of copying and pasting. Maybe when I refactor this I can make the &lt;code&gt;State&lt;&#x2F;code&gt; enum carry payloads. The quicker I am out of assembly instructions fixup, however, the better. Assemblers should just be smarter.&lt;&#x2F;p&gt;
&lt;p&gt;All &lt;code&gt;codegen&lt;&#x2F;code&gt; tests. Pass, which here simply means it is failing when it should and is not hitting any panics in the passed codepaths. Always a plus. Filling up code emission would prove the pudding.&lt;&#x2F;p&gt;
&lt;p&gt;Thanks to the already implemented boilerplate last chapter, this is also a nice and straightforward task. And, silly typos aside, everything works smoothly and all tests pass. Here is the sample C program in &quot;&lt;code&gt;codegen&lt;&#x2F;code&gt;&quot; form, and final assembly form.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-folding-1&quot;&gt;&lt;a href=&quot;#fn-folding&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		allocate	16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 4 -&amp;gt; stack -4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -4 -&amp;gt; R11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mul	imm 5 -&amp;gt; R11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R11 -&amp;gt; stack -4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 3 -&amp;gt; stack -8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -4 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		add	R10 -&amp;gt; stack -8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	imm 4 -&amp;gt; stack -12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		neg	stack -12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -8 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	R10 -&amp;gt; stack -16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -12 -&amp;gt; R10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		add	R10 -&amp;gt; stack -16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov	stack -16 -&amp;gt; AX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.globl _main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;_main:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	pushq   %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	movq&lt;&#x2F;span&gt;&lt;span&gt;    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;, %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	subq    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$16&lt;&#x2F;span&gt;&lt;span&gt;, %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$4&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;), %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r11d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	imull   &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$5&lt;&#x2F;span&gt;&lt;span&gt;, %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r11d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r11d&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$3&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;), %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r10d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	addl    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r10d&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$4&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	negl    -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;), %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r10d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r10d&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;), %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r10d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	addl    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;r10d&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl    -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;(%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;span&gt;), %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;eax&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	movq&lt;&#x2F;span&gt;&lt;span&gt;    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rbp&lt;&#x2F;span&gt;&lt;span&gt;, %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rsp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	popq    %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rbp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;extra-credit&quot;&gt;Extra Credit&lt;&#x2F;h2&gt;
&lt;p&gt;The Book has an extra credit section for doing bitwise operations. I am skipping extra credit this run. They are useful and interesting but also more churn in the following chapters. This is the last time you will hear me talk of it.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Implemented a &lt;del&gt;macro&lt;&#x2F;del&gt; &lt;code&gt;comptime&lt;&#x2F;code&gt; function.&lt;&#x2F;li&gt;
&lt;li&gt;Closures at home.&lt;&#x2F;li&gt;
&lt;li&gt;Positive reinforcement of previous design decisions.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;hr &#x2F;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-yard&quot;&gt;
&lt;p&gt;Yet to see a compiler book explaining the shunting yard algorithm. &lt;a href=&quot;#fr-yard-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-zig_lexer&quot;&gt;
&lt;p&gt;The Zig tokenizer does not have a &lt;code&gt;peek&lt;&#x2F;code&gt; function. But the compiler just collects the entire token stream in an array before passing it to the parser. &lt;a href=&quot;#fr-zig_lexer-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-folding&quot;&gt;
&lt;p&gt;Now is not the time for constant folding and optimizations. These come in Part 3 of the Book. &lt;a href=&quot;#fr-folding-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Chapter 2: Unary</title>
        <published>2025-05-14T00:00:00+00:00</published>
        <updated>2025-05-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/paella/c2/"/>
        <id>https://ar-ms.me/paella/c2/</id>
        
        <content type="html" xml:base="https://ar-ms.me/paella/c2/">&lt;p&gt;So, with the &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;paella&#x2F;c1&#x2F;&quot;&gt;first chapter&lt;&#x2F;a&gt; of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;norasandler.com&#x2F;2022&#x2F;03&#x2F;29&#x2F;Write-a-C-Compiler-the-Book.html&quot;&gt;Writing a C Compiler&lt;&#x2F;a&gt; behind us, it is time to start on the second chapter: Unary Operators. But first, a word from &lt;code&gt;build.zig&lt;&#x2F;code&gt; land.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;running-the-tests-with-zig-build-test&quot;&gt;Running the tests with &lt;code&gt;zig build test&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The tests for this Book live in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nlsandler&#x2F;writing-a-c-compiler-tests&quot;&gt;their own repository&lt;&#x2F;a&gt;, which I have dutifully cloned and run tests in.&lt;&#x2F;p&gt;
&lt;p&gt;The process I followed to run the tests is fairly manual:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;navigate to the test directory.&lt;&#x2F;li&gt;
&lt;li&gt;run the command &lt;code&gt;arch -x86_64 zsh&lt;&#x2F;code&gt; (which I have cleverly aliased to &lt;code&gt;x86&lt;&#x2F;code&gt;). This runs a x86 version of &lt;code&gt;zsh&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;run the tests.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;When I was doing &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;asibahi&#x2F;trjm&quot;&gt;my Rust implementation&lt;&#x2F;a&gt;, I kept a terminal accessible with a global hotkey and I kept the inner shell running at all times.&lt;&#x2F;p&gt;
&lt;p&gt;With &lt;code&gt;build.zig&lt;&#x2F;code&gt;, I looked for a way to do that automatically. The &lt;code&gt;Build&lt;&#x2F;code&gt; object, which is central to &lt;code&gt;build.zig&lt;&#x2F;code&gt; has a nice &lt;code&gt;addSystemCommand&lt;&#x2F;code&gt; method, which I could use to run my stuff in. Now remained the problem of how to run the tests in the x86 shell.&lt;&#x2F;p&gt;
&lt;p&gt;My first thought was to have the command as &lt;code&gt;arch -x86_64 test_compiler ..etc&lt;&#x2F;code&gt; (&lt;code&gt;test_compiler&lt;&#x2F;code&gt; being the test script provided). While it worked, as in the tests for chapter 1 all ran fine, upon further reading I realized that the &lt;code&gt;arch&lt;&#x2F;code&gt; actually chooses which binary to run from a macOS Universal Binary. It has no effect on python scripts, and the simple tests on chapter 1 worked fine either way. So I asked around, and some kind soul pointed me to the right thing to search for: Subshells.&lt;&#x2F;p&gt;
&lt;p&gt;See, this might seem obvious if you&#x27;ve lived in Unix land all your life, but shells are applications too. You can pass command line arguments to them!! So, &lt;code&gt;bash -c &quot;echo foo&quot;&lt;&#x2F;code&gt;, runs &lt;code&gt;bash&lt;&#x2F;code&gt;, runs the command &lt;code&gt;echo foo&lt;&#x2F;code&gt; in &lt;code&gt;bash&lt;&#x2F;code&gt;, then exits. Perfect.&lt;&#x2F;p&gt;
&lt;p&gt;Putting these two together, this was the added bit to &lt;code&gt;build.zig&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; test_step&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.step(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;test&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Run tests&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; subshells. how do they work.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; inner_command&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; std.mem.join(b.allocator,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;..&#x2F;writing-a-c-compiler-tests&#x2F;test_compiler&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    b.pathJoin(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{ b.exe_dir,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;paella&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; std.mem.join(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        b.allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        b.args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; orelse&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; does this work like i think it does?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; test_command&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.addSystemCommand(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;    &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;arch&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;-x86_64&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;zsh&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;-c&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, inner_command },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;test_command.step.dependOn(b.getInstallStep());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;test_step.dependOn(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;test_command.step);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I am unreasonably happy with this. Using regular Zig standard library tools like &lt;code&gt;std.mem.join&lt;&#x2F;code&gt; allowed to join together the commands I am passing to the &lt;code&gt;zsh&lt;&#x2F;code&gt; subshell, and voila!!&lt;&#x2F;p&gt;
&lt;p&gt;Now the tests (say for chapter 1) can be ran &quot;simply&quot; with &lt;code&gt;zig build test -- --chapter 1&lt;&#x2F;code&gt;. Great success!&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lexer&quot;&gt;Lexer&lt;&#x2F;h2&gt;
&lt;p&gt;There are three tokens to add in this chapter: &lt;code&gt;~&lt;&#x2F;code&gt;, &lt;code&gt;-&lt;&#x2F;code&gt;, and &lt;code&gt;--&lt;&#x2F;code&gt;. The decrement operator is only being tokenized here to reject illegal C syntax like &lt;code&gt;return --2&lt;&#x2F;code&gt;, but otherwise will not be implemented.&lt;&#x2F;p&gt;
&lt;p&gt;So our &lt;code&gt;Tag&lt;&#x2F;code&gt; enum grows&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-main-1&quot;&gt;&lt;a href=&quot;#fn-main&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; to have these three tokens: &lt;code&gt;tilde, hyphen&lt;&#x2F;code&gt;. As I am not planning to implement the book&#x27;s extra credit this time around, I will just have the double hyphen lex into the &lt;code&gt;invalid&lt;&#x2F;code&gt; token. This would reject lexing valid code like &lt;code&gt;x--&lt;&#x2F;code&gt;, but I do not think this is going to be present into the test cases. We will see.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;State&lt;&#x2F;code&gt; enum is a bit more interesting. It cannot accept two consecutive hyphens, so seeing a hyphen would put it into the &lt;code&gt;hyphen&lt;&#x2F;code&gt; state, where if it sees another hyphen, it puts out &lt;code&gt;Tag.invalid&lt;&#x2F;code&gt;, or &lt;code&gt;Tag.hyphen&lt;&#x2F;code&gt; otherwise.&lt;&#x2F;p&gt;
&lt;p&gt;So, if the state is at &lt;code&gt;.start&lt;&#x2F;code&gt;, and the lexer encounters a &lt;code&gt;&#x27;-&#x27;&lt;&#x2F;code&gt; character, it just switches gear to the &lt;code&gt;.hyphen&lt;&#x2F;code&gt; state. Labelled &lt;code&gt;switch&lt;&#x2F;code&gt; in action. Then in there, triage happens. The code is honestly copied, again, from the Zig compiler, with adjustments.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;state:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (State.start) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .start&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (self.buffer[self.index]) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;#39;~&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            result.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .tilde;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            self.index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;#39;-&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; continue&lt;&#x2F;span&gt;&lt;span&gt; :state .hyphen,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; etc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .hyphen&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self.index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        switch&lt;&#x2F;span&gt;&lt;span&gt; (self.buffer[self.index]) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;#39;-&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; result.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .invalid,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; result.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .hyphen,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; etc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This should be it. Time to put the new testing command into action.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ran 43 tests in 5.432s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OK&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Both of them work. Time for AST and parsing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;parsing&quot;&gt;Parsing&lt;&#x2F;h2&gt;
&lt;p&gt;Changes to the AST are fairly minimal. There are two unary operations: negation, and complement. Instead of adding a separate &lt;code&gt;UnaryOp&lt;&#x2F;code&gt; enum as the Book suggests, I am going to embed them right into &lt;code&gt;Expr&lt;&#x2F;code&gt; as separate tags, updating the pretty printer while I am at it.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-json-1&quot;&gt;&lt;a href=&quot;#fn-json&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    constant:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    unop_negate:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    unop_complement:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span&gt; format(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @This&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;        comptime&lt;&#x2F;span&gt;&lt;span&gt; _: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _: std.fmt.FormatOptions,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        writer:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; anytype&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        switch&lt;&#x2F;span&gt;&lt;span&gt; (self) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{d}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{c}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .unop_negate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot; -{}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{e}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .unop_complement&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot; ~{}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{e}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Updating the parsing functions is a bit more involved, however. Now is the start of PEMDAS, and time to start our recursive descemt into madness.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-madness-1&quot;&gt;&lt;a href=&quot;#fn-madness&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; This is pretty much the same function provided in the book, except that the operation is chosen immediately.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt;!*&lt;&#x2F;span&gt;&lt;span&gt;ast.Expr {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; current&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.ExpectExpr;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (current.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .number_literal&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; lit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.buffer[current.loc.start..current.loc.end];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; res&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; std.fmt.parseInt(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;u64&lt;&#x2F;span&gt;&lt;span&gt;, lit,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F;         vvv this helper function just allocates and sets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return try&lt;&#x2F;span&gt;&lt;span&gt; create(ast.Expr, alloc, .{ .constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; res });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .hyphen&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; inner_exp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(alloc, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return try&lt;&#x2F;span&gt;&lt;span&gt; create(ast.Expr, alloc, .{ .unop_negate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; inner_exp });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .tilde&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; inner_exp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(alloc, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return try&lt;&#x2F;span&gt;&lt;span&gt; create(ast.Expr, alloc, .{ .unop_complement&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; inner_exp });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .l_paren&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; inner_exp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(alloc, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; expect(.r_paren, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; inner_exp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.ExpectExpr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now the parsing is done, but to test a small annoyance needs to be fixed. In &lt;code&gt;asm_gen.zig&lt;&#x2F;code&gt;, there is a switch over expressions, and it needs to handle the new modes, even tho it is not being called right now. This tedium and the need to repeat it for every step is partially why I stopped the Rust implementation. Adding a &lt;code&gt;else =&amp;gt; @panic(&quot;unimplemented&quot;),&lt;&#x2F;code&gt; to that &lt;code&gt;switch&lt;&#x2F;code&gt; smoothes things over for now.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ran 43 tests in 6.363s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OK&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Yuppee.&lt;&#x2F;p&gt;
&lt;p&gt;Last but not least, even though it is not needed for the first chapters, as the only identifier is &lt;code&gt;main&lt;&#x2F;code&gt;, I figured I&#x27;d try some &lt;code&gt;comptime&lt;&#x2F;code&gt; magic to improve my expectation experience. I changed &lt;code&gt;expect&lt;&#x2F;code&gt; a little bit so it returns a string when I am asking for an identifier, but &lt;code&gt;void&lt;&#x2F;code&gt; otherwise.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-matklad-1&quot;&gt;&lt;a href=&quot;#fn-matklad&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; expect(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;    comptime&lt;&#x2F;span&gt;&lt;span&gt; expected: lexer.Token.Tag,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (expected&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .identifier)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt;    void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (tokens.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;actual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (actual.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span&gt; expected)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (expected&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .identifier)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; tokens.buffer[actual.loc.start..actual.loc.end];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;intermediate-representation&quot;&gt;Intermediate Representation&lt;&#x2F;h2&gt;
&lt;p&gt;The Book uses its own version of Intermediate Representation, called &lt;code&gt;TACKY&lt;&#x2F;code&gt;. It is a variation of a popular IR strategy called &lt;em&gt;three-address code&lt;&#x2F;em&gt;, hence the name.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;TACKY&lt;&#x2F;code&gt; uses its own AST, and it would slot between the program&#x27;s AST and the assembly&#x27;s AST. This is the first pass. So many strings.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; std&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @import&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;std&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Prgm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    func_def:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;FuncDef,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; FuncDef&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; for similar reasons to its use in assembly AST&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    instrs: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(Inst),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Inst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ret: Value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; decided to splat the operator here, like discussed in chapter 1.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    unop_negate: Unary,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    unop_complement: Unary,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; to avoid excessive typing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;    pub const&lt;&#x2F;span&gt;&lt;span&gt; Unary&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        src: Value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        dst: Value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;        pub fn&lt;&#x2F;span&gt;&lt;span&gt; init(src: Value, dst: Value) &lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt;@This&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; .{ .src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; src, .dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dst };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    constant:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    variable: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The goal of this IR is to disentangle nested expressions by separating them into what is, at least in IR form, separate operations. This means that for an expression like &lt;code&gt;1 + 2 * 3&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-binary-1&quot;&gt;&lt;a href=&quot;#fn-binary&quot;&gt;5&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, it is transformed into the following representation:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tmp0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tmp1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; tmp0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt; tmp1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The Book provided &lt;code&gt;expr_emit_ir&lt;&#x2F;code&gt;, with my splatted data structures, looks like the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    expr:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    instrs:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(ir.Instr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;ir.Value {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (expr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; .{ .constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; c },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .unop_negate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(alloc, expr, instrs);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; dst_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; make_temporary(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;neg&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; dst: ir.Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .variable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dst_name };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; instrs.append(alloc, .{ .unop_negate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(src, dst) });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; dst;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .unop_complement&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(alloc, expr, instrs);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; dst_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; make_temporary(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;cml&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; dst: ir.Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .variable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dst_name };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; instrs.append(alloc, .{ .unop_complement&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(src, dst) });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; dst;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A bit repetitive, isn&#x27;t it? So I put together the repeated logic into its own function, &lt;code&gt;unary_helper&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; unary_helper(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    expr:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    instrs:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(ir.Instr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;    comptime&lt;&#x2F;span&gt;&lt;span&gt; prefix: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; { ir.Value, ir.Value } {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(alloc, expr, instrs);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; dst_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; make_temporary(alloc, prefix);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; dst: ir.Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .variable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dst_name };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ src, dst };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nothing fancy. &lt;code&gt;make_temporary&lt;&#x2F;code&gt; over here is just a function with an ever increasing static variable for creating always different variable names. However, I hit here the weirdest zig compile error I have seen, yet. &lt;code&gt;error: unable to resolve inferred error set&lt;&#x2F;code&gt;. What gives?&lt;&#x2F;p&gt;
&lt;p&gt;Turns out when two recursive functions call each other, both with an inferred error type, Zig throws in the towel. Swift would&#x27;ve never given up and compiled, eventually;&lt;&#x2F;p&gt;
&lt;p&gt;Apparently I had to specify the error type myself.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; helper_error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-type z-zig&quot;&gt; = error&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    MakeTemporary,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; return error value of `make_temporary`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    UnaryHelper,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;... and changed &lt;code&gt;unary_helper&lt;&#x2F;code&gt; to this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; unary_helper(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    expr:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    instrs:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(ir.Instr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;    comptime&lt;&#x2F;span&gt;&lt;span&gt; prefix: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) helper_error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; { ir.Value, ir.Value } {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(alloc, expr, instrs) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;catch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.UnaryHelper;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; dst_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; make_temporary(alloc, prefix);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; dst: ir.Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .variable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dst_name };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ src, dst };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And now it compiles. The rest of &lt;code&gt;ir_gen.zig&lt;&#x2F;code&gt;, is rahter a straightforward one to one between the two trees, and rather boring to implement. Instead, I will show you &lt;code&gt;make_temporary&lt;&#x2F;code&gt;. Zig has a weird way to define local static variables.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; make_temporary(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;    comptime&lt;&#x2F;span&gt;&lt;span&gt; prefix: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) helper_error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; zig static variables&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; coun&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        var&lt;&#x2F;span&gt;&lt;span&gt; ter:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt; usize =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.fmt.allocPrint(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (prefix.len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;temp&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; prefix&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; ++&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.{}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .{coun.ter},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;catch return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.MakeTemporary;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    coun.ter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; name;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;First of all, non-Atomic is fine. All this is single threaded anyway. Second of all, any &lt;em&gt;variable&lt;&#x2F;em&gt; directly declared in a &lt;code&gt;struct&lt;&#x2F;code&gt; scope is static. So if you need a local static variable you define a &lt;code&gt;struct&lt;&#x2F;code&gt; with a .. variable. This is exactly the same semantics as declaring a global variable (or at file scope) except the scope here is a lot smaller.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-struct-1&quot;&gt;&lt;a href=&quot;#fn-struct&quot;&gt;6&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; Mind bending a bit, but makes sense.&lt;&#x2F;p&gt;
&lt;p&gt;To save on pretty printing this time, I figured to try &lt;code&gt;std.json.stringify&lt;&#x2F;code&gt; to get the IR output. This is the C file I am working on. So small and non-threatening.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ~-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And this is the IR output:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;	&amp;quot;func_def&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;		&amp;quot;name&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;main&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;		&amp;quot;instrs&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;			&amp;quot;items&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;				{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;					&amp;quot;unop_negate&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;						&amp;quot;src&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;							&amp;quot;constant&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;						},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;						&amp;quot;dst&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;							&amp;quot;variable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;neg.0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;						}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;					}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;				},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;				{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;					&amp;quot;unop_complement&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;						&amp;quot;src&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;							&amp;quot;variable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;neg.0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;						},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;						&amp;quot;dst&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;							&amp;quot;variable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;cml.1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;						}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;					}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;				},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;				{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;					&amp;quot;ret&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;						&amp;quot;variable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;cml.1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;					}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;				}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;			&amp;quot;capacity&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Very longwinded, with some useless info. Why do I need to know the &lt;code&gt;ArrayListUnmanaged&lt;&#x2F;code&gt; capacity? Time to work on pretty printing and allocation bookkeeping. Not very interesting, to be honest, so I will skip writing about it.&lt;&#x2F;p&gt;
&lt;p&gt;Except for string interning. that is interesting.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;string-interning&quot;&gt;String Interning&lt;&#x2F;h2&gt;
&lt;p&gt;String interning is having a single storage for strings that are used throught the program. Keeping the source around is not enough, because of the new strings for the IR&#x27;s temporary variables. Giving ownership of the strings to &lt;code&gt;ir.Value&lt;&#x2F;code&gt; is &lt;em&gt;fine&lt;&#x2F;em&gt;, except it is really easy to double free the strings when cleaning up. In fact, I did that when I was trying to not implement the string interner, and Zig&#x27;s &lt;code&gt;DebugAllocator&lt;&#x2F;code&gt; dutifully caught it.&lt;&#x2F;p&gt;
&lt;p&gt;The basic idea behind the interner is to have all strings owned by one repository that you can free at once at the end. One can use an arena, but the interner&#x27;s structure is more efficient because it also avoids duplication of strings. It can be backed by a hashmap, so it can also attach information to each string. All in all it is a useful memory and resource management technique.&lt;&#x2F;p&gt;
&lt;p&gt;The friendly people at the Zig discord, especially &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;InKryption&quot;&gt;InKryption&lt;&#x2F;a&gt; not only helped me out understand the data idea, bu actually provided me with a complete implementation.&lt;&#x2F;p&gt;
&lt;p&gt;It makes use of Zig&#x27;s, hoenstly weird, sentinel-terminated arrays: a generalization of C&#x27;s null-terminated strings.&lt;&#x2F;p&gt;
&lt;p&gt;The idea is as follows: a regular slice (say the &lt;code&gt;[]comst u8&lt;&#x2F;code&gt; we use and love) stores its length within it. It knows what length it is at all times. So if you read from it or iterate on it, it stops dutifully at the length it knows. A null-terminated string, however, would be&lt;code&gt; [:0]const u8&lt;&#x2F;code&gt;. When you read from it or iterate on it, it keeps going until it hits the &lt;code&gt;0&lt;&#x2F;code&gt;. (Obviously you can use any sentinel value but the &lt;code&gt;0&lt;&#x2F;code&gt; is very convenient for strings.)&lt;&#x2F;p&gt;
&lt;p&gt;So the String Interner keeps as its backing data a regular &lt;code&gt;ArrayListUnmanaged(u8)&lt;&#x2F;code&gt; that I have been using before. Say it is called &lt;code&gt;bytes&lt;&#x2F;code&gt;.) But for any new string in the application, it appends it to the ArrayList then adds &lt;code&gt;0&lt;&#x2F;code&gt; byte at the end. And I keep its &lt;em&gt;starting&lt;&#x2F;em&gt; index around. When I want to use it, I take slice like so &lt;code&gt;bytes[starting_idx..:0]&lt;&#x2F;code&gt; and voila .. I have a slice of my string.&lt;&#x2F;p&gt;
&lt;p&gt;The remaining pieces of the puzzle is two items in the Zig standard library: &lt;code&gt;StringIndexContext&lt;&#x2F;code&gt; and &lt;code&gt;StringIndexAdapter&lt;&#x2F;code&gt;. They&#x27;re specifically designed for this specific use case. Who knew?&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;code&gt;Context&lt;&#x2F;code&gt; in Zig&#x27;s hash maps is a simple enough idea. It just defines the &lt;code&gt;eql&lt;&#x2F;code&gt; and &lt;code&gt;hash&lt;&#x2F;code&gt; functions said hash map will use, with an optional backing data structe. An &lt;code&gt;Adapter&lt;&#x2F;code&gt; is used to override these two functions for speciifc operations. The &lt;code&gt;StringIndex&lt;&#x2F;code&gt; duo have slightly different implementation of the &lt;code&gt;eql&lt;&#x2F;code&gt; function, and if you&#x27;re curious you can check them out in the standard library&#x27;s code.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-adapters-1&quot;&gt;&lt;a href=&quot;#fn-adapters&quot;&gt;7&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Without further ado, here is the full &lt;code&gt;StringInterner&lt;&#x2F;code&gt; provided thankfully by InKryption. I honestly had to read multiple times to wrap my head around what&#x27;s going on, so I commented some parts of it.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; std&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @import&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;std&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; StringInterner&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bytes: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    map: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;HashMapUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Id,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt;        void&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        std.hash_map.StringIndexContext,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        std.hash_map.default_max_load_percentage,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; management&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;    pub const&lt;&#x2F;span&gt;&lt;span&gt; init: StringInterner&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .empty,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .map&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .empty,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span&gt; deinit(self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;StringInterner, allocator: std.mem.Allocator) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self.bytes.deinit(allocator);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self.map.deinit(allocator);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; type alias. store this in stuff.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;    pub const&lt;&#x2F;span&gt;&lt;span&gt; Idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-type z-integer z-zig&quot;&gt; = u32&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; checks if a string is in or not. returns ID&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span&gt; getIdx(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        string: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;Idx {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; self.map.getKeyAdapted(string, self.hmAdapter());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; get string from id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span&gt; getString(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        idx: Idx,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;[:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;self.map.containsContext(idx, self.hmCtx())) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; cast is necessary for type inference reasons.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; slice_sentinel: [:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt; u8 =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @ptrCast&lt;&#x2F;span&gt;&lt;span&gt;(self.bytes.items[idx..]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; std.mem.sliceTo(slice_sentinel,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; the insert function. returns aither an existing idx or a new idx.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span&gt; getOrPut(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        allocator: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        string: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) std.mem.Allocator.Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;Idx {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; reserves capacity in both the backing array and the map&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; self.bytes.ensureUnusedCapacity(allocator, string.len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; self.map.ensureUnusedCapacityContext(allocator,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;, self.hmCtx());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; getOrPut returns a reference to the key and the value. If it existed, they&amp;#39;re&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; valid pointers. If not, their contents are undefined waiting for you to fill them.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; gop&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; self.map.getOrPutAssumeCapacityAdapted(string, self.hmAdapter());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        gop.value_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; {};&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; this is void, but it can be anything!! note void is zero-width&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (gop.found_existing) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt; gop.key_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; unlikelt to hit that. the source files are tiny.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (self.bytes.items.len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; std.math.maxInt(Idx)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.OutOfMemory;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; new_idx: Idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @intCast&lt;&#x2F;span&gt;&lt;span&gt;(self.bytes.items.len);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; indertion happens here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self.bytes.appendSliceAssumeCapacity(string);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; don&amp;#39;t forget to append the null byte !!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        self.bytes.appendAssumeCapacity(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; update the map through the pointer.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        gop.key_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; new_idx;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; new_idx;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; helper functions to avoid a self referential struct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span&gt; hmCtx(self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; StringInterner) std.hash_map.StringIndexContext {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; .{ .bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;self.bytes };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span&gt; hmAdapter(self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; StringInterner) std.hash_map.StringIndexAdapter {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; .{ .bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;self.bytes };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I will currently use this structure as is, only changing the names to be &lt;code&gt;snake_case&lt;&#x2F;code&gt; as I cannot read &lt;code&gt;camelCase&lt;&#x2F;code&gt;. Later on I can use it to attach data to the strings. Fairly useful.&lt;&#x2F;p&gt;
&lt;p&gt;My first go at this was to replace every string with &lt;code&gt;StringInterner.Idx&lt;&#x2F;code&gt;. Just make sure to pass a pointer to the interner when constructing these structures.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Prgm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    func_def:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;FuncDef,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; FuncDef&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name: utils.StringInterner.Idx,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    instrs: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(Instr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; and so on.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;While this works and compiles fine, it turned out to be problematic when pretty printing. &lt;code&gt;Idx&lt;&#x2F;code&gt; is just a &lt;code&gt;u32&lt;&#x2F;code&gt; and stores no reference to the interner. And the &lt;code&gt;format&lt;&#x2F;code&gt; functions do not have an allocator or a user-space reference to use. So instead, I am changing the type to &lt;code&gt;[:0]const u8&lt;&#x2F;code&gt;, then storing slices from the interner rather than indices.&lt;&#x2F;p&gt;
&lt;p&gt;Then adjust our &lt;code&gt;ir_gen&lt;&#x2F;code&gt; functions to pass a pointer to the interner through all of them. That or creating a makeshift &lt;code&gt;Ctx&lt;&#x2F;code&gt; type. Time will tell. For an example, now, this the &lt;code&gt;unary_helper&lt;&#x2F;code&gt; mentioned earlier and the new &lt;code&gt;make_temporary&lt;&#x2F;code&gt;, with the new structure threaded in.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; unary_helper(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    interner:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;utils.StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    expr:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ast.Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    instrs:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(ir.Instr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;    comptime&lt;&#x2F;span&gt;&lt;span&gt; prefix: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) helper_error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; { ir.Value, ir.Value } {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; expr_emit_ir(alloc, interner, expr, instrs) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;catch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.UnaryHelper;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; dst_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; make_temporary(alloc, interner, prefix);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; dst: ir.Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{ .variable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dst_name };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ src, dst };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; make_temporary(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    interner:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;utils.StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;    comptime&lt;&#x2F;span&gt;&lt;span&gt; prefix: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) helper_error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;[:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; static&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        var&lt;&#x2F;span&gt;&lt;span&gt; counter:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt; usize =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.fmt.allocPrint(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (prefix.len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;temp&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; prefix&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; ++&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;.{}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .{static.counter},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;catch return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.MakeTemporary;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; alloc.free(name);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; name_idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; interner.get_or_put(alloc, name) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;catch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.MakeTemporary;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; name_res&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; interner.get_string(name_idx).&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;- unwrap optional&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    static.counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; name_res;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So this all compiles and runs and passes tests just fine. All is left is implementing the pretty printing myself, as the &lt;code&gt;json&lt;&#x2F;code&gt; module seemed to break for reasons I do not understand (related to the interner).&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-json_bug-1&quot;&gt;&lt;a href=&quot;#fn-json_bug&quot;&gt;8&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; The technique to do so was discussed in the Chapter 1 article, so no point in repeating it here. It is time to move on to the next section.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;codegen&quot;&gt;Codegen&lt;&#x2F;h2&gt;
&lt;p&gt;The first task here is almost invariably to update the assembly AST to include more instructions. Again deviating from the book, I will splat the unary operator into the instructions. This will totally bite me later. The updated parts of the new AST look as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Inst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mov: Mov,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ret:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; void&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; unary operations&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    neg: Operand,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    not: Operand,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    allocate_stack:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; i64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; same type as `.stack` below.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; Mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        src: Operand,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        dst: Operand,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;        pub fn&lt;&#x2F;span&gt;&lt;span&gt; init(src: Operand, dst: Operand) &lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt;@This&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; .{ .src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; src, .dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dst };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Operand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    imm:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    reg: Register,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    stack:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; i64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pseudo: [:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; these get replaced&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;    pub const&lt;&#x2F;span&gt;&lt;span&gt; Register&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; { AX, R10 };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Oh there is a string there. Our string interner will come in handy.&lt;&#x2F;p&gt;
&lt;p&gt;Another note: I am not perfectly happy with the way the book represents register. Because later in the book, when &lt;code&gt;long&lt;&#x2F;code&gt; and pointers are implemented, different names have to be chosen for each register, and I had to encode that info in the &lt;code&gt;Register&lt;&#x2F;code&gt; type itself, which led to weird amount of code duplications. I have not looked at how the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nlsandler&#x2F;nqcc2&quot;&gt;reference OCaml implementation&lt;&#x2F;a&gt; does it. But I will cross that bridge when I come to it. So far all registers are 32 bits wide.&lt;&#x2F;p&gt;
&lt;p&gt;Now &lt;code&gt;asm_gen.zig&lt;&#x2F;code&gt; is reworked to take the IR AST as input instead. This is almost a complete rewrite except for the first, trivial, &lt;code&gt;Prgm&lt;&#x2F;code&gt; transformation. Complicates the matter a bit is that IR instructions and Assembly instructions do not map 1 to 1, but each IR instruction can be one or more Assembly instructions. So I have to return a slice. Manual memory management strikes again.&lt;&#x2F;p&gt;
&lt;p&gt;It is easier to start from the bottom up. This is IR values to Assembly operands. No allocator needed! Just copy the string&#x27;s reference as is.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; value_to_asm(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    value: ir.Value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) assembly.Operand {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (value) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; .{ .imm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; c },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .variable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; .{ .pseudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; v },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And this is more involved &lt;code&gt;Instr&lt;&#x2F;code&gt; porter:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; instr_to_asm(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    instr: ir.Instr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;[]assembly.Instr {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (instr) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value_to_asm(v);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; alloc.dupe(assembly.Instr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(src, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .AX }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .ret,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; ret;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .unop_complement&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value_to_asm(u.src);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value_to_asm(u.dst);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; alloc.dupe(assembly.Instr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(src, dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .not&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dst },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; ret;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .unop_negate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value_to_asm(u.src);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; value_to_asm(u.dst);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; alloc.dupe(assembly.Instr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(src, dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .neg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dst },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; ret;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Not very DRY, and a lot is going on. Certainly a lot of (what is going to be very temporary) allocations. Returning pointers to stack space is a rookie mistake. (Thanks Rust!)&lt;&#x2F;p&gt;
&lt;p&gt;The classic solution to a lot of temporary allocations in similar programs is to use an arena allocator, and then free it all at once when the function is done. This would be set up from &lt;code&gt;func_def_to_asm&lt;&#x2F;code&gt;. So here is the first attempt at it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; func_def_to_asm(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    func_def: ir.FuncDef,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;assembly.FuncDef {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; arena_allocator&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.heap.ArenaAllocator.init(alloc);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; arena_allocator.deinit();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; arena&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; arena_allocator.allocator();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; instrs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(assembly.Instr).empty;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; (func_def.instrs.items) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;instr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; note the different allocators for each function.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; instr_to_asm(arena, instr);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; instrs.appendSlice(alloc, ret);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; func_def.name,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .instrs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instrs,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And finally &lt;code&gt;Prgm&lt;&#x2F;code&gt; is trivial.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; prgm_to_asm(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    prgm: ir.Prgm,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;assembly.Prgm {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; func_def&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; utils.create(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assembly.FuncDef,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; func_def_to_asm(alloc, prgm.func_def.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .func_def&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; func_def };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And the proof of the pudding is in the eating. But not before filling in all the &lt;code&gt;@panic(&quot;todo&quot;)&lt;&#x2F;code&gt;s and cleaning up the allocated memory. The code so far works and produces the expected result on the previously mentioned tiny C program, but codegen is not over yet.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fixing-up-instructions&quot;&gt;Fixing Up Instructions&lt;&#x2F;h2&gt;
&lt;p&gt;There are two final tasks before actually generating the assembly. First is to replace all them &lt;code&gt;.pseudo&lt;&#x2F;code&gt; operands with &lt;code&gt;.stack&lt;&#x2F;code&gt; operands. The Book used the &lt;code&gt;pseudo&lt;&#x2F;code&gt; operands as a placeholder, as the compiler does not have the stack info at hand yet. It needs to count the amount of intermediate, temporary variables, created during IR generation.&lt;&#x2F;p&gt;
&lt;p&gt;The second is to rewrite illegal assembly instructions, such as moving from a stack to a stack, into legal ones.&lt;&#x2F;p&gt;
&lt;p&gt;These are essentially additional compiler passes, and I am loath to do the same thing I did in my Rust implementation and stuff everything in one file. So a new directory is born, titled &lt;code&gt;asm_passes&lt;&#x2F;code&gt;, with two new Zig files in toe. If you are keeping track, this is my current folder structure.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&#x2F;src&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── asm_gen.zig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── asm_passes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── fixup.zig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   └── pseudos.zig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── assembly.zig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── ast.zig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── ir_gen.zig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── ir.zig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── lexer.zig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── main.zig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── parser.zig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;└── utils.zig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Most of them are self descriptive. &lt;code&gt;utils&lt;&#x2F;code&gt; is where the string interner definition lives and, currently, one &lt;code&gt;create&lt;&#x2F;code&gt; function, that allocates a value on the heap.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pseudoregisters&quot;&gt;Pseudoregisters&lt;&#x2F;h3&gt;
&lt;p&gt;This simply goes over the &lt;code&gt;instrs&lt;&#x2F;code&gt; array stored in &lt;code&gt;FuncDef&lt;&#x2F;code&gt; to change up the arrays. The interesting challenge here is maintaining a map from identifiers to stack offsets. Storing the strings as map keys is horribly wasteful, so the string interner&#x27;s &lt;code&gt;Idx&lt;&#x2F;code&gt; type is used instead, so it passes in.&lt;&#x2F;p&gt;
&lt;p&gt;I probably made this a lot harder for myself. I tried to implement my own hash map adapter type, then had a struggle with Zig&#x27;s syntax for references. Eventually, Good prevailed and the code was compiled.&lt;&#x2F;p&gt;
&lt;p&gt;The building block is this &quot;simple&quot; function, with a minimal amount of parameters. &lt;code&gt;getOrPut&lt;&#x2F;code&gt; is a standard library function that almost does what it says on the tin, but gives you pointers to place the key and value yourself as you please. I opted to use a managed (not &lt;code&gt;Unmanaged&lt;&#x2F;code&gt;) hash map here to spare myself an allocator parameter. I could shave off &lt;code&gt;strings&lt;&#x2F;code&gt; too if I manage to figure out how &lt;code&gt;Context&lt;&#x2F;code&gt; works.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-stringhashmap-1&quot;&gt;&lt;a href=&quot;#fn-stringhashmap&quot;&gt;9&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; pseudo_to_stack(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    op: assembly.Operand,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    strings:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;utils.StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    map:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;AutoHashMap&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        utils.StringInterner.Idx,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assembly.Operand.StackDepth,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;assembly.Operand {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; static&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        var&lt;&#x2F;span&gt;&lt;span&gt; counter: assembly.Operand.StackDepth&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (op) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .reg, .imm, .stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; op,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .pseudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; strings.get_idx(name).&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; gop&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; map.getOrPut(idx);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (gop.found_existing) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span&gt; .{ .stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; gop.value_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                static.counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                gop.key_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; idx;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                gop.value_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; static.counter;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span&gt; .{ .stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; gop.value_ptr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The public facing function that runs on &lt;code&gt;assembly.Prgm&lt;&#x2F;code&gt; comes next. The &lt;code&gt;&amp;amp;&lt;&#x2F;code&gt; and &lt;code&gt;*&lt;&#x2F;code&gt; and &lt;code&gt;.*&lt;&#x2F;code&gt; sprinkled over the loop&#x27;s variables took a lot of trial and error and Zig discord help to get right. But the shared payload between &lt;code&gt;.neg&lt;&#x2F;code&gt; and &lt;code&gt;.not&lt;&#x2F;code&gt; does not to be duplicated.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; replace_pseudos(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    strings:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;utils.StringInterner,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    prgm:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;assembly.Prgm,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; pseudo_map: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;AutoHashMap&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        utils.StringInterner.Idx,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assembly.Operand.StackDepth,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .init(alloc);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; pseudo_map.deinit();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; (prgm.func_def.instrs.items) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt;|*&lt;&#x2F;span&gt;&lt;span&gt;instr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;   ^ no address operator as it is already a slice&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        switch&lt;&#x2F;span&gt;&lt;span&gt; (instr.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;                &#x2F;&#x2F;   ^ this was the tricky one to find&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;                const&lt;&#x2F;span&gt;&lt;span&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; pseudo_to_stack(m.src, strings,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;pseudo_map);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;                const&lt;&#x2F;span&gt;&lt;span&gt; dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; pseudo_to_stack(m.dst, strings,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;pseudo_map);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                m.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .init(src, dst);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .neg, .not&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; =&amp;gt; |*&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; v.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; pseudo_to_stack(v.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;, strings,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;pseudo_map),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .ret, .allocate_stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It works. Thankfully. This little bit made me tear my hair out.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-zig-1&quot;&gt;&lt;a href=&quot;#fn-zig&quot;&gt;10&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As a small comparison, this is the C file in question, followed by the pretty printed codegen before and after replacing pseudoregisters.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; to save you a scroll&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ~-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#before&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		mov&lt;&#x2F;span&gt;&lt;span&gt;	imm &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt; pseudo &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;neg&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		neg&lt;&#x2F;span&gt;&lt;span&gt;	pseudo &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;neg&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		mov&lt;&#x2F;span&gt;&lt;span&gt;	pseudo &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;neg&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;0 -&amp;gt; pseudo cml&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		not&lt;&#x2F;span&gt;&lt;span&gt;	pseudo cml&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		mov&lt;&#x2F;span&gt;&lt;span&gt;	pseudo cml&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;1 -&amp;gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;AX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;# afer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		mov&lt;&#x2F;span&gt;&lt;span&gt;	imm &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt; stack -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		neg&lt;&#x2F;span&gt;&lt;span&gt;	stack -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		mov&lt;&#x2F;span&gt;&lt;span&gt;	stack -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt; stack -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		not&lt;&#x2F;span&gt;&lt;span&gt;	stack -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		mov&lt;&#x2F;span&gt;&lt;span&gt;	stack -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt; -&amp;gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;AX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is a horribly inefficient compiler, but it clearly works as intended. Optimization comes later in Part 3 of the book.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fixing-instructions&quot;&gt;Fixing Instructions&lt;&#x2F;h3&gt;
&lt;p&gt;The first fixup is to insert the &lt;code&gt;.allocate_stack&lt;&#x2F;code&gt; instruction with the depth of the stack. But this is not being returned anywhere! So a slight rejiggering of &lt;code&gt;pseudo_to_stack&lt;&#x2F;code&gt; to use a passed in counter instead of a local static one, and having &lt;code&gt;replace_pseudos&lt;&#x2F;code&gt; return the stack depth, would solve the problem. Simple, if annoying, code change.&lt;&#x2F;p&gt;
&lt;p&gt;Then adding the first instruction this way becomes fairly simple. Bad performance for this one step but I am not paying too much attention to that.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; pass_pseudo.replace_pseudos(alloc, strings, prgm_asm);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt; prgm_asm.func_def.instrs.insert(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;    0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .{ .allocate_stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @intCast&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt;@abs&lt;&#x2F;span&gt;&lt;span&gt;(depth)) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F;                            ^ this retunrs an unsigned int.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; next step gets called here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The other, more involved step is fixing up illegal instructions. If you know anything about x86 assembly, you would know that you cannot make a &lt;code&gt;mov&lt;&#x2F;code&gt; instruction between two stack places. There are reasons for that that I do not particularly care about. Why cannot the Book compile to a saner assembly language like WASM? I am not even on a x86 machine! Thankfully, this is the only thing to deal with in this chapter. Here is my first pass at the code.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; fixup_instrs(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    prgm:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;assembly.Prgm,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; out: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(assembly.Instr) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; .initCapacity(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        prgm.func_def.instrs.capacity,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        std.mem.swap(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(assembly.Instr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;            &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;out,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;            &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;prgm.func_def.instrs,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        out.deinit(alloc);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; (prgm.func_def.instrs.items) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;instr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        switch&lt;&#x2F;span&gt;&lt;span&gt; (instr) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (m.src) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (m.dst) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    .stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(m.src, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }, m.dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.append(alloc, instr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.append(alloc, instr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.append(alloc, instr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So much rightwards drift. It would perhaps be more readable to express it as a state machine, like the tokenizer works. I will make sure this works as intended first then try to streamline it, as this is untenable. Time to run the codegen tests.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ran 43 tests in 5.153s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OK&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;code-emission&quot;&gt;Code Emission&lt;&#x2F;h2&gt;
&lt;p&gt;Before we get into the state machine, it is better to be done with code emission. It is a fairly simple and mechanical exercise as it just requires updating the printing code, but it could expose pretty much any bugs in the program.&lt;&#x2F;p&gt;
&lt;p&gt;and ...&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ran 43 tests in 5.147s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FAILED (errors=19)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Oh come on. This turns out to be a combination of some commented out code when I was updating the compiler driver to include IR, &lt;em&gt;and&lt;&#x2F;em&gt; dumb spelling mistakes I did in this fairly simple and mechanical task, such as writing &lt;code&gt;&amp;amp;&lt;&#x2F;code&gt; instead of &lt;code&gt;%&lt;&#x2F;code&gt;. Simple mistakes, really.&lt;&#x2F;p&gt;
&lt;p&gt;All tests pass now:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ran 43 tests in 14.731s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OK&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;state-machine&quot;&gt;State Machine&lt;&#x2F;h2&gt;
&lt;p&gt;Following from the tokenizer&#x27;s code, I defined a simple &lt;code&gt;State&lt;&#x2F;code&gt; enum:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; State&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    start,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mov_stack_stack,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And the main &lt;code&gt;switch&lt;&#x2F;code&gt; inside the loop turns into a labelled &lt;code&gt;switch&lt;&#x2F;code&gt; over &lt;code&gt;State&lt;&#x2F;code&gt;, in which each state has its own logic, but any legal instruction just funnels to &lt;code&gt;.legal&lt;&#x2F;code&gt;. To be honest, writing this was easier than I expected it to be. It even worked on the first iteration, after I fixed the variable names. This is the second.&lt;&#x2F;p&gt;
&lt;p&gt;Jury&#x27;s up whether the state machine is more readable than the nested &lt;code&gt;switch&lt;&#x2F;code&gt;es, but I think I will stick with it for the time being. It passes all tests.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; (prgm.func_def.instrs.items) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;instr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    state:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (State.start) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .start&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (instr) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (m.src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; m.dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .stack)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                continue&lt;&#x2F;span&gt;&lt;span&gt; :state .mov_stack_stack&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; continue&lt;&#x2F;span&gt;&lt;span&gt; :state .legal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .mov_stack_stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(instr.mov.src, .{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .init(.{ .reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .R10 }, instr.mov.dst) },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .legal&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; out.append(alloc, instr),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Just for comparison&#x27;s sake, this is the equivalent code in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;asibahi&#x2F;trjm&#x2F;blob&#x2F;6bfc750386f2f3b886021a0351c9a716d26558f2&#x2F;src&#x2F;asm.rs&quot;&gt;my Rust implementation&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; instr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; std&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;mem&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;take(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-self&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;instrs) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    match&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; instr {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Instr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; @&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Operand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;Stack(_),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; @&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Operand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;Stack(_),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; out&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;extend([&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            Instr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                src,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Operand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;Reg(Register&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;R10&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            Instr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Operand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;Reg(Register&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;R10&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                dst,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ]),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        other&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; out&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;push(other),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Pattern matching is the best. And this concludes Chapter 2.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Building a cool state machine from zero.&lt;&#x2F;li&gt;
&lt;li&gt;More manual memory management magic tricks. (Couldn&#x27;t push the alliteration further.)&lt;&#x2F;li&gt;
&lt;li&gt;Subshells, and a more automated testing process.&lt;&#x2F;li&gt;
&lt;li&gt;First taste of &lt;code&gt;comptime&lt;&#x2F;code&gt;. ULTIMATE POWER.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Maybe next time I will compile the tests to be always in &lt;code&gt;ReleaseSafe&lt;&#x2F;code&gt; instead of &lt;code&gt;Debug&lt;&#x2F;code&gt; mode. Would certainly make things go more smoothly. Need to figure that one out.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-main&quot;&gt;
&lt;p&gt;I refactored the code a bit after chapter 1 and added proper support for the &lt;code&gt;identifier&lt;&#x2F;code&gt; token. It is a trivial change so no point in detailing it further, except that the new &lt;code&gt;expect&lt;&#x2F;code&gt; is cooler than before. &lt;a href=&quot;#fr-main-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-json&quot;&gt;
&lt;p&gt;There is an argument to be made for replacing my custom pretty printer with standard library&#x27;s &lt;code&gt;json&lt;&#x2F;code&gt; serializer. The result is more verbose and has more vertical space and redundant info, but on the plus side, it requires zero maintenance. &lt;a href=&quot;#fr-json-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-madness&quot;&gt;
&lt;p&gt;Sounds good for a book title or something, doesn&#x27;t it? &lt;a href=&quot;#fr-madness-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-matklad&quot;&gt;
&lt;p&gt;Inspired by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;matklad.github.io&#x2F;2025&#x2F;04&#x2F;21&#x2F;fun-zig-program.html&quot;&gt;matklad&lt;&#x2F;a&gt;. &lt;a href=&quot;#fr-matklad-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-binary&quot;&gt;
&lt;p&gt;Binary operations are in the next chapter. &lt;a href=&quot;#fr-binary-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-struct&quot;&gt;
&lt;p&gt;Helps to keep in mind that every file in Zig is a struct, too. &lt;a href=&quot;#fr-struct-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-adapters&quot;&gt;
&lt;p&gt;A useful read, which was educational for me on Contexts and Adaptors (in current Zig version, at least), are the Zig issues &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ziglang&#x2F;zig&#x2F;issues&#x2F;21917&quot;&gt;#21917&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ziglang&#x2F;zig&#x2F;issues&#x2F;23872&quot;&gt;#23872&lt;&#x2F;a&gt;, especially &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mlugg&quot;&gt;mulgg&lt;&#x2F;a&gt;&#x27;s comments. On the zig discord, mlugg gave me this useful summary: &quot;they&#x27;re quite similar. a context is essentially an adapter but for the &#x27;real&#x27; key type; a context tells you how to hash&#x2F;eql the actual &lt;code&gt;comptime K: T&lt;&#x2F;code&gt;, whereas an adapter allows you to insert &lt;em&gt;different&lt;&#x2F;em&gt; key types as long as you can implement &lt;em&gt;compatible&lt;&#x2F;em&gt; hash&#x2F;eql on them&quot;. &lt;a href=&quot;#fr-adapters-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-json_bug&quot;&gt;
&lt;p&gt;The crash disappeared when I removed the needless reference to the interner from the &lt;code&gt;ir.Prgm&lt;&#x2F;code&gt; struct, but I hit a new problem. The null terminated strings were printing as &lt;code&gt;&quot;main\u0000&quot;&lt;&#x2F;code&gt;. I am not sure if this is a standard library bug or a bug in my code. Definitely a case of debugging my language knowledge. &lt;a href=&quot;#fr-json_bug-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-stringhashmap&quot;&gt;
&lt;p&gt;I ended up replacing the hashmap here with &lt;code&gt;std.StringHashMap&lt;&#x2F;code&gt; which does exactly what I want and allowed me to avoid passing the string interner. My mistake was assuming, for some reason, that &lt;code&gt;StringHashMap&lt;&#x2F;code&gt; stores the strings inernally, but it just stores the slices already backed by the interner. &lt;a href=&quot;#fr-stringhashmap-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-zig&quot;&gt;
&lt;p&gt;I was debugging my language knowledge, it seems. &lt;a href=&quot;#fr-zig-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Chapter 1: Intro</title>
        <published>2025-05-10T00:00:00+00:00</published>
        <updated>2025-05-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/paella/c1/"/>
        <id>https://ar-ms.me/paella/c1/</id>
        
        <content type="html" xml:base="https://ar-ms.me/paella/c1/">&lt;p&gt;In a constant drive to spend, or waste, time while I am looking for work, I got and worked through Nora Sandler&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;norasandler.com&#x2F;2022&#x2F;03&#x2F;29&#x2F;Write-a-C-Compiler-the-Book.html&quot;&gt;Writing a C Compiler&lt;&#x2F;a&gt; in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;asibahi&#x2F;trjm&quot;&gt;Rust&lt;&#x2F;a&gt;. It is an excellent introduction to things like intermediate representation and &lt;code&gt;x86_64&lt;&#x2F;code&gt; assembly. About halfway through the book, however, I lost focus.&lt;&#x2F;p&gt;
&lt;p&gt;Continuing to have nothing particularly productive to do, I figured that I could try following the book again in a different language: either Swift or Zig. I do want to learn Swift eventually as writing Apps is probably more useful than writing operating systems, but the tooling leaves something to be desired. So Zig it is, for the time being.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ziglang.org&quot;&gt;Zig&lt;&#x2F;a&gt; is a very opinionated &quot;C replacement&quot;. It has a lot of weird and arbitrary design decisions: no typed integer literals (&lt;code&gt;@as(u8, 1)&lt;&#x2F;code&gt; instead of &lt;code&gt;1u8&lt;&#x2F;code&gt;) for example. But it also has a lot of nice ideas and it is being posited as the hottest thing since sliced bread, so why not Zig. Swift can happen later.&lt;&#x2F;p&gt;
&lt;p&gt;Zig, and the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tristanisham&#x2F;zvm&quot;&gt;Zig Version Manager&lt;&#x2F;a&gt; were already on my machine from previous flirtations with the language. &lt;code&gt;0.14.0&lt;&#x2F;code&gt; is the latest zig &quot;release&quot;, so that is what I am using.&lt;&#x2F;p&gt;
&lt;p&gt;I decided to call this project &lt;code&gt;paella&lt;&#x2F;code&gt;. I like paella. So without further ado, let&#x27;s go.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;build-zig&quot;&gt;&lt;code&gt;build.zig&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Zig is not being marketed, as it were, as a language. It is being marketed as a build system that just happens to have a language attached. &lt;code&gt;zig init&lt;&#x2F;code&gt; in the terminal creates a template project with full explanations of the basic building blocks.&lt;&#x2F;p&gt;
&lt;p&gt;Editing it to what I need, this is where I landed:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; build.zig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; std&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @import&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;std&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; build(b:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;std.Build) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; entry point&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; exe_mod&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.createModule(.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .root_source_file&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.path(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;src&#x2F;main.zig&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; this is the target for the Book and my machine.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.resolveTargetQuery(.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .cpu_arch&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .x86_64,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .os_tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .macos,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; choose optimization based on --release&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .optimize&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (b.release_mode) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .off&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .Debug,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; .ReleaseFast,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; exe&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b.addExecutable(.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;paella&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .root_module&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; exe_mod,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    b.installArtifact(exe);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; the rest is boilerplate for `zig build run` and `zig build test`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I did not include all the boilerplate that would allow me to use &lt;code&gt;zig build run&lt;&#x2F;code&gt; instead of &lt;code&gt;zig run main src&#x2F;main.zig&lt;&#x2F;code&gt;. Not much better, just nicer. Also a build system currently would let me add dependencies easier later.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;build.zig.zon&lt;&#x2F;code&gt; is whatever the initial command spit up, tbh. But it is where dependencies are to be listed later on.&lt;&#x2F;p&gt;
&lt;p&gt;The test suite and the book expect everything to use the &lt;code&gt;x86_64&lt;&#x2F;code&gt; CPU architecture, which is a little inconvenient in macOS due to it being on &lt;code&gt;aarm64&lt;&#x2F;code&gt;. This is howver well explained in the book and the environment set up for it is already done when doing the Book previously in Rust.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;the-compiler-driver&quot;&gt;The Compiler Driver&lt;&#x2F;h2&gt;
&lt;p&gt;The next step is what is called in the book the Compiler Driver, or rather the framework which surrounds the compiler bits the Book is actually about.&lt;&#x2F;p&gt;
&lt;p&gt;The Driver does several things:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Takes a file path and an optional phase flag as arguments.&lt;&#x2F;li&gt;
&lt;li&gt;Calls the system&#x27;s compiler, &lt;code&gt;gcc&lt;&#x2F;code&gt; to preprocess the C source file at said path, (so no macros or comments or compiler flags or whatever),&lt;&#x2F;li&gt;
&lt;li&gt;Calls the to-be-implemented compiler to transform the preprocessed file on disk into assembly, or stop at the requested compilation phase.&lt;&#x2F;li&gt;
&lt;li&gt;And finally, calls &lt;code&gt;gcc&lt;&#x2F;code&gt; again to assemble the assembly file into machine code.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The reason I am actually spelling it out, even though it is spelt out in the Book, is that it got me really confused at first. I thought the Driver was a separate thing that we will get to later. But no, it was pretty much step zero.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;argument-parsing&quot;&gt;Argument Parsing&lt;&#x2F;h3&gt;
&lt;p&gt;The simple argument parsing needed doesnt warrant getting a whole library in. The program will be called by the test suite and is not really meant for public consumption. So the bare minimum it is. (The returned errors are for my benefit.)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    path: [:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; a string in zigland&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mode: Mode,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; { lex, parse, codegen, compile, assembly };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_args() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;Args {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.process.args();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; args.skip();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; args.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.PathNotFound;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; mode: Mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (args.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;arg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        std.meta.stringToEnum(Mode, arg[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;..]) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.UnrecognizedFlag&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .compile;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; path, .mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; mode };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This code snippet makes use of some of the higher level Zig features, including two ways to unwrap optional values.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; optional_int:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt; ?i32 =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; ?i32 is an optional i32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; first one&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; If_is_an_expression:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt; i32 =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (optional_int) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; `int` is in scope here and we can do things&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;    7&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; second one&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; unwraps the result or returns a value.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; definite_int:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt; i32 =&lt;&#x2F;span&gt;&lt;span&gt; optional_int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; orelse&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; the two are exactly the same.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;calling-commands&quot;&gt;Calling Commands&lt;&#x2F;h3&gt;
&lt;p&gt;To run the preprocessor before compiling and the assembler after compiling, one needs to make use of &lt;code&gt;std.process.Child&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The quickest and least painful way to do so is &lt;code&gt;Child.run()&lt;&#x2F;code&gt;. However, this by default allocates, and returns, &lt;code&gt;stdout&lt;&#x2F;code&gt; and &lt;code&gt;stderr&lt;&#x2F;code&gt;. If the intent is to forward them to the parent process (which it is), the easiest way is this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;var&lt;&#x2F;span&gt;&lt;span&gt; child&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.process.Child.init(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;    &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;echo&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;something&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    allocator,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; zig is all about passing allocators&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; change options of `child` here: for example&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; child.stdout_behavior = .Ignore;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; term is the returned result of said process.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; term&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; child.spawnAndWait();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;manipulating-file-extensions&quot;&gt;Manipulating File Extensions&lt;&#x2F;h3&gt;
&lt;p&gt;However, before that, let&#x27;s get started at the much more complex problem of changing a file&#x27;s extension.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-extension-1&quot;&gt;&lt;a href=&quot;#fn-extension&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; Zig&#x27;s standard library provides a few ways to get the components, as it were, from a file path. They live in the &lt;code&gt;std.fs.path&lt;&#x2F;code&gt; and &lt;code&gt;std.mem&lt;&#x2F;code&gt; namespaces. After a bunch of trials and errors, I came up with the folliwng.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;foo&#x2F;bar.txt&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; stem&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; std.fs.path.join(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;    &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        std.fs.path.dirname(path) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        std.fs.path.stem(path),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;defer&lt;&#x2F;span&gt;&lt;span&gt; alloc.free(stem);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; new_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; std.mem.join(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;    &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        stem,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;quot;TXT&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;defer&lt;&#x2F;span&gt;&lt;span&gt; alloc.free(new_path);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;std.debug.assert(std.mem.eql(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, new_path,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;foo&#x2F;bar.TXT&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;finally&quot;&gt;Finally!(?)&lt;&#x2F;h3&gt;
&lt;p&gt;Putting two and two together, this is the first draft of the compiler driver. I am not even sure if it compiles or if I made any dumb mistakes, because the hole in the middle is rather large and it needs filling first.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; std&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @import&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;std&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; main() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; debug_allocator&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.heap.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;DebugAllocator&lt;&#x2F;span&gt;&lt;span&gt;(.{}).init;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; debug_allocator.deinit();&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; leak detection in Debug&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; gpa&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; debug_allocator.allocator();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_args();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; run(gpa, args);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; run(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    args: Args,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; input_path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; args.path;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; pp_out,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; const&lt;&#x2F;span&gt;&lt;span&gt; asm_out,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt; const&lt;&#x2F;span&gt;&lt;span&gt; exe&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt; get_output_paths(alloc, input_path);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; yay for manual memory management&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        alloc.free(pp_out);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        alloc.free(asm_out);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        alloc.free(exe);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; preprocessor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        var&lt;&#x2F;span&gt;&lt;span&gt; child&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.process.Child.init(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;            &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;gcc&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;-E&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;-P&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, input_path,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;-o&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, pp_out },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; term&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; child.spawnAndWait();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;std.meta.eql(term, .{ .Exited&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; }))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.PreprocessorFail;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; compiler&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; args.mode;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; mode controls compilation here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; todo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; take from path `pp_out` output to path `asm_out`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; assembler&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        var&lt;&#x2F;span&gt;&lt;span&gt; child&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.process.Child.init(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;            &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;gcc&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, asm_out,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;-o&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, exe },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        defer&lt;&#x2F;span&gt;&lt;span&gt; std.fs.cwd().deleteFile(asm_out) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;catch&lt;&#x2F;span&gt;&lt;span&gt; {};&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; cleanup&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span&gt; term&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; child.spawnAndWait();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;std.meta.eql(term, .{ .Exited&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; }))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.AssemblerFail;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    path: [:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mode: Mode,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    lex,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    parse,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    codegen,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    compile,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; default&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    assembly,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; unused by test script - useful for debugging&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; parse_args() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;Args {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.process.args();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; args.skip();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; args.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.PathNotFound;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; mode: Mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; (args.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;arg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        std.meta.stringToEnum(Mode, arg[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;..]) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.UnrecognizedFlag&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .compile;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; path, .mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; mode };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; get_output_paths(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    input_path: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;} {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; exe&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; std.fs.path.join(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;        &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            std.fs.path.dirname(input_path) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            std.fs.path.stem(input_path),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    errdefer&lt;&#x2F;span&gt;&lt;span&gt; alloc.free(exe);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; pp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; std.mem.join(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;quot;.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;        &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{ exe,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;i&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    errdefer&lt;&#x2F;span&gt;&lt;span&gt; alloc.free(pp);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; keywords and arbitrary strings become identifiers in zig like so&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; @&amp;quot;asm&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; std.mem.join(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;quot;.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;        &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{ exe,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;s&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ pp, @&amp;quot;asm&amp;quot;, exe };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lexer&quot;&gt;Lexer&lt;&#x2F;h2&gt;
&lt;p&gt;The Book takes things &lt;em&gt;very&lt;&#x2F;em&gt; gradually. So in the first chapter it just focuses on build the bare minimum of the compiler. The C program to be compiled in that chapter is this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;No, seriously, that&#x27;s it. And the preprocessor takes care of pesky things like comments. The lexer is absurdly simple, for now.&lt;&#x2F;p&gt;
&lt;p&gt;In Rust, I did all the lexing ahd parsing with &lt;code&gt;nom&lt;&#x2F;code&gt;, the lovely parser combinator library. However, here things should be done the old-fashioned, imperative way. That&#x27;s why the &lt;code&gt;0.14.0&lt;&#x2F;code&gt; Zig release introduced a new feature: labelled &lt;code&gt;switch&lt;&#x2F;code&gt;!&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-switch-1&quot;&gt;&lt;a href=&quot;#fn-switch&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; State&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; { a, b, c, d };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;loop:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (State.a) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        std.debug.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;reached .a&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; fallthrough at home&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        continue&lt;&#x2F;span&gt;&lt;span&gt; :loop .b;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        std.debug.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;reached .b&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (today&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .monday)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            continue&lt;&#x2F;span&gt;&lt;span&gt; :loop .c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            continue&lt;&#x2F;span&gt;&lt;span&gt; :loop .d;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; std.debug.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;reached .c&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; std.debug.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;reached .d&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{}),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The biggest, clearest example of using it is in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ziglang&#x2F;zig&#x2F;blob&#x2F;master&#x2F;lib&#x2F;std&#x2F;zig&#x2F;tokenizer.zig&quot;&gt;Zig compiler itself&lt;&#x2F;a&gt;. It is a cool design so I decided to just copy the design as is.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-unicode-1&quot;&gt;&lt;a href=&quot;#fn-unicode&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;There are a few moving parts, so I added a bunch of comments to explain.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; lexer.zig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; std&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @import&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;std&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; each Token carries a tag and a span (called `loc` here.)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tag: Tag,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    loc: Loc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; location within the source file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;    pub const&lt;&#x2F;span&gt;&lt;span&gt; Loc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        start:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        end:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; keywords identified here with their corresponding tags.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;    pub const&lt;&#x2F;span&gt;&lt;span&gt; keywords&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;StaticStringMap&lt;&#x2F;span&gt;&lt;span&gt;(Tag).initComptime(.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;return&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .keyword_return },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;int&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .type_int },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;void&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .keyword_void },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;main&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .keyword_main },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; helper function for the above&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span&gt; getKeyword(bytes: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;Tag {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; keywords.get(bytes);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; the tag collection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;    pub const&lt;&#x2F;span&gt;&lt;span&gt; Tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; punctuation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        l_paren,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        r_paren,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        l_brace,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        r_brace,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        semicolon,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        number_literal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; keywords&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        type_int,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        keyword_void,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        keyword_return,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        keyword_main,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; identifiers happen later&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; helpers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        identifier,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; useful for state for now&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        invalid,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; this and the one below it are unused for now, but maybe useful later?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;        pub fn&lt;&#x2F;span&gt;&lt;span&gt; lexeme(tag: Tag) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return switch&lt;&#x2F;span&gt;&lt;span&gt; (tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .invalid,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .number_literal,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .identifier,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt;                =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .l_paren&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;(&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .r_paren&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .l_brace&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;{&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .r_brace&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .semicolon&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .type_int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;int&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .keyword_void&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;void&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .keyword_return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;return&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .keyword_main&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;main&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;        pub fn&lt;&#x2F;span&gt;&lt;span&gt; symbol(tag: Tag) []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; tag.lexeme() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse switch&lt;&#x2F;span&gt;&lt;span&gt; (tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .invalid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;invalid token&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .identifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;an identifier&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .number_literal&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;a number literal&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-statement z-zig&quot;&gt; unreachable&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; the lexer state machine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Tokenizer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; pointer to source&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    buffer: [:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; where in source we are&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    index:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt; usize =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span&gt; init(buffer: [:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;) Tokenizer {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; .{ .buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; buffer };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; states. this will grow in complexity with more tokens.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; State&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        start,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        identifier,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        int,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; the loop itself&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;    pub fn&lt;&#x2F;span&gt;&lt;span&gt; next(self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Tokenizer) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;Token {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; the eventually returned value.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;        var&lt;&#x2F;span&gt;&lt;span&gt; result: Token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; undefined&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .loc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .start&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; self.index,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .end&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; undefined&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        state:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (State.start) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;            &#x2F;&#x2F; the starting state for every new token.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .start&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (self.buffer[self.index]) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;                0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; nullbyte&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    if&lt;&#x2F;span&gt;&lt;span&gt; (self.index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; self.buffer.len) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; eof&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        result.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .invalid;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;#39; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;\n&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;\t&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;\r&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; { &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; whitespace&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    self.index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; advance cursor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    result.loc.start&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; self.index;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .start;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; and restart&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;#39;a&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;z&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;A&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;Z&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;_&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    result.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .identifier;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .identifier;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; move to identifier state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;#39;0&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;9&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    result.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .number_literal;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    self.index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .int;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; move to integer state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;                &#x2F;&#x2F; all of the following is self-explanatory really&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;#39;(&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    result.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .l_paren;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    self.index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;#39;)&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    result.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .r_paren;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    self.index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;#39;;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    result.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .semicolon;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    self.index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;#39;{&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    result.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .l_brace;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    self.index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;#39;}&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    result.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .r_brace;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    self.index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; result.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .invalid,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .identifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                self.index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                switch&lt;&#x2F;span&gt;&lt;span&gt; (self.buffer[self.index]) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;                    &#x2F;&#x2F; keep going until ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                    &amp;#39;a&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;z&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;A&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;Z&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;_&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;0&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;9&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; continue&lt;&#x2F;span&gt;&lt;span&gt; :state .identifier,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;                    &#x2F;&#x2F; .. something other than those happens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;                        const&lt;&#x2F;span&gt;&lt;span&gt; ident&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; self.buffer[result.loc.start..self.index];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;                        &#x2F;&#x2F; check if it s a keyword&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                        if&lt;&#x2F;span&gt;&lt;span&gt; (Token.getKeyword(ident)) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                            result.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tag;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .int&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; (self.buffer[self.index]) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;#39;0&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;9&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    self.index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; :state .int;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;                &#x2F;&#x2F; integers not allowed to have letters after them, for now.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;#39;a&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;z&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;A&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;Z&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; result.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .invalid,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; tidy up.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        result.loc.end&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; self.index;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; result;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It is a bit cut down from the original behemoth, but this will grow in complexity as I advance through the book. The corresponding file in my Rust implementation eventually became full of macros and slowed rust-analyzer to a crawl.&lt;&#x2F;p&gt;
&lt;p&gt;The stub in &lt;code&gt;main.zig&lt;&#x2F;code&gt; is filled as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; main.zig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; compiler&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; the use of the more complex function here is to specify the sentinel null terminator ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; std.fs.cwd().readFileAllocOptions(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        alloc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        pp_out,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        std.math.maxInt(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt;        null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt;        @alignOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;        0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; .. this null terminator.here. The rest are defaults.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; std.fs.cwd().deleteFile(pp_out);&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; cleanup&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; alloc.free(src);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; tokenizer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; lexer.Tokenizer.init(src);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (tokenizer.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;        &#x2F;&#x2F; just to see the results for now.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        std.debug.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{?}: {s}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            token.tag,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            src[token.loc.start..token.loc.end],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        switch&lt;&#x2F;span&gt;&lt;span&gt; (token.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .invalid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.LexFail,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (args.mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .lex) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; to be continued&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Unlike the original implementation, there are a few differences: it does not attempt to recover on new lines, but breaks as soon as one invalid token happens. This is actually a terrible idea but it is passable in a toy compiler. Also there is no &lt;code&gt;eof&lt;&#x2F;code&gt; token, choosing to return &lt;code&gt;null&lt;&#x2F;code&gt; on source file end. Not very data oriented of me, as it increases the size by a byte (probably), but I will live.&lt;&#x2F;p&gt;
&lt;p&gt;Bugs shall be found when I tie it to the book&#x27;s test suite.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;setting-up-tests&quot;&gt;Setting Up Tests&lt;&#x2F;h2&gt;
&lt;p&gt;This is actually so dumb it is not worth its own section. Just clone the book&#x27;s tests repo and create a symlink to the compiler in the base directory. For future reference, this is what I typed to create said symlink:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;# while in the tests folder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ln&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ..&#x2F;paella&#x2F;zig-out&#x2F;bin&#x2F;paella&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then I just call the tests as follows from the same said folfer.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&#x2F;test_compiler&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; .&#x2F;paella&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; --chaoter 1 --stage&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; lex&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;All tests should pass now.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ran 24 tests in 2.008s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FAILED (failures=19)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Oh come on.&lt;&#x2F;p&gt;
&lt;p&gt;All of these errors seem to be hitting the &lt;code&gt;error.UnrecognizedFlag&lt;&#x2F;code&gt; specified in the argument parser. Debugging the situation, with friendly &lt;code&gt;std.debug.print&lt;&#x2F;code&gt;, showed me that not all calls to the function have the same order of arguments, which is definitely a surprise. The argument parsing code clearly needs to be revised.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; parse_args() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;Args {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.process.args();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; args.skip();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; path:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt;[:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt; u8 =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span&gt; mode: Mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .compile;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (args.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;arg&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (arg[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;-&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; std.meta.stringToEnum(Mode, arg[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;..]) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.UnrecognizedFlag;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else if&lt;&#x2F;span&gt;&lt;span&gt; (path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; arg;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.PathDuplicated;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; orelse return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.PathNotFound,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; mode,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s try again.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;----------------------------------------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ran 24 tests in 2.420s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OK&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Yay!&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;ast&quot;&gt;AST&lt;&#x2F;h2&gt;
&lt;p&gt;Dealing with abstract syntax trees (ASTs) is pretty much the reason the book tells the reader to use a functional language with sum types&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-sum-1&quot;&gt;&lt;a href=&quot;#fn-sum&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; and pattern matching. In fact, the reference implementation is in relatively easy to read OCaml.&lt;&#x2F;p&gt;
&lt;p&gt;To explore how to represent the AST in Zig, I mostly just looked for C resources. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;keleshev.com&#x2F;abstract-syntax-tree-an-example-in-c&#x2F;&quot;&gt;This very nice article&lt;&#x2F;a&gt; explains how to represent a basic AST in C, and as a bonus compares it to an equivalent OCaml (as it happens) implementation.&lt;&#x2F;p&gt;
&lt;p&gt;I also had a read on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mitchellh.com&#x2F;zig&#x2F;parser&quot;&gt;Mitchell Hashimoto&#x27;s series on the Zig compiler&lt;&#x2F;a&gt;. The series is very informative, but to be honest there is no real need for this project to be super data oriented design driven with maximum cache friendliness and whatever may be. A, relatively, naive implementation of an AST is perhaps much more useful for learning purposes.&lt;&#x2F;p&gt;
&lt;p&gt;That said, I can adapt some of the interesting ideas mentioned, like &quot;splatting&quot; some &lt;code&gt;enum&lt;&#x2F;code&gt;s. For example, assume an expression can be either a binary operation or a unary operation. It would be represented naively as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    number:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    binary:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; { BinOp,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    unary:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; { UnOp,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; BinOp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; { add, sub, and_, or_ };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; UnOp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; { negate, not };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;However, splatting the &lt;code&gt;Expr&lt;&#x2F;code&gt; enum would make the whole type slightly smaller. As an added benefit, many parts of the code would have different behaviour depending on what type of binary or unary operator it is, leading to &lt;code&gt;switch&lt;&#x2F;code&gt; statements within &lt;code&gt;switch&lt;&#x2F;code&gt; statements. The flatter design would look liek this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    number:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bin_add:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; { &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bin_sub:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; { &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bin_and:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; { &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bin_or:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; { &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    un_negate:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    un_not:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It &lt;em&gt;looks&lt;&#x2F;em&gt; slightly more verbose, but it is exactly the same amount of data. The types are being summed in our sum types!&lt;&#x2F;p&gt;
&lt;p&gt;In the actual Zig compiler, the pointers are replaced by indices into the other &lt;code&gt;Expr&lt;&#x2F;code&gt; nodes where they are stored in a giant array: Handles being the better pointers and all that. As I do not particualy need that kind of optimization, I will just throw every node into an &lt;code&gt;Arena&lt;&#x2F;code&gt; and free it all at once once I am done with the AST (in a later stage from parsing.)&lt;&#x2F;p&gt;
&lt;p&gt;The needs for this chapter are a lot simpler, however. The entirety of our current AST can be summarized as follows.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Prgm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    func_def:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;FuncDef,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; FuncDef&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    body:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Stmt,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Stmt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @&amp;quot;return&amp;quot;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; Expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    constant:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;parser&quot;&gt;Parser&lt;&#x2F;h2&gt;
&lt;p&gt;Writing a parser is a bit more involved, and it is something I have never done before. In my previous implementation I used a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;nom&#x2F;latest&#x2F;nom&#x2F;&quot;&gt;parser combinator library&lt;&#x2F;a&gt;. It was probably the easiest and smoothest part.&lt;&#x2F;p&gt;
&lt;p&gt;There &lt;em&gt;are&lt;&#x2F;em&gt; parser combinator libraries for Zig. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Hejsil&#x2F;mecha&quot;&gt;&lt;code&gt;mecha&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; is the first result on Google.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-generator-1&quot;&gt;&lt;a href=&quot;#fn-generator&quot;&gt;5&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I think at first I will try my handrolling the parser. Should that prove to be arduous, I will maybe switch to &lt;code&gt;mecha&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The pseudocode given in the book translates, in Zig, to the next listing. I am passing the allocator as all items should be allocated in an Arena, as mentioned before. I am also passing the tokenizer as a reference. I do not expect to have a lot of backtracking, as it is C I am compiling, after all, so the tokens are allocated nowhere and the tokenizer just produces them as it goes along.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_stmt(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt;!*&lt;&#x2F;span&gt;&lt;span&gt;ast.Stmt {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.keyword_return, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; expr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(alloc, tokens);&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; stub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.semicolon, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; alloc.create(ast.Stmt);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ret.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .{ .@&amp;quot;return&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; expr };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; ret;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; expect(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    expected: lexer.Token.Tag,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (tokens.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;actual&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (actual.tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span&gt; expected)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.SyntaxError;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Looks simple enough. Let&#x27;s try the rest.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;parse_expr&lt;&#x2F;code&gt; has currently only one thing: an integer. It should have some structure, however. It does not use &lt;code&gt;expect&lt;&#x2F;code&gt; as &lt;code&gt;expect&lt;&#x2F;code&gt; discards its token.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_expr(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt;!*&lt;&#x2F;span&gt;&lt;span&gt;ast.Expr {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; current&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.next() &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;orelse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.ExpectExpr;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (current.tag) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .number_literal&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; lit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tokens.buffer[current.loc.start..current.loc.end];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; res&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; std.fmt.parseInt(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;u64&lt;&#x2F;span&gt;&lt;span&gt;, lit,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span&gt; ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; alloc.create(ast.Expr);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            ret.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .{ .constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; res };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; ret;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.ExpectExpr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The other two, &lt;code&gt;parse_func_def&lt;&#x2F;code&gt; and &lt;code&gt;parse_prgm&lt;&#x2F;code&gt; are as straightforward as they get. I am putting off dealing with identifiers for now, because I do not want to put them in the arena, but use some sort of global hashmap instead. Maybe for the next chapter.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_prgm(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt;!*&lt;&#x2F;span&gt;&lt;span&gt;ast.Prgm {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; func_def&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_func_def(alloc, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; alloc.create(ast.Prgm);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ret.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .{ .func_def&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; func_def };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; ret;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_func_def(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt;!*&lt;&#x2F;span&gt;&lt;span&gt;ast.FuncDef {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.type_int, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; this should be an identifier but i am taking a rain check&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.keyword_main, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.l_paren, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.keyword_void, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.r_paren, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.l_brace, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; body&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_stmt(alloc, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; expect(.r_brace, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; alloc.create(ast.FuncDef);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ret.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;main&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .body&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; body };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; ret;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Great. Now to call them from &lt;code&gt;main.zig&lt;&#x2F;code&gt; and build and run the tests.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;AssertionError: Didn&amp;#39;t catch error in chapter_1&#x2F;invalid_parse&#x2F;extra_junk.c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;----------------------------------------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ran 24 tests in 4.164s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FAILED (failures=1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Pfft. This is &lt;code&gt;extra_junk.c&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; A single identifier outside of a declaration isn&amp;#39;t a valid top-level construct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;foo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Oh that&#x27;s why. Adding a small check to &lt;code&gt;parse_prgm&lt;&#x2F;code&gt; should solve the issue.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; parse_prgm(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tokens:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;lexer.Tokenizer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt;!*&lt;&#x2F;span&gt;&lt;span&gt;ast.Prgm {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; func_def&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; parse_func_def(alloc, tokens);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; funny piece of syntax.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (tokens.next()) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;_&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; error&lt;&#x2F;span&gt;&lt;span&gt;.ExtraJunk;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; alloc.create(ast.Prgm);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ret.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span&gt; .{ .func_def&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; func_def };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; ret;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This passes all tests.&lt;&#x2F;p&gt;
&lt;p&gt;To be honest I do not if I am doing things correctly yet. Less so in writing a compiler part but more so in the not leaking any memory part. The &lt;code&gt;DebugAllocator&lt;&#x2F;code&gt; does tell if there are leakages, but the test runner hides the output from me unless there is a test failure. It does not matter in the writing a compiler side of things, but I guess it does matter on the learning properly side of things. Whatever. What&#x27;s the next task?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pretty-printing-the-ast&quot;&gt;Pretty Printing the AST&lt;&#x2F;h2&gt;
&lt;p&gt;Before I start on the actual next task, now would be a pretty good time to start implementing pretty printing. It would help massively down the line with debugging.&lt;&#x2F;p&gt;
&lt;p&gt;It is possible in Zig to create custom formatters for types, which I plan to use. However it relies on weird generic pseudo-interface shenanigans, very unlike what is in the Rust system. Zig&#x27;s interface like behaviour is structural: it checks if there is a function a specific name and type in there, and if not, does something else.&lt;&#x2F;p&gt;
&lt;p&gt;First let&#x27;s show the result &lt;em&gt;without&lt;&#x2F;em&gt; pretty printing, fir the following C program.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; main (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-built-in z-primitive z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When parsed into an AST, it prints by default like that:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ast.Prgm{ .func_def&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; ast.FuncDef{ .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; { &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;109&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 97&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 105&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 110&lt;&#x2F;span&gt;&lt;span&gt; }, .body&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; ast.Stmt{ .&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; ast.Expr{ ... } } } }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Not particularly useful or helpful.&lt;&#x2F;p&gt;
&lt;p&gt;The way to create a custom formatter is to add this function to the type&#x27;s definition:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; format(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @This&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;    comptime&lt;&#x2F;span&gt;&lt;span&gt; fmt: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    options: std.fmt.FormatOptions,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    writer:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; anytype&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    &#x2F;&#x2F; do stuff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;writer&lt;&#x2F;code&gt; field seems to have the functions &lt;code&gt;print&lt;&#x2F;code&gt; and &lt;code&gt;writeAll&lt;&#x2F;code&gt;, based on various examples, but I do not actually know from this signature what is vailable.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-write-1&quot;&gt;&lt;a href=&quot;#fn-write&quot;&gt;6&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; This resolves at compile time via C++ template-like SFINAE behaviour (as far as I understand it anyway).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;FormatOptions&lt;&#x2F;code&gt; is a lot more interesting. this is the definition from the Zig standard library:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; FormatOptions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    precision:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt; ?usize =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    width:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt; ?usize =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-constant z-default z-zig&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alignment: Alignment&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; default_alignment,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    fill:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig z-keyword z-operator z-assignment&quot;&gt; u21 =&lt;&#x2F;span&gt;&lt;span&gt; default_fill_char,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Like in did in my Rust implementation, I can use the optional &lt;code&gt;width&lt;&#x2F;code&gt; variable to pass the indentation level to each child element. If this does not make sense now, it might in a minute.&lt;&#x2F;p&gt;
&lt;p&gt;The formatting apparatus in Zig is also explained in the standard library documentation, which is explained &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zig.guide&#x2F;standard-library&#x2F;advanced-formatting&#x2F;&quot;&gt;in neat examples in zig.guide&lt;&#x2F;a&gt;. Here is the format written out for your convenience:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; `{[argument][specifier]:[fill][alignment][width].[precision]}`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There was one missing piece though. How do I pass a &lt;em&gt;variable&lt;&#x2F;em&gt; to the &lt;code&gt;width&lt;&#x2F;code&gt; parameter? All the examples seem to use a literal. This took some tinkering to figure out, but figure it out I did.&lt;&#x2F;p&gt;
&lt;p&gt;The signature of &lt;code&gt;std.debug.print&lt;&#x2F;code&gt; accepts in its second argument an &lt;code&gt;anytype&lt;&#x2F;code&gt;, which is analyzed at &lt;code&gt;comptime&lt;&#x2F;code&gt; and matched with the given formatting string (which must be &lt;code&gt;comptime&lt;&#x2F;code&gt; known), and it fails to compile if they do not. I always passed on a tuple and relied on its general ordering, like so.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;std.debug.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{?}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{prgm});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But the &lt;code&gt;args&lt;&#x2F;code&gt; parameter does not have to be a tuple. The struct elements can have names!! This explained very briefly in the docs (found in &lt;code&gt;std.fmt.zig&lt;&#x2F;code&gt; in the standard library) like so:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; - *argument* is either the numeric index or the field name of the argument that should be inserted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;   - when using a field name, you are required to enclose the field name (an identifier) in square&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;     brackets, e.g. {[score]...} as opposed to the numeric index form which can be written e.g. {2...}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I did not know that. But that laos meant I can pass the &lt;code&gt;width&lt;&#x2F;code&gt; as a variable as well if I pass it in as a named field and surround it in square brackets.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F;    magic happens here vvvvvvv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{[def]:[width]}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .def&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; self.func_def,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .width&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; w,&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &#x2F;&#x2F; passed on from before.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;&#x2F; this also works. vvv index&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{:[1]}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    self.func_def,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    w,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This passes the &lt;code&gt;w&lt;&#x2F;code&gt; variabe to the &lt;code&gt;FormatOptions&lt;&#x2F;code&gt; of the called formatter. voila!!&lt;&#x2F;p&gt;
&lt;p&gt;What follows is conceptually simple. This is my &lt;code&gt;format&lt;&#x2F;code&gt; function implemented for &lt;code&gt;ast.Prgm&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; format(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @This&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;    comptime&lt;&#x2F;span&gt;&lt;span&gt; _: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    options: std.fmt.FormatOptions,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    writer:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; anytype&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;PROGRAM&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{[def]:[w]}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .def&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; self.func_def,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .w&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (options.width&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; orelse&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And this is the one for &lt;code&gt;FuncDef&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; format(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    self:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-zig&quot;&gt; @This&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig&quot;&gt;    comptime&lt;&#x2F;span&gt;&lt;span&gt; _: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    options: std.fmt.FormatOptions,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    writer:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; anytype&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-type z-zig&quot;&gt;!void&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; options.width&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; orelse&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; writer.writeByteNTimes(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;\t&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;, w);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;FUNCTION {s}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{self.name});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt; writer.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{[body]:[w]}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .body&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; self.body,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .w&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And the rest, as chess players say, is just technique. Now running our program on the C snippet gives this glorious output.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		RETURN 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This creates an additional maintenance burden the bigger the compiler grows, but it is worth it for the debugging goodness.&lt;&#x2F;p&gt;
&lt;p&gt;Now back to work.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;assembly-generation&quot;&gt;Assembly Generation&lt;&#x2F;h2&gt;
&lt;p&gt;Straight to the point. I like it. No intermediate representations or anything &lt;em&gt;tacky&lt;&#x2F;em&gt; of the sort.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-ir-1&quot;&gt;&lt;a href=&quot;#fn-ir&quot;&gt;7&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; So let&#x27;s get on with it.&lt;&#x2F;p&gt;
&lt;p&gt;The first step in assembly generation is to actually put up an syntax tree for assembly. the second tree is whwat we use to actually generate the assembly code at the end. So, the first thing I will do here is to create an &lt;code&gt;assembly.zig&lt;&#x2F;code&gt; file with the similar structure as &lt;code&gt;ast.zig&lt;&#x2F;code&gt;. This is fairly straightforward.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Prgm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    func_def:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;FuncDef,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; FuncDef&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name: []&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    instrs: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(Inst),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Inst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mov:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; { src: Operand, dst: Operand },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ret:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; void&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-keyword z-default z-zig&quot;&gt;pub const&lt;&#x2F;span&gt;&lt;span&gt; Operand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-structure z-zig&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    imm:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    reg:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-zig&quot;&gt; void&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To generate this AST from the source AST, I am going to stick the logic in yet another file I will call &lt;code&gt;asm_gen.zig&lt;&#x2F;code&gt;. So many files. I am not quite sure about storing the body of instructions this way, but it saves from the allocation dance every time I need to edit the contents down the line. Using a &lt;code&gt;SimplyLinkedList&lt;&#x2F;code&gt; might be an option too. For now, this is it.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;Unmanaged&lt;&#x2F;code&gt; part is sems intimidating, but it just really means that it does not keep a reference to its allocator, putting the responsibility of making sure the same allocator is passed every time on the caller. My understanding is that this is mean to be the default interface for &lt;code&gt;ArrayList&lt;&#x2F;code&gt; going forard.&lt;&#x2F;p&gt;
&lt;p&gt;Back to task. After wrangling a bit with zig&#x27;s compiler errors and its type checks&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-compiler_errors-1&quot;&gt;&lt;a href=&quot;#fn-compiler_errors&quot;&gt;8&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, I came up with these intimidating looking functions with all kinds of memory leaks in the sad path (I fear).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-zig z-storage z-type&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; prgm_to_asm(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    prgm: ast.Prgm,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;assembly.Prgm {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; func_def&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; alloc.create(assembly.FuncDef);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    errdefer&lt;&#x2F;span&gt;&lt;span&gt; alloc.destroy(func_def);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    func_def.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-keyword z-operator z-assignment&quot;&gt;* =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; func_def_to_asm(alloc, prgm.func_def.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{ .func_def&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; func_def };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; func_def_to_asm(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    func_def: ast.FuncDef,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;assembly.FuncDef {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; alloc.dupe(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-type z-integer z-zig&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;, func_def.name);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    errdefer&lt;&#x2F;span&gt;&lt;span&gt; alloc.free(name);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span&gt; instrs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; stmt_to_asm(alloc, func_def.body.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; name,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .instrs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instrs,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This next one took a lot of wrangling until I figured out the syntax for a slice of unions.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; stmt_to_asm(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    alloc: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    stmt: ast.Stmt,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(assembly.Inst) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (stmt) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .@&amp;quot;return&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-default z-zig&quot;&gt;            var&lt;&#x2F;span&gt;&lt;span&gt; result: std.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ArrayListUnmanaged&lt;&#x2F;span&gt;&lt;span&gt;(assembly.Inst) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; .empty;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt; result.appendSlice(alloc,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;.{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .mov&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    .src&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; try&lt;&#x2F;span&gt;&lt;span&gt; expr_to_asm(alloc, value.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    .dst&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .reg,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                } },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;                &#x2F;&#x2F; I could just ype `.ret,` here but that might be confusing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                .{ .ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {} },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; result;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And last but not least, the absolute bottom of the totem pole. The allocator is passed in here just in case because I think I might need it later.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; expr_to_asm(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _: std.mem.Allocator,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    expr: ast.Expr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;assembly.Operand {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; (expr) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .constant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; =&amp;gt; |&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; .{ .imm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; i },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Testing this out with the tiny C program gives me a rather ugly output. Implementing pretty printing (based on our previous attempt) for our assembly AST gives us this nice output.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PROGRAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	FUNCTION main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		mov imm 0, register&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Obviously this can just be repurposed to generate the actual assembly. So that is what is going to happen next.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;code-emission&quot;&gt;Code Emission&lt;&#x2F;h2&gt;
&lt;p&gt;Here is a funny thing. The &lt;code&gt;format&lt;&#x2F;code&gt; function that needs to be implemented for the formatting interface has a field that I have so far discarded. This field is one of the option the user tells the formatter what to do, and it is used all the time for everyone. For example, when you want to print a digit as a digit, you do &lt;code&gt;print(&quot;{d}, .{my_digit})&lt;&#x2F;code&gt;. Wheh nyou want an ASCII character, &lt;code&gt;print(&quot;{c}, .{my_digit})&lt;&#x2F;code&gt; is your friend. This tiny &lt;code&gt;d&lt;&#x2F;code&gt; or &lt;code&gt;c&lt;&#x2F;code&gt; is the string passed in through the hitherto discarded input. And I can define it to be anything I want!! I actually tried the phrase &lt;code&gt;free syria&lt;&#x2F;code&gt; with a space, and some Arabic text,, and it passed through as expected.&lt;&#x2F;p&gt;
&lt;p&gt;I have been printing to the terminal like so:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;std.debug.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{prgm});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which gives me the (arguably) nice debugging output seen above. But if I, say, call it like so:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;std.debug.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{gen}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, .{prgm});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I can have it emit the assembly code wanted just fine. And since it works with any &lt;code&gt;Writer&lt;&#x2F;code&gt;, I can write it to a file immediately. Pretty cool, and a similar interface to what Rust does, &lt;code&gt;anytype&lt;&#x2F;code&gt; notwithstanding.&lt;&#x2F;p&gt;
&lt;p&gt;Without boring you with the details, the formatting prints this really nice assembly (which does not forget the underscore since I am on macOS):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.globl _main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;_main:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	movl &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;$0&lt;&#x2F;span&gt;&lt;span&gt;, %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;eax&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And this concludes all tests for this chapter, which pass with flying colors.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;&#x2F;h2&gt;
&lt;p&gt;This is, currently, a tiny do-nothing program. However, in the course of implementing it, I learned the followings things:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;More comfort with Zig&#x27;s syntax.&lt;&#x2F;li&gt;
&lt;li&gt;Learned a bit about Zig&#x27;s standard library (environment, file system, child processes, collections), and build system.&lt;&#x2F;li&gt;
&lt;li&gt;Not shown here, but I managed to figure out how to actually add dependencies. It is a bit more involved than &lt;code&gt;cargo add&lt;&#x2F;code&gt;, but it is nice enough.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;I think this program is a decent testing ground for someone wanting to learn a new language, especially if done before in a familiar one.&lt;&#x2F;p&gt;
&lt;p&gt;Jury&#x27;s out on whether to continue with chapter 2 with Zig or try reimplementing chapter 1 in Swift, (or maybe Gleam? How do you even run Gleam programs?)&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s all, and thanks for reading.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-extension&quot;&gt;
&lt;p&gt;Rust provides a nice, encapsulated, function for this: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;path&#x2F;struct.Path.html#method.with_extension&quot;&gt;&lt;code&gt;with_extension&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;. But this is Zig: why have a convenient function for a common operation when one can instead do things the complicated and explicit way? Explicitness is extremely important, you know. &lt;a href=&quot;#fr-extension-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-switch&quot;&gt;
&lt;p&gt;Which is really just a loop in switch clothing. &lt;a href=&quot;#fr-switch-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-unicode&quot;&gt;
&lt;p&gt;An interesting tidbit: the Zig lexer&#x2F;tokenizer only supports the ASCII letters for identifiers. If one wants to use Unicode, it should be escaped like keywords do inside &lt;code&gt;@&quot;&quot;&lt;&#x2F;code&gt;. This has the benefit of the Unicode data not being a dependency of the compiler, and it simplifies lexing. &lt;a href=&quot;#fr-unicode-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-sum&quot;&gt;
&lt;p&gt;like Zig &lt;code&gt;union(enum)&lt;&#x2F;code&gt;s or Rust &lt;code&gt;enum&lt;&#x2F;code&gt;s. The &quot;sum&quot; terminology comes from math, apparently. An enum is one of several things, so the total possible values are a &lt;em&gt;sum&lt;&#x2F;em&gt; of each value. A &lt;code&gt;struct&lt;&#x2F;code&gt;, in pretty much any language, in comparison is a &lt;em&gt;product&lt;&#x2F;em&gt; type, where its number of possible states is the product of its individual elements possible states. &lt;a href=&quot;#fr-sum-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-generator&quot;&gt;
&lt;p&gt;The other option is to use a parser generator. I looked and failed to find any that output Zig code. If you know of one, please let me know. &lt;a href=&quot;#fr-generator-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-write&quot;&gt;
&lt;p&gt;Further internet browsing revealed it was &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ziglang.org&#x2F;documentation&#x2F;master&#x2F;std&#x2F;#std.io.Writer&quot;&gt;std.io.GenericWriter&lt;&#x2F;a&gt; which has a few other potentially useful functions. &lt;a href=&quot;#fr-write-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-ir&quot;&gt;
&lt;p&gt;&lt;em&gt;That&lt;&#x2F;em&gt; is introduced in later chapters, and is called TACKY. &lt;a href=&quot;#fr-ir-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-compiler_errors&quot;&gt;
&lt;p&gt;Why just why do compilers print the first error first? They do that, then the terminal scrolls up, and I cannot find where the first error begins and the last error of the previous commands ends. Can you all add a pager or print the first error last? &lt;a href=&quot;#fr-compiler_errors-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Placemaking Syria</title>
        <published>2025-05-03T00:00:00+00:00</published>
        <updated>2025-05-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/thoughts/placemaking-syria/"/>
        <id>https://ar-ms.me/thoughts/placemaking-syria/</id>
        
        <content type="html" xml:base="https://ar-ms.me/thoughts/placemaking-syria/">&lt;blockquote&gt;
&lt;p&gt;Note: This was written as a draft socument. The ideas are haphazard and not properly organized.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The cities of Syria are, to put it lightly, in bad shape. Decades of neglect followed by the war and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.washingtonpost.com&#x2F;graphics&#x2F;world&#x2F;destruction-of-aleppo&#x2F;&quot;&gt;large-scale destruction&lt;&#x2F;a&gt; have destroyed the cities. Everyone in Syria wants to rebuild, but we need to re-build it &lt;em&gt;right&lt;&#x2F;em&gt;. We should build them for humans.&lt;&#x2F;p&gt;
&lt;p&gt;But cities should be designed for humans. Humans should be able to walk the streets safely and freely. Chuldren should be able to run and play. Women with strollers and the elderlies with canes and disabled with wheelchairs should be able to get around. Our environment should pleaze our senses.&lt;&#x2F;p&gt;
&lt;p&gt;Unfortunately, modern cities are designed first and foremost for cars. Streets are made for cars, and humans walking around are merely a necessity. Car pollute our enivornment with noise and smells and eye-sores. Our children cannot walk safely on streets. All the pavements and asphalt makes it difficult to walk around with a stroller (seriously, try it one day.)&lt;&#x2F;p&gt;
&lt;p&gt;But it does not have to be this way. We can use this opportunity to build our cities and streets again to cater for living things. The idea has many names in Academia and Practice. You&#x27;ll often see it called Placemaking, or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stories.undp.org&#x2F;humanizing-cities&quot;&gt;Humanization&lt;&#x2F;a&gt;, or the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;15-minute_city&quot;&gt;15-minute City&lt;&#x2F;a&gt;. The theory behind these concepts are entirely uncotroversial among academics and practioners, but where they stumble is often in convincing policy makers (which brings about all the brand names).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-real-problem-with-cars&quot;&gt;The Real Problem with Cars&lt;&#x2F;h2&gt;
&lt;p&gt;Cars are often brought up as a major contributor to air pollution and global warming. And the solution, very often, is posited as enviironmentally friendly cars, or (in case of Syria) newer less polluting cars. Another usual suggested solution is to mandate &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Carpool&quot;&gt;carpools&lt;&#x2F;a&gt;, or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Odd%E2%80%93even_rationing&quot;&gt;odd-even rationing&lt;&#x2F;a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;apnews.com&#x2F;article&#x2F;egypt-cemetery-highways-cairo-city-dead-4b14e617e154fec1ec2dc34f5890d2c9&quot;&gt;widening roads at the expense of all else&lt;&#x2F;a&gt;.But all that is just kicking the can down the road instead of picking it up.&lt;&#x2F;p&gt;
&lt;p&gt;Cars inside cities are terrible as a &lt;em&gt;concept&lt;&#x2F;em&gt;. They are the absolute worst, least efficient way, to move people around a city (second only to a boat, perhaps.)&lt;&#x2F;p&gt;
&lt;p&gt;To illustrate the point, I invite you to watch &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=e_oWmY_mkCA&quot;&gt;this old car commercial&lt;&#x2F;a&gt;. Note how &lt;em&gt;empty&lt;&#x2F;em&gt; the world looks, with all that space that is taken away by cars could be instead used for pavements and trees and shops and housing and other humans. The ad is mwant, ironically, to advertise cars; but it only shows how ridiculous they are.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;lh6.googleusercontent.com&#x2F;8mgL-we3qQpMU7Uzf73fRdkfNggoHTbwDSIig6AT4BMB0jZqEXaEk3RVABFrlGv0Y0YGB1K4W2eoxQRG2m6QjS0UbzHX2TUmulYnq30ADeGXFRfrsoSU4ThGRkemA50g33UsNhI&quot; alt=&quot;humans and how much cards they need&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The irony of this is a self reinforcing cycle. The more cars you have, the more space you need of car infrastructure, the less space there is for actual useful humans things, the further everything is, the more you need cars.&lt;&#x2F;p&gt;
&lt;p&gt;Imagine all the additional space you could have in your city if there just was not any cars?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2.bp.blogspot.com&#x2F;-NTVK5-KUink&#x2F;Ud7SGpgh9jI&#x2F;AAAAAAAAAIE&#x2F;zRdHQnTZ-Pc&#x2F;s1600&#x2F;3olqub.jpg&quot; alt=&quot;so much room for activiites&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;any-examples&quot;&gt;Any Examples?&lt;&#x2F;h2&gt;
&lt;p&gt;Unfortunately, policy makers are generally very resistant to city humanization policies. There are many rational (and irrational) reasons for that. People do not like change. And people &lt;em&gt;love&lt;&#x2F;em&gt; their cars. Most importantly, infrastructure is expensive, and decades of sunk costs reinforce these positions. The solutions also require maintenance and long term policy commitments.&lt;&#x2F;p&gt;
&lt;p&gt;But there are plenty of positive examples of cities that have done a lot to make their streets walkable and human friendly, with various levels of commitment. This showcases that this is not an all or nothing position, (as much as I would like it to be an &quot;all&quot; position,) but someting to aspire to.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;chicago-the-l-and-the-parks&quot;&gt;Chicago, the L, and the Parks&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Chicago_%22L%22&quot;&gt;Chicago &quot;L&quot;&lt;&#x2F;a&gt; (known as the &#x27;L&#x27;) is one of the most successful examples around the world for a &quot;subway&quot;. It is integral to the walkability and ease of transit around the city, allowing residents to move anywhere within the city in walkable distance, aided by the system. [^suburbs]&lt;&#x2F;p&gt;
&lt;p&gt;[^suburbs:] No love for the Chicago suburbs, but that is really an all-american ailments that is not remedied at the City level but at the state or &quot;muhafaza&quot; level.&lt;&#x2F;p&gt;
&lt;p&gt;The L does not just connect the different sections of Chicago to each other, and to its downtown, the Loop (called so because there is Loop of L lines,) but it also connects them to the various huge &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Parks_in_Chicago&quot;&gt;parks around Chicago&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;cdn.choosechicago.com&#x2F;uploads&#x2F;2019&#x2F;08&#x2F;AA_Fall_MILPARK_01-900x612.jpg&quot; alt=&quot;The Bean&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The parks themselves are an important part of what makes Chicago a livable beautiful city. [The Burnham Park] (after legendary Chicago architect Daniel Burnham&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-devil-1&quot;&gt;&lt;a href=&quot;#fn-devil&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;) on the lakefron is a place for residents and tourists alike. Other parks like the Millenium Park and the Jackson Park celebrate famous historical events in the city. Not unlike the Sword of Damascus, really.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;riyadh&quot;&gt;Riyadh&lt;&#x2F;h3&gt;
&lt;p&gt;The City of Riyadh, capital of Saudi Arabia, is as dependent on cars a city can be. It is one of the least dense cities in the world, where it is virtually impossible to exist without a car, or without paying exhoberant taxi fares. Road deadlocks are a regular fact of life.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.alriyadhcity.com&#x2F;wp-content&#x2F;uploads&#x2F;2023&#x2F;03&#x2F;%D9%88%D8%A7%D8%AF%D9%8A-%D8%AD%D9%86%D9%8A%D9%81%D9%87-%D8%A7%D9%84%D8%B1%D9%8A%D8%A7%D8%B62-566x360.jpg&quot; alt=&quot;Wadi Hanifa&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This has been, largely, due to the historical mistake (commonly attributed to Greek urban planner &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Constantinos_Apostolou_Doxiadis&quot;&gt;Doxiadis&lt;&#x2F;a&gt;) of expanding the city horizontally over the desert to the north instead of expanding around the various valleys and natural water sources that exist to the south. Riyadh (which is Arabic for &quot;Gardens&quot;) is actually green. It has pelnty of natural parks, but the development on the city, and the rapid expansion (aided by cars) has led to the poor state of the city as it is today.&lt;&#x2F;p&gt;
&lt;p&gt;However, the Municipality of Riyadh has over the last decade been meaning to change that, and to remake Riyadh into a beautiful walkable cty that is fit for her name. The natural parks around the city (such as Wadi Hanifa and Wadi Namar) have been developed to become regular resident spots. The massvie Riyadh Metro development that took over the city (which was not without its pains) has finally launched last year, has done much to improve the walkability and reach of the various parts of the city and, to paraphrase one news article, &quot;Promore walking culture amoung Saudis&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Even the desert, horizontal parts of Riyadh are being developed. The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rcrc.gov.sa&#x2F;ar&#x2F;projects&#x2F;green-riyadh&#x2F;&quot;&gt;Green Riyadh&lt;&#x2F;a&gt; is planning to plant around 7.5 million trees around mosques and schools and shopping malls. The grand avenues of the city (like Olaya and Tahlia) are frequent hanging out spots. Changes to the building code in Wadi Hanifa and north of the city are emphasisng denser development. Paid street level parking is being introduced all over to discourage car abandonment on streets.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.al-jazirah.com&#x2F;2020&#x2F;20200222&#x2F;ln_29_1.jpg&quot; alt=&quot;Riyadh Basta&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Mind that this is not a quick and painless work. There have a lot of pains around the redevelopment (and redevelopment of redevelopment) of Riyadh that caused a lot of busienesses and areas to wither and suffer during it. The Riyadh Metro project was undertaken all at once, in the way only Saudi Arabia could, istead of stages. Similarly with the current ongoing Green Riyadh and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sportsboulevard.sa&#x2F;ar&#x2F;&quot;&gt;Sports Boulevard&lt;&#x2F;a&gt; shutting down many businesses and areas during the work. But the benefites from the already done projects and the projected benefits of the ones about to conclude are worth it. Riyadh is actually becoming quite pleasant to live in.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;issues-and-challenges&quot;&gt;Issues and Challenges&lt;&#x2F;h2&gt;
&lt;p&gt;These positions require a lasting policy commitment that recognizes their long term value. People respond to economic incentives, not to long term quality of life ones. If going around the city in a single occupant car is more economically viable (cheaper) than riding the metro, then people will do that. The improvement of public transport and city walkability should coincide with making cars harder and more annoying to use: restricted parking, road tolls (both of which actually help with public service maintenance) are two tools that can be used effectively to do that.&lt;&#x2F;p&gt;
&lt;p&gt;The need to start planning this is &lt;em&gt;right now&lt;&#x2F;em&gt;. Public transport and urban design take an incredibly long time to design and execute and maintain. Public and policy support should be cultivated and used to support such projects, and view public transport and proper, walkable streets as a &lt;em&gt;necessity&lt;&#x2F;em&gt;, not a luxury.&lt;&#x2F;p&gt;
&lt;p&gt;in Syria, the silver lining is that the bandaid is already ripped off: The infrastrudtcure is destroyed. There is no sunk cost any more, but we need to start planning &lt;em&gt;now&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Aleppo has plenty of public parks and wide streets and beautiful features. Did you know Aleppo has a river in it that flows through the city center? Connections around the city with an elevated sytem like Chiago&#x27;s would help reduce transport and petrol costs for residents. It would be easier to the Citadel from Nile Street or Hamdania without an expensive cab. Excessively wide streets (like Faisal Road, which is one-direction anyway) and and excessively narrow ones (like the roundabout around the Citadel) could beasily transformed into human-first spaces.&lt;&#x2F;p&gt;
&lt;p&gt;However, what actually prompted me to write this piece is this image of Damascus:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;cdn.24.co.za&#x2F;files&#x2F;Cms&#x2F;General&#x2F;d&#x2F;12395&#x2F;0bdde630a4c74f01a4034f934056c537.jpg&quot; alt=&quot;Umayad Square&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Imagine this beautiful grand space without cars or asphalt. How buatiful would that shot have been?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;additional-reading-and-viewing&quot;&gt;Additional Reading and Viewing&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=WmGKZFzJcoM&quot;&gt;(Arabic) Sharik Podcast: Meeting with Abdul Rahman al-Sayel: City Humanization and Sustainabolty&lt;&#x2F;a&gt;. Al-Sayel&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;x.com&#x2F;alsayel&quot;&gt;Twitter account&lt;&#x2F;a&gt; is a worth a follow.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.pps.org&#x2F;article&#x2F;what-is-placemaking&quot;&gt;(English) What is Placemaking, Project for Publix Spaces&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;If you don&#x27;t mind the vulgarity: the subreddit &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;fuckcars&#x2F;wiki&#x2F;faq&#x2F;#wiki_why_does_this_sub_hate_cars.3F&quot;&gt;r&#x2F;fuckcars&lt;&#x2F;a&gt; has a nice write up with additional resouces.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-devil&quot;&gt;
&lt;p&gt;Protagonist of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;The_Devil_in_the_White_City&quot;&gt;The Devil in the White City&lt;&#x2F;a&gt;. &lt;a href=&quot;#fr-devil-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Parsing Hearthstone Deck Codes</title>
        <published>2024-11-14T00:00:00+00:00</published>
        <updated>2024-11-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/thoughts/parsing-hearthstone-deck-codes/"/>
        <id>https://ar-ms.me/thoughts/parsing-hearthstone-deck-codes/</id>
        
        <content type="html" xml:base="https://ar-ms.me/thoughts/parsing-hearthstone-deck-codes/">&lt;p&gt;In the last few days I have been mucking around with &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;projects&#x2F;mimiron-discord-bot&#x2F;&quot;&gt;&lt;code&gt;Mimiron&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, my Hearthstone API library and Discord bot. One of the main functions of the bot, and the one it is used for the most, is parsing Hearhstone deck codes and presenting them in a pretty fashion.&lt;&#x2F;p&gt;
&lt;p&gt;I had a working parser for a while, but I wanted to experiment with it so I decided to rewrite it in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;nom&#x2F;latest&#x2F;nom&#x2F;&quot;&gt;nom&lt;&#x2F;a&gt;. Here are both parsers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;deck-code-format&quot;&gt;Deck Code Format&lt;&#x2F;h2&gt;
&lt;p&gt;The deck code fromat is explained &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hearthsim.info&#x2F;docs&#x2F;deckstrings&#x2F;&quot;&gt;by HearthSim&lt;&#x2F;a&gt;, the company behind &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hsreplay.net&quot;&gt;HSReplay&lt;&#x2F;a&gt; As far as I know, there is no official specification of deck codes encoding, so HearthSim&#x27;s description is what everyone relies on. The page is actually outdated, but their example implementations (in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;HearthSim&#x2F;HearthDb&#x2F;blob&#x2F;5258360a9c0411334e4f5a6dcb876b085d89cd3a&#x2F;HearthDb&#x2F;Deckstrings&#x2F;DeckSerializer.cs#L169&quot;&gt;C#&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;HearthSim&#x2F;python-hearthstone&#x2F;blob&#x2F;82e7c71ebdb6c8521b168d6f0ca418ff56e0fd5d&#x2F;hearthstone&#x2F;deckstrings.py#L109&quot;&gt;Python&lt;&#x2F;a&gt;, and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;HearthSim&#x2F;hearthstone-deckstrings&#x2F;blob&#x2F;6fa4d9cb896841a6246130a59b52a7cf752ca69f&#x2F;src&#x2F;index.ts#L123&quot;&gt;TypeScript&lt;&#x2F;a&gt;) explain it clearly enough.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The deck code is essentially a &lt;code&gt;base64&lt;&#x2F;code&gt; encoded series of integers.&lt;&#x2F;li&gt;
&lt;li&gt;These integers are encoded as unsigned &lt;code&gt;varint&lt;&#x2F;code&gt;s, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Variable-length_quantity&quot;&gt;variable width integers&lt;&#x2F;a&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-wikipedia-1&quot;&gt;&lt;a href=&quot;#fn-wikipedia&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The first two integers are always &lt;code&gt;0&lt;&#x2F;code&gt; and &lt;code&gt;1&lt;&#x2F;code&gt;. They happen to be a byte each, simplifying matters.&lt;&#x2F;li&gt;
&lt;li&gt;The third integer is the Format. &lt;code&gt;1&lt;&#x2F;code&gt; is Wild, &lt;code&gt;2&lt;&#x2F;code&gt; is Standard, &lt;code&gt;3&lt;&#x2F;code&gt; is Classic, and &lt;code&gt;4&lt;&#x2F;code&gt; is Twist.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;After &lt;code&gt;Format&lt;&#x2F;code&gt;, every block of integers starts with a count, then a listing of items, usually Card IDs (often called DBF IDs). Card IDs are unique numerical IDs that uniquely&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-cardid-1&quot;&gt;&lt;a href=&quot;#fn-cardid&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; identify each card in the game. The blocks are as follows:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Hero. Conveniently, this block only ever has one element.&lt;&#x2F;li&gt;
&lt;li&gt;Single-copy cards.&lt;&#x2F;li&gt;
&lt;li&gt;Double-copy cards.&lt;&#x2F;li&gt;
&lt;li&gt;N-copy cards. Each item in this block is a Card ID followed a by a count. This is only used for weird one-off formats or Arena codes.&lt;&#x2F;li&gt;
&lt;li&gt;A block of blocks? Unclear.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The block of blocks is not clearly documented. Sussing it out from existing parsers, it only has one item, which is the Sideboard block. The Sideboard block starts with a count, as usual, but each item is a pair of Card IDs. The first is the card itself, and the second is the Card ID of the Card it is &lt;em&gt;under&lt;&#x2F;em&gt;. There are, as of this time, only two Sideboard cards in the game.&lt;&#x2F;p&gt;
&lt;p&gt;After that is whatever. It apparently does not matter. It seems to usually be two &lt;code&gt;0&lt;&#x2F;code&gt;s? hitherto undefined blocks? WHo knows.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;example&quot;&gt;Example&lt;&#x2F;h3&gt;
&lt;p&gt;Take this deck code for example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;AAECAdrJBgbHpAaopQbUpQaX4Qat4Qaq6gYM5p4GpKcGqKcG66kGw74GzsAG0MAG0dAGmOEGmOIG5OoGjfgGAAED9bMGx6QG97MGx6QG6N4Gx6QGAAA=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is the list of numbers it represents, with comments.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;       # Format&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;107738&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;  # Hero ID&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;       # Single Copy IDs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;102983&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;  # &amp;lt;-- Note this ID is the same as the Sidebaord Card later.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;103080&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;103124&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;110743&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;110765&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;111914&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;12&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;      # Double Copy IDs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;102246&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;103332&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;103336&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;103659&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;106307&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;106574&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;106576&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;108625&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;110744&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;110872&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;111972&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;113677&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;       # N-Copy IDs. This is only used in weird formats.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;       # no idea really&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;       # Sideboard IDs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;104949&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;102983&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;104951&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;  # first part of pair: Card IN Sideboard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;102983&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;  # The Sideboard Card&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;110440&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;102983&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;       # who knows? Future proofing maybe?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It is a very simple format really.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;desired-output-and-shared-elements&quot;&gt;Desired Output and Shared Elements&lt;&#x2F;h2&gt;
&lt;p&gt;This is the Object which I need to fill up.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Data&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    format&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Format&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    hero&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: usize&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cards&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    sideboard_cards&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And this is the &lt;code&gt;Format&lt;&#x2F;code&gt; type with its conversion from a &lt;code&gt;usize&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;#[derive(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Default&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Format&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Standard&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;    #[default]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Wild&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Classic&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Twist&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;TryFrom&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Format&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    type&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; ();&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Petend it is something useful.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span&gt; try_from(value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: usize&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-self&quot;&gt;Self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-self&quot;&gt; Self&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type z-result&quot;&gt;        Ok&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;match&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; value {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;            1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-self&quot;&gt; Self&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Wild&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;            2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-self&quot;&gt; Self&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Standard&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;            3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-self&quot;&gt; Self&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Classic&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;            4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-self&quot;&gt; Self&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Twist&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-entity z-name z-type z-result&quot;&gt; return Err&lt;&#x2F;span&gt;&lt;span&gt;(()),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;        })&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To be able to implement and test the different parsers without much of the surrounding code interfering with it, I decided to wrap the whole thing into a tiny executable to be able to pass the codes directly on the command line. I&#x27;d also need the &lt;code&gt;base64&lt;&#x2F;code&gt; crate.&lt;&#x2F;p&gt;
&lt;p&gt;This is the venerable &lt;code&gt;Cargo.toml&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;toml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[package]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;name =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;deck_parser&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;version =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;0.1.0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;edition =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;2021&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[dependencies]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;base64 =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;0.22.1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pico-args =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;0.5.0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;# more to xome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And this is &lt;code&gt;main.rs&lt;&#x2F;code&gt;, without the types defined above:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;use&lt;&#x2F;span&gt;&lt;span&gt; base64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;{prelude&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;BASE64_STANDARD&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Engine&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;use&lt;&#x2F;span&gt;&lt;span&gt; pico_args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Arguments&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; main() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;    let mut&lt;&#x2F;span&gt;&lt;span&gt; args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Arguments&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from_env();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; raw&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;contains(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;--raw&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-entity z-name z-type z-result&quot;&gt;    let Ok&lt;&#x2F;span&gt;&lt;span&gt;(decoded)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;free_from_fn(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; BASE64_STANDARD&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;decode(s))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;        eprintln!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;Not base64 encoded&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        std&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;process&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;exit(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; raw {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        print_nums(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;decoded);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; print_data(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;decoded)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;is_err() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;            eprintln!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;Invalid Deck Code&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            std&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;process&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;exit(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; Print the List of Numbers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; print_nums(decoded&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;]) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;    todo!&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; Print the Raw Data obejct.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; print_data(decoded&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;(),&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;dyn&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;    todo!&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;--raw&lt;&#x2F;code&gt; flag is mostly to test the &lt;code&gt;varint&lt;&#x2F;code&gt; reader, and check it always gets the same output.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;straightforward-parser&quot;&gt;Straightforward Parser&lt;&#x2F;h2&gt;
&lt;p&gt;This is the first parser that I implemented. I used the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;integer-encoding&#x2F;latest&#x2F;integer_encoding&#x2F;&quot;&gt;&lt;code&gt;integer_encoding&lt;&#x2F;code&gt; crate&lt;&#x2F;a&gt; because I did not want to think about how &lt;code&gt;varint&lt;&#x2F;code&gt; encoding works, and it presents a nice API. It required wrapping the buffer in a &lt;code&gt;std::io::Cursor&lt;&#x2F;code&gt;, but that was it. It reads right from there.&lt;&#x2F;p&gt;
&lt;p&gt;Consdiering the &lt;code&gt;varint&lt;&#x2F;code&gt; parsing is relegated to a crate, &lt;code&gt;print_nums&lt;&#x2F;code&gt; is fairly straightforward.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;use&lt;&#x2F;span&gt;&lt;span&gt; integer_encoding&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;VarIntReader&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; way at the top of the file.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;use&lt;&#x2F;span&gt;&lt;span&gt; std&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;io&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Cursor&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; print_nums(decoded&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;]) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;    let mut&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Cursor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(decoded);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-storage z-type z-entity z-name z-type z-result&quot;&gt;    while let Ok&lt;&#x2F;span&gt;&lt;span&gt;(n)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;read_varint&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;        println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{n}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And one can quickly test that it works with the following command. Should you run it with the deck code earlier, you will find it lists the same numbers.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cargo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; run&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -- --raw&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;insert-deck-code-her&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Excellent. This means that &lt;code&gt;integer_encoding&lt;&#x2F;code&gt; does its job splendidly.&lt;&#x2F;p&gt;
&lt;p&gt;The second one is a bit more involved, but also fairly straightforward. &lt;code&gt;read_varint&lt;&#x2F;code&gt; advances the &lt;code&gt;Cursor&lt;&#x2F;code&gt;, so all that is needed is to assign the values in the correct order. There is a small footgun hiding in the API, however, which is that unsigned &lt;code&gt;varint&lt;&#x2F;code&gt;s have a different encoding for signed &lt;code&gt;varint&lt;&#x2F;code&gt;s. Considering literals are, by default, &lt;code&gt;i32&lt;&#x2F;code&gt;, Rust&#x27;s type inference works against you here.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; print_data(decoded&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;(),&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;dyn&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;    let mut&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Cursor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;decoded);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Format is the third number.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;set_position(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; format&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span&gt;read_varint&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span&gt;try_into()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span&gt;unwrap_or_default();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Hero ID is the fifth number.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;set_position(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; hero&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;read_varint()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;    let mut&lt;&#x2F;span&gt;&lt;span&gt; cards&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Single copy cards&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;read_varint()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0_&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-keyword z-operator&quot;&gt;usize..&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;count {&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- Type Inference footgun!!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;read_varint()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cards&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;push(id);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Double copy cards&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;read_varint()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0_&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-keyword z-operator&quot;&gt;usize..&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;count {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;read_varint()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cards&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;push(id);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cards&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;push(id);&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; twice&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; N-copy cards&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;read_varint()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0_&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-keyword z-operator&quot;&gt;usize..&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;count {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;read_varint()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;read_varint()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0_&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-keyword z-operator&quot;&gt;usize..&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;n {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            cards&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;push(id);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Sideboard cards. Are they always available?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;    let mut&lt;&#x2F;span&gt;&lt;span&gt; sideboard_cards&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;read_varint&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;is_ok_and(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;read_varint()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0_&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-keyword z-operator&quot;&gt;usize..&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;count {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;            let&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;read_varint()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;            let&lt;&#x2F;span&gt;&lt;span&gt; sb_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;read_varint()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            sideboard_cards&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;push((id, sb_id));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Data&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        format,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        hero,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cards,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        sideboard_cards,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;    println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{:#?}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, result);&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Don&amp;#39;t forget to dervie Debug&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type z-result&quot;&gt;    Ok&lt;&#x2F;span&gt;&lt;span&gt;(())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Not a very pretty printing. But it works. Good base implementation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;unsigned-variable-integers&quot;&gt;Unsigned Variable Integers&lt;&#x2F;h2&gt;
&lt;p&gt;When I started trying to rewrite the parser in &lt;code&gt;nom&lt;&#x2F;code&gt;, I looked for an extension &lt;code&gt;nom&lt;&#x2F;code&gt; crate that can read &lt;code&gt;varint&lt;&#x2F;code&gt;s. I found two! Reading through their source, however, I realized that it is really simple, and decided to bring it in the code base myself.&lt;&#x2F;p&gt;
&lt;p&gt;Unsigned &lt;code&gt;varint&lt;&#x2F;code&gt;s&#x27; encoding is, as it turned out, fairly simple. Honestly it is actually easier to just show the code than explain how the encoding works.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_varint(input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Option&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; a usize can only be as big as 9 bytes in varint encoding&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; MAX_BYTES&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric z-keyword z-operator z-assignment&quot;&gt;: usize =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;    let mut&lt;&#x2F;span&gt;&lt;span&gt; num&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; (idx,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;byte)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;iter()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;take(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;MAX_BYTES&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;enumerate() {  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; 7 bits from each byte are used&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; byte&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; byte&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-keyword z-operator&quot;&gt; usize &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x7F&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        num&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; byte&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; offset;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; The last byte&amp;#39;s most significant bit is 0.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; byte&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x80&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-entity z-name z-type z-option&quot;&gt;            return Some&lt;&#x2F;span&gt;&lt;span&gt;(num);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type z-option&quot;&gt;    None&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Insufficient data or overflow&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Signed &lt;code&gt;varint&lt;&#x2F;code&gt;s are a whole other beast, and they do not concern this article outside of the type inference footgun from the previous section.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;nom-parser&quot;&gt;&lt;code&gt;nom&lt;&#x2F;code&gt; Parser&lt;&#x2F;h2&gt;
&lt;p&gt;This is what actually prompted writing this article.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-nom-1&quot;&gt;&lt;a href=&quot;#fn-nom&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; I already used &lt;code&gt;nom&lt;&#x2F;code&gt; elsewhere in &lt;code&gt;Mimiron&lt;&#x2F;code&gt;, and I wanted to exercise more with it.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;nom&lt;&#x2F;code&gt; way is all about small, composable functions. The clearest small composable function to do is &lt;code&gt;parse_varint&lt;&#x2F;code&gt;. I am not going to use the imperative version shown above, I am writing one using &lt;code&gt;nom&lt;&#x2F;code&gt;&#x27;s parser combinators and the standard library&#x27;s &lt;code&gt;Iterator&lt;&#x2F;code&gt; combinators.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; no nom codebase is complete without a giant use statement on top&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; this includes combinators for all the functions below&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;use&lt;&#x2F;span&gt;&lt;span&gt; nom&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;complete&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        take,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;      &#x2F;&#x2F; takes a number of bytes unconditionally&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        take_till,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; takes until a condition is met and stops before&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    combinator&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cond,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;      &#x2F;&#x2F; calls a parser only if a condition is met&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        map,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;       &#x2F;&#x2F; maps the result of a parser&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        map_opt,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;   &#x2F;&#x2F; maps the result of a parser to an Option&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        opt,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;       &#x2F;&#x2F; optional parser, for a value. returns Option&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        verify,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; verifies the result satisfies a condition&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    multi&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        length_count,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; gets a number from first parser,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                      &#x2F;&#x2F; then applies second parser that many times&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        many0,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; repeats a parser until it fails. returns Vec&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    sequence&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        pair,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;       &#x2F;&#x2F; call first parser, then second parser.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        preceded,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;   &#x2F;&#x2F; discards result of first parser&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tuple,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;      &#x2F;&#x2F; same as pair, but up to 21 separate parsers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;IResult&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; nom&amp;#39;s Result type.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                    &#x2F;&#x2F; Returns remaining input and successful results&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                    &#x2F;&#x2F; or an error with the input inside the Error.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_varint(input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;IResult&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; is_last&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-logical&quot;&gt; = |&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x80&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; is_in_bounds&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-logical&quot;&gt; = |&lt;&#x2F;span&gt;&lt;span&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;len() &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; try_varint&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator z-logical&quot;&gt; = |&lt;&#x2F;span&gt;&lt;span&gt;(p, lb)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; this is the same imperative code up above with some error checking&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;iter()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;            .&lt;&#x2F;span&gt;&lt;span&gt;chain(lb)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;            .&lt;&#x2F;span&gt;&lt;span&gt;enumerate()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;            .&lt;&#x2F;span&gt;&lt;span&gt;try_fold(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt;acc, (idx, byte)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                ((&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;byte&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x7F&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                    .&lt;&#x2F;span&gt;&lt;span&gt;checked_shl(idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-keyword z-operator&quot;&gt; u32 *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                    .&lt;&#x2F;span&gt;&lt;span&gt;map(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; acc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt; n)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;            })&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    map_opt(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        pair(verify(take_till(is_last), is_in_bounds), take(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        try_varint,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )(input)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Same, but slightly more unreadable (I am going to have so much fun with this):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; parse_varint(input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;IResult&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    map_opt(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        pair(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            verify(take_till(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x80&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;len() &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            take(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;        |&lt;&#x2F;span&gt;&lt;span&gt;(p, lb)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;iter()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                .&lt;&#x2F;span&gt;&lt;span&gt;chain(lb)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                .&lt;&#x2F;span&gt;&lt;span&gt;enumerate()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                .&lt;&#x2F;span&gt;&lt;span&gt;try_fold(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt;acc, (idx, byte)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    ((&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;byte&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0x7F&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                        .&lt;&#x2F;span&gt;&lt;span&gt;checked_shl(idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-keyword z-operator&quot;&gt; u32 *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                        .&lt;&#x2F;span&gt;&lt;span&gt;map(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; acc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt; n)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;                })&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )(input)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Using this small function to generate the list of numbers, going straight for the unreadable verion:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; print_nums(decoded&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;]) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; many0(map(parse_varint,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt; println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{n}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)))(decoded);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The second function is a bit more involved, but it generally follows the structure of the previous section&#x27;s solution. I think it is easy enough to follow.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; print_data(decoded&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;(),&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;dyn&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-lifetime&quot;&gt;_&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; starting from 2 as Format is the third number.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; (rem, format)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; map(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        parse_varint,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;        |&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;try_into()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap_or_default()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;decoded[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; skip 1 byte for Hero ID.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; (rem, _)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; parse_varint(rem)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; (rem, hero)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; parse_varint(rem)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; (rem, cards)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; map(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tuple((&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F; single cards&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            length_count(parse_varint, parse_varint),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F; double cards&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            length_count(parse_varint, map(parse_varint,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; [id;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;])),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F; n-count cards&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            length_count(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                parse_varint,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                map(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    pair(parse_varint, parse_varint), &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    (id, n)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; [id]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;repeat(n)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;        |&lt;&#x2F;span&gt;&lt;span&gt;(v1, v2, vn)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            v1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;into_iter()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                .&lt;&#x2F;span&gt;&lt;span&gt;chain(v2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;into_iter()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;flatten())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                .&lt;&#x2F;span&gt;&lt;span&gt;chain(vn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;into_iter()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;flatten())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                .&lt;&#x2F;span&gt;&lt;span&gt;collect()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )(rem)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; (rem, c)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; opt(parse_varint)(rem)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; (_rem, sideboard_cards)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; map(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cond(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;is_some_and(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            length_count(parse_varint, pair(parse_varint, parse_varint)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Option&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;unwrap_or_default,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )(rem)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-super&quot;&gt; super&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Data&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        format,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        hero,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cards,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        sideboard_cards,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;    println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{result:#?}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type z-result&quot;&gt;    Ok&lt;&#x2F;span&gt;&lt;span&gt;(())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But this can be made worse: the whole thing can be collapsed into one function. &lt;code&gt;rustfmt&lt;&#x2F;code&gt; is pulling a lot of weight here, to be honest.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-bug-1&quot;&gt;&lt;a href=&quot;#fn-bug&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span&gt; print_data(decoded&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;(),&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;dyn&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-lifetime&quot;&gt;_&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; map(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tuple((&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            map(parse_varint,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;try_into()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap_or_default()),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            preceded(parse_varint, parse_varint),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            map(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                tuple((&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    length_count(parse_varint, parse_varint),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    length_count(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        parse_varint,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        map(parse_varint,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; [id;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    length_count(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        parse_varint,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        map(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                            pair(parse_varint, parse_varint),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;                            |&lt;&#x2F;span&gt;&lt;span&gt;(id, n)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; [id]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;repeat(n)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                )),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;                |&lt;&#x2F;span&gt;&lt;span&gt;(v1, v2, vn)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    v1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;into_iter()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                        .&lt;&#x2F;span&gt;&lt;span&gt;chain(v2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;into_iter()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;flatten())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                        .&lt;&#x2F;span&gt;&lt;span&gt;chain(vn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;into_iter()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;flatten())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                        .&lt;&#x2F;span&gt;&lt;span&gt;collect()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;                },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            preceded(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                verify(parse_varint,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-keyword z-operator&quot;&gt;| *&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                length_count(parse_varint, pair(parse_varint, parse_varint)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;        |&lt;&#x2F;span&gt;&lt;span&gt;(format, hero, cards, sideboard_cards)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Data&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            format,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            hero,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            cards,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            sideboard_cards,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;decoded[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt;    println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;{:#?}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, result);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type z-result&quot;&gt;    Ok&lt;&#x2F;span&gt;&lt;span&gt;(())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;One tiny thing before the end. Note the &lt;code&gt;+&#x27;_&lt;&#x2F;code&gt; bound on the return type. Since &lt;code&gt;nom&lt;&#x2F;code&gt;&#x27;s errors contain the input, which is a reference, converting the errors can sometimes cause Rust&#x27;s type inference to declare that your functions expect a &lt;code&gt;&#x27;static&lt;&#x2F;code&gt; lifetime. For example, here, when the &lt;code&gt;+&#x27;_&lt;&#x2F;code&gt; bound is removed, or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;rust&#x2F;comments&#x2F;1goc61r&#x2F;nom_implemented_parser_is_demanding_i_use_a&#x2F;&quot;&gt;when converting &lt;code&gt;nom&lt;&#x2F;code&gt;&#x27;s errors to &lt;code&gt;anyhow&lt;&#x2F;code&gt;&#x27;s errors using the &lt;code&gt;?&lt;&#x2F;code&gt; operator.&lt;&#x2F;a&gt;. It is not a footgun, per se, as the compiler yells at you. But the error is frankly inscrutable unless you know what you are looking for.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;final-thoughts&quot;&gt;Final Thoughts&lt;&#x2F;h2&gt;
&lt;p&gt;Rewriting in nom was a bit easier than I thought it would be. And even the compact &quot;one-liner&quot; is more readable than I thought. The hardest part is probably how to translate the problem into &lt;code&gt;nom&lt;&#x2F;code&gt;&#x27;s API. (Which I struggled with when I considered using &lt;code&gt;nom&lt;&#x2F;code&gt; for &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;adventofcode.com&quot;&gt;Advent of Code&lt;&#x2F;a&gt;). Who knows? Maybe this year.&lt;&#x2F;p&gt;
&lt;p&gt;If you would like to do this with another Rust parser library (&lt;code&gt;chumsky&lt;&#x2F;code&gt; or &lt;code&gt;winnow&lt;&#x2F;code&gt; or &lt;code&gt;combine&lt;&#x2F;code&gt; or &lt;code&gt;pest&lt;&#x2F;code&gt;), please do share, and I will happily link it here.&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-wikipedia&quot;&gt;
&lt;p&gt;This Wikipedia page gives a terrible and obtuse explanation. The implementation turned out to very simple. &lt;a href=&quot;#fr-wikipedia-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-cardid&quot;&gt;
&lt;p&gt;IDs can be deleted from the game, leading to outdated deck codes out there, but that&#x27;s out of scope of this article. In &lt;code&gt;Mimiron&lt;&#x2F;code&gt;, I work around that by looking them up in the third party database everyone else uses: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hearthstonejson.com&quot;&gt;HearthSim&#x27;s&lt;&#x2F;a&gt;, and &quot;canonizing&quot; the IDs. My bot is somewhat unique for relying first on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;develop.battle.net&#x2F;documentation&quot;&gt;Blizzard&#x27;s official API&lt;&#x2F;a&gt;. &lt;a href=&quot;#fr-cardid-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-nom&quot;&gt;
&lt;p&gt;If you are somehow this far into this post and do not know what &lt;code&gt;nom&lt;&#x2F;code&gt; is, it is a Rust parser combinator library, probably the first and most famous. &lt;em&gt;Combinators&lt;&#x2F;em&gt; are small higher order functions (read: functions that can take and&#x2F;or output other functions: function functions, if you will), that can be composed together. Parser Combinator Libraries are, in a way, their own Domain Specific Language. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;nom&#x2F;latest&#x2F;nom&#x2F;#parser-combinators&quot;&gt;&lt;code&gt;nom&lt;&#x2F;code&gt;&#x27;s documentation has a nice intro&lt;&#x2F;a&gt;. &lt;a href=&quot;#fr-nom-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-bug&quot;&gt;
&lt;p&gt;2024-11-26 update: I found out that this code has a bug: it rejects valid decks without a sideboard. How would one fix that? &lt;a href=&quot;#fr-bug-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Hanging Gardens Problem</title>
        <published>2024-10-17T00:00:00+00:00</published>
        <updated>2024-10-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/thoughts/the-hanging-gardens-problem/"/>
        <id>https://ar-ms.me/thoughts/the-hanging-gardens-problem/</id>
        
        <content type="html" xml:base="https://ar-ms.me/thoughts/the-hanging-gardens-problem/">&lt;p&gt;This is an interesting puzzle inspired by Christian Freeling&#x27;s tile set &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mindsports.nl&#x2F;index.php&#x2F;puzzles&#x2F;3d&#x2F;394-the-china-cube&quot;&gt;The China Cube&lt;&#x2F;a&gt;. As it really has nothing to do with China, I call it &lt;strong&gt;the Hanging Gardens Problem&lt;&#x2F;strong&gt;. Imagine each cube as a section of the Garden, and connections to other cubes are paths and stairways.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Here is a nice drawing showing the full set of 64 Cubes, from Freeling&#x27;s site.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-hanging-gardens-problem&#x2F;cubeset.gif&quot; alt=&quot;The full set of Cubes&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;problem-formulation&quot;&gt;Problem Formulation&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;There are 64 cubes.&lt;&#x2F;li&gt;
&lt;li&gt;Each cube is unique.&lt;&#x2F;li&gt;
&lt;li&gt;Each cube has a specific number of Red and Blue faces.&lt;&#x2F;li&gt;
&lt;li&gt;Cubes do not rotate or change orientation in anyway.&lt;&#x2F;li&gt;
&lt;li&gt;Direction of the faces is specific: North, East, South, West, Top, Bottom.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It follows from these that there is&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;One cube with all Red faces (the Red cube, bottom Cube in the earlier drawing.)&lt;&#x2F;li&gt;
&lt;li&gt;One cube with all Blue faces (the Blue cube, top Cube in the earlier drawing)&lt;&#x2F;li&gt;
&lt;li&gt;Six cubes with one Red face.&lt;&#x2F;li&gt;
&lt;li&gt;Six cubes with one Blue face.&lt;&#x2F;li&gt;
&lt;li&gt;... etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;All possible permutations of Red and Blue faces are represented (hence 64 cubes).&lt;&#x2F;p&gt;
&lt;p&gt;Here is the puzzle: &lt;strong&gt;Assemble the cubes so the Blue faces touch each other, and all the Red faces are exposed.&lt;&#x2F;strong&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;#fn-2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In other words, a Blue face must always face, touching, another Blue face. A Red face must not do that. However, a Red face might wave to another Red face from a distance (at least one cube far.)&lt;&#x2F;p&gt;
&lt;p&gt;There is most likely is a solution.&lt;&#x2F;p&gt;
&lt;p&gt;The solution does not have to be one big shape. It actually &lt;em&gt;cannot&lt;&#x2F;em&gt;, because of the Red Cube.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;tl;dr&lt;&#x2F;strong&gt; I gave up on the problem due to time and memory constraints. However, while I was at it, I found solutions to two, equally interesting, sub problems, and nice graphics.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;wave-function-collapse&quot;&gt;Wave Function Collapse&lt;&#x2F;h2&gt;
&lt;p&gt;I asked around in a number of Discord servers on how to approach solving the problem programmatically, outside of 3-D printing the set and physically assembling it by hand. The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gorillasun.de&quot;&gt;Gorilla Sun&lt;&#x2F;a&gt; Creative Coding server suggested that using the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mxgmn&#x2F;WaveFunctionCollapse&quot;&gt;Wave Function Collapse&lt;&#x2F;a&gt; algorithm might be the best fit for the problem, and suggested &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=rI_y2GAlQFM&quot;&gt;a very excellent Youtube video from the Coding Train&lt;&#x2F;a&gt; implementing the algorithm in Javascript. It is a &lt;em&gt;very&lt;&#x2F;em&gt; good video that I suggest watching.&lt;&#x2F;p&gt;
&lt;p&gt;As explained at the start of the video, this is simply the Sudoku solving algorithm, generalized to creating random tile sets. Apparently, the Quantum Mechanics inspired name is simply for flavor and searchability.&lt;&#x2F;p&gt;
&lt;p&gt;So, how does one solve a Sudoku?&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;First, identify the connection rules and the tile set. (Which, in Sudoku, need no explaining.)&lt;&#x2F;li&gt;
&lt;li&gt;Second, &lt;em&gt;Observation&lt;&#x2F;em&gt;: mark each empty cell in the grid with the candidate &lt;del&gt;tiles&lt;&#x2F;del&gt; numbers that go in them.&lt;&#x2F;li&gt;
&lt;li&gt;Third, the &lt;em&gt;Collapse&lt;&#x2F;em&gt; in Wave Function Collapse: identify the cells with the fewest number of candidates.
1. Any cell with 1 candidate &quot;collapses&quot; into that candidate, and the number is inked in.
2. &lt;em&gt;If there are not any cells with one candidate&lt;&#x2F;em&gt;, pick one cell with the fewest number of candidates and pick a candidate at random, &quot;collapsing&quot; it.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-1&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Fourth, &lt;em&gt;Propagation&lt;&#x2F;em&gt;: with the new state of things, update the candidates in each call. Here is where Sudoku people use X-wings and Swordfishes and what have you.&lt;&#x2F;li&gt;
&lt;li&gt;Repeat the &lt;em&gt;Collapse&lt;&#x2F;em&gt;, until the grid is full.&lt;&#x2F;li&gt;
&lt;li&gt;If there ever, after Propagation, a cell with &lt;em&gt;zero&lt;&#x2F;em&gt; candidates, this means an illegal state was reached. Either &lt;em&gt;Backtrack&lt;&#x2F;em&gt; to the last random choice, (and, well, choose another branch), or simply start the whole thing over.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This approach can work just fine for the Hanging Gardens. The Tile set and the connection rules are clearly defined. It is only a matter of putting it into code and .. running it. The problem most apparent to me, however, is that the search space is potentially &lt;em&gt;huge&lt;&#x2F;em&gt;. So, I first need to try this approach with a smaller problem set.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;square-gardens&quot;&gt;Square Gardens&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-hanging-gardens-problem&#x2F;.&#x2F;transcendental1-3.gif&quot; alt=&quot;Garden Squares&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Phrasing the problem in terms of Squares, and 2D connections, rather than Cubes, shrinks the problem space by an order of magnitude. Plus, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.mindsports.nl&#x2F;index.php&#x2F;puzzles&#x2F;tilings&#x2F;china-labyrinth&#x2F;&quot;&gt;there is a known solution given by Freeling&lt;&#x2F;a&gt;!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tiles-and-air&quot;&gt;Tiles and Air&lt;&#x2F;h3&gt;
&lt;p&gt;First, I need to formulate the tiles. There are two kinds of Tiles. The first kind is the actually Squares. This is a &lt;em&gt;finite&lt;&#x2F;em&gt; set. The second kind, is an &quot;Air&quot; tile. This empty tile is infinitely available, and is automatically placed at the Propagation phase connected to every Red face. A Red face &lt;em&gt;must&lt;&#x2F;em&gt; connect to an Air tile, and a Blue face can &lt;em&gt;never&lt;&#x2F;em&gt; connect to one. An Air tile can connect from any side to any Air tile with no restriction.&lt;&#x2F;p&gt;
&lt;p&gt;I am still having fun with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;odin-lang.org&quot;&gt;Odin&lt;&#x2F;a&gt;, so I will try this solution in it first. Here are the starting types:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Side&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; { North, East, South, West }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; distinct bit_set&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Side&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Air&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; distinct struct&lt;&#x2F;span&gt;&lt;span&gt; {}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Cell&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt; { Air, Tile }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I am not too happy about this because while the data can neatly fit into one byte, Odin puts this in two. This looks cleaner and easier to understand than weird hacks, so I will stick to it for the time being. Odin&#x27;s &lt;code&gt;union&lt;&#x2F;code&gt; is nice here, semantically, as it actually has three states: &lt;code&gt;nil&lt;&#x2F;code&gt;, &lt;code&gt;Air&lt;&#x2F;code&gt; and &lt;code&gt;Tile&lt;&#x2F;code&gt;, exactly as much as needed.&lt;&#x2F;p&gt;
&lt;p&gt;The Squares are only 16 (count them in the image above). It is possible to safely ignore the Red (unconnected) Square, because it can simply be put anywhere in space and does not need to connect to anything. Generating a list of the Squares is as simple as counting to 15, or &lt;code&gt;0xF&lt;&#x2F;code&gt;. Running the below snippet to confirm:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;main&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; () {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    list&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;dynamic&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Cell&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; u8(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0x1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0xF&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        fmt.println(transmute(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;)i)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        append(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;list, transmute(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;)i)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- Odin casting magic here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    fmt.println(len(list))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Prints the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Tile{North}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Tile{East}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Tile{North, East}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Tile{South}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Tile{North, South}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Tile{East, South}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Tile{North, East, South}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Tile{West}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Tile{North, West}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Tile{East, West}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Tile{North, East, West}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Tile{South, West}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Tile{North, South, West}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Tile{East, South, West}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Tile{North, East, South, West}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;15&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which is exactly what is needed. Hooray!!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;grid-and-candidates&quot;&gt;Grid and Candidates&lt;&#x2F;h3&gt;
&lt;p&gt;An infinite grid is infeasible due to being in a finite universe and using computers with finite resources. So what is a good size for a finite grid? There are 16 Tiles, so a 16 by 16 grid is a clear upper bound, and clearly too big, due to the impossibility of all squares being in one line. I will go with a 15 by 15 grid, which is also safe as it is too big, but it gives me a nice center cell to fix the Blue square in, and branch everywhere from there.&lt;&#x2F;p&gt;
&lt;p&gt;To track the candidates in each cell, the simplest option, perhaps, is to create a set of tiles. Since each tile corresponds neatly to a number (as per the &lt;code&gt;transmute&lt;&#x2F;code&gt; above,) simply tracking the numbers should be enough. As mentioned also, the Red square can be placed anywhere in space, so it does not need to be tracked. Giving its number, 0, to track the Air Tile should be enough, as it can later replace almost any Air tile in the final grid.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; distinct bit_set&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;; u16]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cells&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;      [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Cell&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; central cell is [7][7]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Candidates&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Having &lt;code&gt;candidates&lt;&#x2F;code&gt; in a separate field like that is convenient. Any cell with no candidates (a &lt;code&gt;nil&lt;&#x2F;code&gt; bit set), would signal an illegal position reached. Any cell with only one candidate is considered collapsed, and the collapse would then be reflected in the &lt;code&gt;cells&lt;&#x2F;code&gt; field, which represents the actual contents. All this, of course, is subject to be iterated out later.&lt;&#x2F;p&gt;
&lt;p&gt;This is the first draft of how to initialize the grid. Note that in Odin &lt;code&gt;~&lt;&#x2F;code&gt; is the bitwise &lt;code&gt;NOT&lt;&#x2F;code&gt; operator. So &lt;code&gt;~Candidates{15}&lt;&#x2F;code&gt; is the full set &lt;em&gt;except&lt;&#x2F;em&gt; for 15. And &lt;code&gt;~Tile{}&lt;&#x2F;code&gt; is the full set.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grid_init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Grid&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Blue Square&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ret.cells[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = ~&lt;&#x2F;span&gt;&lt;span&gt;Tile{}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Fill the Candidates Grid &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ret.candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = ~&lt;&#x2F;span&gt;&lt;span&gt;Candidates{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; broadcast magic&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ret.candidates[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;propagation&quot;&gt;Propagation&lt;&#x2F;h3&gt;
&lt;p&gt;An astute Sudoku solver would quickly be able to see that this initial list of candidates is, in fact, useless and incorrect. Yes it removes the placed Tile from all candidate positions, but it does &lt;em&gt;not&lt;&#x2F;em&gt; take into account the placed Tile&#x27;s connections.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-edges-1&quot;&gt;&lt;a href=&quot;#fn-edges&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; For this to work the Candidate grid must be updated to match the new reality.&lt;&#x2F;p&gt;
&lt;p&gt;It follows that for each placed &lt;code&gt;Cell&lt;&#x2F;code&gt; in &lt;code&gt;cells&lt;&#x2F;code&gt;, it must update the surrounding candidates. So a function that gives out the candidates per face is needed. This can almost just be hardcoded, since each number maps neatly to a specific square. It is possible to hardcode it for each tile individually, but where is the fun in that.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;Candidate_Set&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span&gt; [Side]Candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Enumerated arrays, a nice Odin feature.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tile_connections&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; (c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Cell&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Candidate_Set&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Why not just hardcode it all the way?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; c {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt; Tile: &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.North]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; .North&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.East]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; .East&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;  in&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.South]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; .South&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.West]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; .West&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;  in&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt; Air:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.North]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.East]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.South]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.West]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = ~&lt;&#x2F;span&gt;&lt;span&gt;{}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is nice, mainly because the &lt;code&gt;Candidates&lt;&#x2F;code&gt; type, being a bit set, can be &lt;code&gt;AND&lt;&#x2F;code&gt;ed together to quickly eliminate candidates from Cells in the relevant direction. This can be run for each new state in a loop (or maybe just twice) to propagate candidates of collapsed &lt;code&gt;Air&lt;&#x2F;code&gt; Cells.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;grid_propagate&lt;&#x2F;code&gt; procedure will have to do a few things. First, it should scan &lt;code&gt;cells&lt;&#x2F;code&gt; for known placements. If there is a known placement, update &lt;code&gt;candidates&lt;&#x2F;code&gt; accordingly. Then scan &lt;code&gt;candidates&lt;&#x2F;code&gt; for any collapsed cells (where there is only one left candidate), and update those in &lt;code&gt;cells&lt;&#x2F;code&gt; accordingly, then repeat. Assertions could be placed if a known placement in &lt;code&gt;cells&lt;&#x2F;code&gt; does not match a collapsed candidates set in &lt;code&gt;candidates&lt;&#x2F;code&gt;. An error would be returned if, during propagation, a &lt;code&gt;candidates&lt;&#x2F;code&gt; cell was found with 0 candidates, indicating an illegal branch reached.&lt;&#x2F;p&gt;
&lt;p&gt;After some trial and error and stack overflows and segmentation faults (due to said stack overflows), I settled on this recursive version It is probably not efficient, as it calculates the same thing multiple times, but it is the most straightforward way i could think of.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grid_propagate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; (grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Grid&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; bool {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Update candidates based on cells&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;15&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cell&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; grid.cells[x][y]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; tile_connections(cell)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; North&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[x][y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; tc[.North]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; East&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;][y]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; tc[.East]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; South&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[x][y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; tc[.South]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; West&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;][y]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; tc[.West]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; if cell is a tile, make sure it is not a candidate anywhere else.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; tile, ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; cell.(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;); ok {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F; Weird hack&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            cand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; Candidates{ int(transmute(u8)tile) }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F; remove it everywhere with broadcast magic&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; cand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F; then add it in the appropriate place&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.candidates[x][y]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    any_collapsed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Update cells based on candidates&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;15&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[x][y]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; cand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; {}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; illegal state reached&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; COLLAPSE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; obviously only a new collapse if it is not collapsed already&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; grid.cells[x][y]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; card(cand)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; cand {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            any_collapsed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F; What did actually collapse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.cells[x][y]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Air{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; transmute(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;)i8(id)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    success&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; any_collapsed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; success&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; grid_propagate(grid)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; recursion!!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; success&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then just update &lt;code&gt;grid_init&lt;&#x2F;code&gt; like this&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grid_init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; ()&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Grid&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Fill the Candidates Grid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ret.candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = ~&lt;&#x2F;span&gt;&lt;span&gt;Candidates{}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Place Blue square&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ret.cells[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = ~&lt;&#x2F;span&gt;&lt;span&gt;Tile{}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid_propagate(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;ret)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; ret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And it works, nicely! Place any of the Squares instead of &lt;code&gt;~Tile{}&lt;&#x2F;code&gt;, and it works correctly. Even propagates &lt;code&gt;Air&lt;&#x2F;code&gt; cells and their neighbors!!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;controlled-demolition&quot;&gt;Controlled Demolition&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;grid_propagate&lt;&#x2F;code&gt; procedure takes of care of collapsing cells with one candidate left. But as soon as right after the initial position, there are still many cells with unresolved state. That&#x27;s why Controlled Demolition is needed, to &lt;em&gt;force&lt;&#x2F;em&gt; things to collapse, randomly.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-metaphor-1&quot;&gt;&lt;a href=&quot;#fn-metaphor&quot;&gt;5&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The best candidates for Controlled Demolition are the cells with the least amount of candidates that are not already collapsed. That&#x27;s to say, the least amount of candidates more than 1. Recording these is probably easy. Choosing one randomly, with even chances all over, is, at first impression, not. It is easy to choose &lt;em&gt;arbitrarily&lt;&#x2F;em&gt;, but not necessarily randomly. If a robust backtracking algorithm exists, then arbitrary is probably better than random. But I do not currently plan to backtrack, but instead simply start over whenever an illegal position is encountered.&lt;&#x2F;p&gt;
&lt;p&gt;How should one go about this? With so much randomness, the probably most straightforward course of action is to randomize the indices 0-14 three times. The first two randomized arrays are to loop over &lt;code&gt;candidates&lt;&#x2F;code&gt; in a somewhat random order. The third one is to loop over the candidates in the final found cell, and collapse to the first one it matches over.&lt;&#x2F;p&gt;
&lt;p&gt;Sounds absolutely &lt;em&gt;boneheaded&lt;&#x2F;em&gt;, but it should work just fine.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grid_controlled_demolition&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; (grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Grid&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; bool {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; all the shuffling &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rows&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; []int{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rand.shuffle(rows)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cols&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; []int{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rand.shuffle(cols)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ids&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  :=&lt;&#x2F;span&gt;&lt;span&gt; []int{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rand.shuffle(ids)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; target collapse stored here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    t_x, t_y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; tracking the minimum&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    min_card&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; loop over the grid &amp;quot;randomly&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; cols&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; rows {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; card(grid.candidates[x][y])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_continue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; already collapsed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; min_card {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            t_x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            t_y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            min_card&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; min_card&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do break&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; no point in looking further&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; loop over the set flags randomly and collapse to the first match.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; ids&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do if&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[t_x][t_y] {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; COLLAPSE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.cells[t_x][t_y]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Air{}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.candidates[t_x][t_y]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; transmute(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;)i8(id)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            cand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; Candidates{ int(transmute(u8)tile) }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.cells[t_x][t_y]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; cand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.candidates[t_x][t_y]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        } &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; then propagate the new changes, returning the legality result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; grid_propagate(grid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This should be enough? Calling &lt;code&gt;grid_controlled_demolition&lt;&#x2F;code&gt; a couple of times seems to produce the expected result.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;main&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; () {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; grid_init()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; crude &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid_controlled_demolition(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;grid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid_controlled_demolition(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;grid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid_controlled_demolition(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;grid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid_controlled_demolition(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;grid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid_controlled_demolition(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;grid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; row, ri&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; c, ci&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; row {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        fmt.println(ri, ci, c)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;details&gt; &lt;summary&gt;Sample output.&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0 0 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0 1 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0 2 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0 3 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0 4 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0 5 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0 6 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0 7 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0 8 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0 9 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0 10 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0 11 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0 12 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0 13 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0 14 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1 0 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1 1 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1 2 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1 3 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1 4 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1 5 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1 6 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1 7 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1 8 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1 9 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1 10 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1 11 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1 12 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1 13 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1 14 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2 0 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2 1 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2 2 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2 3 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2 4 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2 5 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2 6 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2 7 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2 8 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2 9 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2 10 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2 11 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2 12 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2 13 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2 14 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3 0 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3 1 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3 2 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3 3 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3 4 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3 5 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3 6 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3 7 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3 8 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3 9 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3 10 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3 11 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3 12 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3 13 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3 14 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4 0 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4 1 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4 2 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4 3 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4 4 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4 5 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4 6 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4 7 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4 8 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4 9 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4 10 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4 11 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4 12 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4 13 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4 14 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5 0 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5 1 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5 2 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5 3 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5 4 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5 5 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5 6 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5 7 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5 8 Candidates{0, 1, 4, 8, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5 9 Candidates{2, 3, 7, 10, 11}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5 10 Candidates{2, 3, 7, 10, 11}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5 11 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5 12 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5 13 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5 14 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6 0 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6 1 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6 2 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6 3 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6 4 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6 5 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6 6 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6 7 Candidates{0, 2, 4, 8, 10, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6 8 Candidates{0}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6 9 Candidates{9}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6 10 Candidates{13}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6 11 Candidates{4, 7, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6 12 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6 13 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6 14 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7 0 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7 1 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7 2 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7 3 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7 4 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7 5 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7 6 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7 7 Candidates{1, 3, 7, 11}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7 8 Candidates{6}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7 9 Candidates{0}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7 10 Candidates{0}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7 11 Candidates{0, 1, 2, 3, 8, 10, 11}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7 12 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7 13 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7 14 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8 0 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8 1 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8 2 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8 3 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8 4 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8 5 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8 6 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8 7 Candidates{1, 3, 7, 11}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8 8 Candidates{15}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8 9 Candidates{5}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8 10 Candidates{4, 7}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8 11 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8 12 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8 13 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8 14 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9 0 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9 1 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9 2 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9 3 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9 4 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9 5 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9 6 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9 7 Candidates{1, 3, 7, 11}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9 8 Candidates{14}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9 9 Candidates{0}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9 10 Candidates{0, 1, 2, 3, 8, 10, 11}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9 11 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9 12 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9 13 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9 14 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;10 0 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;10 1 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;10 2 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;10 3 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;10 4 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;10 5 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;10 6 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;10 7 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;10 8 Candidates{8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;10 9 Candidates{0, 1, 2, 3, 4, 7}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;10 10 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;10 11 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;10 12 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;10 13 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;10 14 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;11 0 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;11 1 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;11 2 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;11 3 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;11 4 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;11 5 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;11 6 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;11 7 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;11 8 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;11 9 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;11 10 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;11 11 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;11 12 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;11 13 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;11 14 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;12 0 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;12 1 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;12 2 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;12 3 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;12 4 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;12 5 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;12 6 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;12 7 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;12 8 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;12 9 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;12 10 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;12 11 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;12 12 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;12 13 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;12 14 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;13 0 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;13 1 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;13 2 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;13 3 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;13 4 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;13 5 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;13 6 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;13 7 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;13 8 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;13 9 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;13 10 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;13 11 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;13 12 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;13 13 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;13 14 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;14 0 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;14 1 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;14 2 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;14 3 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;14 4 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;14 5 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;14 6 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;14 7 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;14 8 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;14 9 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;14 10 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;14 11 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;14 12 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;14 13 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;14 14 Candidates{0, 1, 2, 3, 4, 7, 8, 10, 11, 12}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;details&gt;
&lt;h3 id=&quot;success-and-failure&quot;&gt;Success and Failure&lt;&#x2F;h3&gt;
&lt;p&gt;This seems to work fine. But it is still missing one thing: it needs to know when to stop. If it is a successful solution, (where every cell has exactly one candidate), then stop and print it out. If it is a failed solution, try again. Thankfully, this could be expressed in a couple of lines, with the assumption that the grid has collapsed completely if the first element in the grid, as unlikely as it is to be reached, equals &lt;code&gt;{0}&lt;&#x2F;code&gt;, an &lt;code&gt;Air&lt;&#x2F;code&gt; cell.:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;main&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; () {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; grid_init()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    outer:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; grid_controlled_demolition(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;grid) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do break&lt;&#x2F;span&gt;&lt;span&gt; outer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; grid_init()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid_print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;grid)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; uninteresting code. it is a grid.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here are two sample results, which appear to be correct. The second result is interesting as it has a floating element. Obviously the code is undeterministic: each time it runs it gives a different result.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-symmetric-1&quot;&gt;&lt;a href=&quot;#fn-symmetric&quot;&gt;6&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; try 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |  |02|  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |03|07|12|  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |11|14|  |  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |09|15|04|  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |10|  |  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |01|05|13|06|  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |  |08|  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; try 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |01|06|  |02|  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |10|  |08|  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |03|14|  |  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |11|15|07|05|04|  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |09|13|12|  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;3D Cubes here I come!!&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;packed-gardens&quot;&gt;Packed Gardens&lt;&#x2F;h2&gt;
&lt;p&gt;As the solution for the Square Gardens works, it is obvious that simply changing the data structures and the hardcoded values would solve the 3D solution. I will get to that, but first, I want to try a Packed solution first.&lt;&#x2F;p&gt;
&lt;p&gt;The Packed solution has a much simpler to state goal: Pack all 64 cubes into a 4x4x4 cube. Obviously, in this version, the Red faces can (actually have to) face each other. &lt;em&gt;Only&lt;&#x2F;em&gt; Red faces are allowed to face outside. In his &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mindsports.nl&#x2F;index.php&#x2F;puzzles&#x2F;3d&#x2F;394-the-china-cube&quot;&gt;page about the set&lt;&#x2F;a&gt;, Freeling does actually provide one Packed solution, with a caveat.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-hanging-gardens-problem&#x2F;chinacube_sol1_2d_466x466.gif&quot; alt=&quot;Packed solution for the Cube Gardens&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The caveat here is that the Red Cube must be contained inside, and not on the edge. It &lt;em&gt;is&lt;&#x2F;em&gt; a difficult requirement, but the provided solution achieves it, at the cost of another floating group at the bottom left of the image above.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;initialization&quot;&gt;Initialization&lt;&#x2F;h3&gt;
&lt;p&gt;Nonetheless, as it is only a 4x4x4 cube, the search space for the solution is much smaller. There are &lt;em&gt;no&lt;&#x2F;em&gt; &lt;code&gt;Air&lt;&#x2F;code&gt; tiles in here: it is packed. Adding the additional requirement of the Red Cube being wholly contained actually simplifies the solution&#x27;s initialization. Start the Blue cube at &lt;code&gt;(1,1,1)&lt;&#x2F;code&gt; coordinates, and the Red cube at &lt;code&gt;(2,2,2)&lt;&#x2F;code&gt; coordinates. Any other placement of the two Cubes would actually be a mirror image, or a rotation, of this specific arrangement.&lt;&#x2F;p&gt;
&lt;p&gt;Here are the types, which, for the most part, are shared between the Packed Gardens and the Hanging Gardens, and the initialization function as described.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Side&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; u8 { North, East, South, West, Top, Bottom }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; distinct bit_set&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Side&lt;&#x2F;span&gt;&lt;span&gt;; u8]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;Cell&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span&gt; Maybe(Tile)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; distinct bit_set&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;; u64]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cells&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;      [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Cell&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Candidates&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;Candidate_Set&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span&gt; [Side]Candidates&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grid_init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; ()&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Grid&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Fill the candidate Grid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ret.candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = ~&lt;&#x2F;span&gt;&lt;span&gt;Candidates{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Place Blue and Red cubes respectively&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ret.cells[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = ~&lt;&#x2F;span&gt;&lt;span&gt;Tile{}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ret.cells[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Tile{}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Placeholder for now&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid_propagate(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;ret)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;cube-edges&quot;&gt;Cube Edges&lt;&#x2F;h3&gt;
&lt;p&gt;Unlike in the Square Gardens, this is not enough. While the candidates for the edges were safely ignored there, (as the the solution is unlikely to reach them), they must be encoded here, because they are integral. Time to hardcode the implementation! This is how the values are generated:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;generate_consts&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; () {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; side&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;~&lt;&#x2F;span&gt;&lt;span&gt;Tile{}) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        fmt.printf(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;%v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_CONNECTED :: Candidates{{&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, side)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; transmute(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;)u8(i)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; side&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; fmt.print(i,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;,&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        fmt.println(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        fmt.printf(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;%v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_NOT_CONNECTED :: Candidates{{&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, side)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; transmute(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;)u8(i)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; side&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; not_in&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; fmt.print(i,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;,&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        fmt.println(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And this is the generated code (with light formatting editing). I have &lt;em&gt;no&lt;&#x2F;em&gt; idea if it is correct. The proof of the pudding is in the eating.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;NORTH_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 17&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 21&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 25&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 27&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 29&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 31&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 33&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 35&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 37&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 39&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 41&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 43&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 45&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 47&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 49&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 51&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 53&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 55&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 57&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 59&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;EAST_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;   ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 18&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 22&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 27&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 31&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 34&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 35&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 38&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 39&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 43&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 46&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 47&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 51&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 54&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 55&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 58&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 59&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 62&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;SOUTH_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 21&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 22&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 29&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 31&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 36&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 37&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 38&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 39&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 44&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 45&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 46&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 47&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 52&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 53&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 54&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 55&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 62&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;WEST_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;   ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 24&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 25&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 27&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 29&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 31&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 40&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 41&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 43&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 44&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 45&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 46&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 47&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 56&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 57&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 58&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 59&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 62&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;TOP_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;    ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 17&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 18&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 21&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 22&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 24&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 25&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 27&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 29&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 31&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 48&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 49&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 51&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 52&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 53&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 54&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 55&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 56&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 57&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 58&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 59&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 62&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;BOTTOM_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 33&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 34&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 35&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 36&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 37&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 38&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 39&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 40&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 41&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 43&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 44&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 45&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 46&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 47&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 48&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 49&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 51&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 52&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 53&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 54&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 55&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 56&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 57&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 58&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 59&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 62&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;NORTH_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 18&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 22&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 24&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 34&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 36&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 38&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 40&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 44&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 46&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 48&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 52&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 54&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 56&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 58&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 62&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;EAST_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;   ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 17&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 21&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 24&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 25&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 29&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 33&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 36&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 37&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 40&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 41&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 44&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 45&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 48&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 49&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 52&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 53&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 56&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 57&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;SOUTH_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 17&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 18&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 24&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 25&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 27&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 33&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 34&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 35&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 40&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 41&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 43&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 48&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 49&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 51&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 56&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 57&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 58&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 59&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;WEST_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;   ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 17&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 18&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 21&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 22&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 33&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 34&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 35&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 36&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 37&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 38&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 39&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 48&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 49&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 51&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 52&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 53&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 54&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 55&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;TOP_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;    ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 33&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 34&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 35&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 36&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 37&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 38&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 39&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 40&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 41&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 43&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 44&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 45&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 46&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 47&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;BOTTOM_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 17&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 18&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 21&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 22&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 24&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 25&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 27&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 29&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 31&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tile_connections&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; (c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Cell&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Candidate_Set&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; c {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt; Tile: &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.North]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; .North&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;  in&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt; SOUTH_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt; SOUTH_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.East]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span&gt; .East&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;   in&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt; WEST_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;   :&lt;&#x2F;span&gt;&lt;span&gt; WEST_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.South]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; .South&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;  in&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt; NORTH_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt; NORTH_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.West]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span&gt; .West&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;   in&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt; EAST_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;   :&lt;&#x2F;span&gt;&lt;span&gt; EAST_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.Top]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span&gt; .Top&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    in&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt; BOTTOM_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&gt; BOTTOM_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.Bottom]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .Bottom&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span&gt; TOP_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;    :&lt;&#x2F;span&gt;&lt;span&gt; TOP_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = ~&lt;&#x2F;span&gt;&lt;span&gt;{}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then edit &lt;code&gt;grid_init&lt;&#x2F;code&gt; to adjust the candidates in the edge cubes accordingly. However, care must be taken as how these values translate there. For example, the westernmost cubes are the ones that do &lt;em&gt;not&lt;&#x2F;em&gt; have a connection on the &lt;code&gt;.West&lt;&#x2F;code&gt; side. Again, I am not currently sure how correct this is. The pudding is yet to be eaten.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grid_init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; ()&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Grid&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Fill the candidate Grid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ret.candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = ~&lt;&#x2F;span&gt;&lt;span&gt;Candidates{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; ret.candidates[x][y][z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; WEST_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; ret.candidates[x][y][z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; EAST_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; ret.candidates[x][y][z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; SOUTH_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; ret.candidates[x][y][z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; NORTH_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; ret.candidates[x][y][z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; BOTTOM_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; ret.candidates[x][y][z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; TOP_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Place Blue and Red cubes respectively&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ret.cells[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = ~&lt;&#x2F;span&gt;&lt;span&gt;Tile{}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ret.cells[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Tile{}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; still a placeholder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid_propagate(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;ret)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;propagation-and-controlled-demolition&quot;&gt;Propagation and Controlled Demolition&lt;&#x2F;h3&gt;
&lt;p&gt;Applying minor changes from the Square Gardens&#x27; &lt;code&gt;grid_propgagate&lt;&#x2F;code&gt; and &lt;code&gt;grid_controlled_demolition&lt;&#x2F;code&gt;, they end up like this.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grid_propagate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; (grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Grid&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; bool {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Update candidates based on cells&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cell&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; grid.cells[x][y][z]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; tile_connections(cell)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[x][y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;][z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; tc[.North]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;][y][z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; tc[.East]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[x][y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;][z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; tc[.South]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;][y][z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; tc[.West]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Top&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[x][y][z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; tc[.Top]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Bottom&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[x][y][z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; tc[.Bottom]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; tile, ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; cell.(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;); ok {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F; Weird magic&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            cand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; Candidates{ int (transmute(u8)tile) }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; cand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.candidates[x][y][z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    any_collapsed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Update cells based on candidates&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;  {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[x][y][z]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; cand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; {}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; grid.cells[x][y][z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; card(cand)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; cand {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            any_collapsed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.cells[x][y][z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transmute(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;)u8(id)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    success&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; any_collapsed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; success&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; grid_propagate(grid)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; recursion!!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; success&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grid_controlled_demolition&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; (grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Grid&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; bool {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; all the shuffling &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rows&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; []int{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rand.shuffle(rows)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cols&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; []int{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rand.shuffle(cols)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    verts&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; []int{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rand.shuffle(verts)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ids&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; []int{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;                 16&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 17&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 18&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 21&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 22&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 24&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 25&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 27&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 29&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 31&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;                 32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 33&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 34&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 35&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 36&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 37&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 38&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 39&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 40&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 41&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 43&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 44&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 45&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 46&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 47&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;                 48&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 49&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 51&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 52&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 53&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 54&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 55&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 56&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 57&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 58&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 59&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 62&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rand.shuffle(ids)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    t_x, t_y, t_z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    min_card&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; max(int)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; verts&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; cols&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; rows {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; card(grid.candidates[x][y][z])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; min_card {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            t_x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            t_y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            t_z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            min_card&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; min_card&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; ids&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do if&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[t_x][t_y][t_z] {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; transmute(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;)i8(id)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; Candidates{ id }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        grid.cells[t_x][t_y][t_z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        grid.candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; cand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        grid.candidates[t_x][t_y][t_z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; grid_propagate(grid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And this does it. Figuring out how to ascertain how every cell in the grid has only one candidate took a bit of finessing and experimenting with Odin&#x27;s core library &lt;code&gt;slice.all_in_proc&lt;&#x2F;code&gt;, but I ended up doing it manually.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;main&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; () {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; grid_init()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    outer:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        inner:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; grid_controlled_demolition(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;grid) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            for&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span&gt; card(grid.candidates[x][y][z])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do continue&lt;&#x2F;span&gt;&lt;span&gt; inner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            break&lt;&#x2F;span&gt;&lt;span&gt; outer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; grid_init()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid_draw(grid)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- this one is a bit more interesting.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This works, and thankfully halts. However, the execution time, in the few times I ran it, varied anything between 3 seconds and one minute. This obviously depends on how &lt;em&gt;lucky&lt;&#x2F;em&gt; the random seed is. Using threads would help to get a result faster.&lt;&#x2F;p&gt;
&lt;p&gt;Printing the solution naïvely prints a bunch of numbers, with no repeats (as far I could tell), but to verify that the solution is correct it needs to be outputted into a readable format. THe &quot;easy&quot; solution is to put together a dictionary of images and make a collage, much like the image at the top of the section, but that is not very interesting.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;solution-output&quot;&gt;Solution Output&lt;&#x2F;h3&gt;
&lt;p&gt;Simply printing out the resultant grid to console is not a very useful output. With the Square Gardens, it is possible to verify the correctness of the result by simply checking, visually, that each number&#x2F;square is the only one in the grid that has neighbors in a specific configuration.&lt;&#x2F;p&gt;
&lt;p&gt;In other words, look at this grid given from before (with pointless empty spaces removed and the Red Square &lt;code&gt;00&lt;&#x2F;code&gt; added):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |00|  |  |02|  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |03|07|12|  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |11|14|  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |09|15|04|  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |10|  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |01|05|13|06|  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |08|  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  |  |  |  |  |  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It is easy to verify that, for example, &lt;code&gt;08&lt;&#x2F;code&gt; is literally the only tile that has only one connection to the top (and whether in code that&#x27;s &lt;code&gt;North&lt;&#x2F;code&gt; or &lt;code&gt;South&lt;&#x2F;code&gt; is irrelevant to the correctness of the solution.) &lt;code&gt;14&lt;&#x2F;code&gt;, for example, is the only tile that has only three connections to the top, left, and bottom, and so on for all of them.&lt;&#x2F;p&gt;
&lt;p&gt;For the packed solution, it is harder to verify that over text output. One solution would be to create a little image for every cube, (as Freeling&#x27;s provided solution does) and pack them together. The other solution is to render a 3D image of the solution and visually inspect it that way.&lt;&#x2F;p&gt;
&lt;p&gt;Looking over Odin&#x27;s &lt;code&gt;vendor&lt;&#x2F;code&gt; libraries, and asking around for ideas how to do that, I could not figure out how to draw on an image canvas (the way the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;imageproc&#x2F;latest&#x2F;imageproc&#x2F;&quot;&gt;&lt;code&gt;imageproc&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; lets me do in Rust.) But there are a few bindings to different graphics libraries, and word on the street was that &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.raylib.com&quot;&gt;&lt;code&gt;raylib&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; is the simplest solution for this sort of thing.&lt;&#x2F;p&gt;
&lt;p&gt;I spent a day playing around with &lt;code&gt;raylib&lt;&#x2F;code&gt;&#x27;s tutorials and asking for help on the Discord. The API is ... weirder than I am used to, to say the least. But it looks simple enough. To draw a window with a render scene, the code is the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; rl&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;vendor:raylib&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grid_draw&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; (grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Grid&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;    SCREEN_WIDTH&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 400&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;    SCREEN_HEIGHT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 200&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; raylib must start with this.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rl.InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; and end with this.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; rl.CloseWindow()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    camera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; rl.Camera3D{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        position&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span&gt; ({&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;10.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;5.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5.0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2.5&lt;&#x2F;span&gt;&lt;span&gt;), &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;     =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2.5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2.5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2.5&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        up&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;         =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.0&lt;&#x2F;span&gt;&lt;span&gt;}, &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        fovy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;       =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        projection&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .ORTHOGRAPHIC&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;rl.WindowShouldClose() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.UpdateCamera(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;camera, .THIRD_PERSON)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; This honestly weird pattern is how everything in raylib must work&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.BeginDrawing()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        defer&lt;&#x2F;span&gt;&lt;span&gt; rl.EndDrawing()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.ClearBackground(rl.WHITE)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.BeginMode3D(camera)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        defer&lt;&#x2F;span&gt;&lt;span&gt; rl.EndMode3D()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; draw 3D things here.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Just to test things out, I will try drawing each cube with a different shade based on how many connections it has. The Blue cube shall be blue and the Red cube shall be red, and the other cubes will be different shades of purple.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; grid.cells[x][y][z].(Tile)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grade&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; u8(card(tile))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; (max(u8)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; grade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; max(u8)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rl.DrawCubeV({f32(x), f32(y), f32(z)},&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1.0&lt;&#x2F;span&gt;&lt;span&gt;, {r,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;, b,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 255&lt;&#x2F;span&gt;&lt;span&gt;})&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And now: the moment of truth &lt;code&gt;odin run .&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-hanging-gardens-problem&#x2F;first_test.png&quot; alt=&quot;weird mush of colors&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I have &lt;em&gt;no&lt;&#x2F;em&gt; idea what&#x27;s going on here. Everything is mushed together and the screen is tiny. Upping the screen&#x27;s resolution (to &lt;code&gt;800, 400&lt;&#x2F;code&gt;), multiplying the position by &lt;code&gt;2.0&lt;&#x2F;code&gt; would be a start, and bringing the camera closer would be a decent start.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-iterating-1&quot;&gt;&lt;a href=&quot;#fn-iterating&quot;&gt;7&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-hanging-gardens-problem&#x2F;second_test.png&quot; alt=&quot;different much of colors&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Ah .. much better already. This actually rotates (but not zooms) with the mouse movement, thanks to that &lt;code&gt;.THIRD_PERSON&lt;&#x2F;code&gt; setting up there. Time to draw the lines, and better organize the code while I am at it. Here is the full function. (I do not actually expect this to be correct.)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grid_draw&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Grid&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;    SCREEN_WIDTH&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1200&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;    SCREEN_HEIGHT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 600&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;    CUBE_DISTANCE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;    CENTER_POINT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2.5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; CUBE_DISTANCE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rl.InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; rl.CloseWindow()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    camera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; rl.Camera3D {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        position&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span&gt; ({&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;10.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;5.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5.0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; CENTER_POINT),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;     =&lt;&#x2F;span&gt;&lt;span&gt; CENTER_POINT,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        up&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;         =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.0&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        fovy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;       =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        projection&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .ORTHOGRAPHIC,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;rl.WindowShouldClose() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.UpdateCamera(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;camera, .THIRD_PERSON)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.BeginDrawing()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        defer&lt;&#x2F;span&gt;&lt;span&gt; rl.EndDrawing()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.ClearBackground(rl.WHITE)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.BeginMode3D(camera)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        defer&lt;&#x2F;span&gt;&lt;span&gt; rl.EndMode3D()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; grid.cells[x][y][z].(Tile)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grade&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; u8(card(tile))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  :=&lt;&#x2F;span&gt;&lt;span&gt; rl.Vector3{f32(x), f32(y), f32(z)}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; CUBE_DISTANCE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; rl.Vector3{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1.0&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; (max(u8)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; grade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; max(u8)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            color&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; rl.Color{ r,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;, b,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 255&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            rl.DrawCubeV( pos, size, color )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; .North&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;  in&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; rl.DrawLine3D(pos, pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,  CUBE_DISTANCE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; .South&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;  in&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; rl.DrawLine3D(pos, pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;CUBE_DISTANCE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; .East&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;   in&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; rl.DrawLine3D(pos, pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; { CUBE_DISTANCE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; .West&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;   in&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; rl.DrawLine3D(pos, pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;CUBE_DISTANCE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; .Top&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    in&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; rl.DrawLine3D(pos, pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,  CUBE_DISTANCE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;}, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; .Bottom&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; rl.DrawLine3D(pos, pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;CUBE_DISTANCE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;}, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-hanging-gardens-problem&#x2F;third_test.png&quot; alt=&quot;wired mesh of colors&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This looks .. ok? half decent? Rotating it around does not show any mistakes. The centering is off, however. And due to the Orthographic projection and camera work I cannot zoom in to see how everything connects in more detail.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;faster-iteration-of-visuals&quot;&gt;Faster Iteration of Visuals&lt;&#x2F;h3&gt;
&lt;p&gt;Also, frankly, I am getting tired of waiting for the solution to solve before the render show up, so I am changing the code a bit to, maybe, see the cube solve it in real time. This makes the solver &lt;em&gt;much&lt;&#x2F;em&gt; slower, but it makes for a fun animation.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;SCREEN_WIDTH&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 800&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;SCREEN_HEIGHT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 800&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;CUBE_DISTANCE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;CENTER_POINT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1.5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; CUBE_DISTANCE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;main&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; () {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rl.InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; rl.CloseWindow()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rl.SetTargetFPS(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;60&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    camera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; rl.Camera3D {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        position&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span&gt; ({&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;10.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;5.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5.0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; CENTER_POINT),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;     =&lt;&#x2F;span&gt;&lt;span&gt; CENTER_POINT,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        up&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;         =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.0&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        fovy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;       =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        projection&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .ORTHOGRAPHIC,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;   :=&lt;&#x2F;span&gt;&lt;span&gt; grid_init()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    solved&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    paused&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;rl.WindowShouldClose() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.UpdateCamera(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;camera, .THIRD_PERSON)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; rl.IsKeyPressed(.SPACE)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; paused&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ~=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Draw current state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            rl.BeginDrawing()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            defer&lt;&#x2F;span&gt;&lt;span&gt; rl.EndDrawing()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            rl.ClearBackground(rl.WHITE)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            rl.BeginMode3D(camera)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            defer&lt;&#x2F;span&gt;&lt;span&gt; rl.EndMode3D()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            for&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; grid.cells[x][y][z].(Tile)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                grade&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; u8(card(tile))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  :=&lt;&#x2F;span&gt;&lt;span&gt; rl.Vector3{f32(x), f32(y), f32(z)}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; CUBE_DISTANCE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; rl.Vector3{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1.0&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; (max(u8)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; grade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; max(u8)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                color&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; rl.Color{ r,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;, b,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 255&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                rl.DrawCubeV( pos, size, color )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span&gt; .North&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;  in&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; rl.DrawLine3D(pos, pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,  CUBE_DISTANCE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span&gt; .South&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;  in&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; rl.DrawLine3D(pos, pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;CUBE_DISTANCE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span&gt; .East&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;   in&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; rl.DrawLine3D(pos, pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; { CUBE_DISTANCE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span&gt; .West&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;   in&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; rl.DrawLine3D(pos, pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;CUBE_DISTANCE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span&gt; .Top&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    in&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; rl.DrawLine3D(pos, pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,  CUBE_DISTANCE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;}, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span&gt; .Bottom&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; rl.DrawLine3D(pos, pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;CUBE_DISTANCE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;}, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;paused&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp; !&lt;&#x2F;span&gt;&lt;span&gt;solved {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; grid_controlled_demolition(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;grid) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                solved&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                for&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    if&lt;&#x2F;span&gt;&lt;span&gt; card(grid.candidates[x][y][z])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        solved&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                        break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; { &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; grid_init() &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                solved&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;video controls width=&quot;400&quot; autoplay=&quot;true&quot;&gt;
  &lt;source src=&quot;animation_1.mp4&quot; type=&quot;video&#x2F;mp4&quot; &#x2F;&gt;
&lt;&#x2F;video&gt;
&lt;p&gt;Well this is a lot more pleasant to look at, isn&#x27;t it? One nicety: it pauses when the Space bar is pressed, easier to inspect the connections. It will find a solution in a million years, but until that happens it would be easier to iterate the presentation&#x27;s colors and distances.&lt;&#x2F;p&gt;
&lt;p&gt;Miracolously, howver, no matter when I pause it, the connections between adaject cubes are always correct. There are no cubes that are next to each other with one line hanging midways between them. Every high five is reciprocated. This is a fancy screenshot for an attempted solution.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-hanging-gardens-problem&#x2F;fourth_test.png&quot; alt=&quot;organized mesh of colors&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;final-visuals&quot;&gt;Final Visuals&lt;&#x2F;h3&gt;
&lt;p&gt;After a bit of trial and error and experimenting with different colors and distances and camera positions, I ended up with these constants and draw functions.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;SCREEN_WIDTH&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 800&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;SCREEN_HEIGHT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 800&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;CUBE_DISTANCE_X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;CUBE_DISTANCE_Y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;CUBE_DISTANCE_Z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2.5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;CENTER_POINT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;]f32 {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;    1.5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; CUBE_DISTANCE_X,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;    1.5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; CUBE_DISTANCE_Y,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;    1.5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; CUBE_DISTANCE_Z&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;main&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; () {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; boring boilerplate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    camera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; rl.Camera3D {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        position&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span&gt; ({&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; CENTER_POINT),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;     =&lt;&#x2F;span&gt;&lt;span&gt; CENTER_POINT,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        up&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;         =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1.0&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        fovy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;       =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 35&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        projection&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .ORTHOGRAPHIC,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; other boring boilerplate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rl.ClearBackground(rl.Color{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 240&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 240&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 240&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 255&lt;&#x2F;span&gt;&lt;span&gt; })&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; you know&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  :=&lt;&#x2F;span&gt;&lt;span&gt; rl.Vector3{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        f32(x)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; CUBE_DISTANCE_X,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        f32(y)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; CUBE_DISTANCE_Y,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        f32(z)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; CUBE_DISTANCE_Z,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; more of it&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rl.DrawCubeV(pos, size, color)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rl.DrawCubeWiresV(pos, size, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; .North&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;  in&lt;&#x2F;span&gt;&lt;span&gt; tile {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        end_pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,  CUBE_DISTANCE_Y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.DrawCylinderEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.ORANGE)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.DrawCylinderWiresEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; .South&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;  in&lt;&#x2F;span&gt;&lt;span&gt; tile {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        end_pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;CUBE_DISTANCE_Y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.DrawCylinderEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.ORANGE)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.DrawCylinderWiresEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; .East&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;   in&lt;&#x2F;span&gt;&lt;span&gt; tile {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        end_pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; { CUBE_DISTANCE_X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.DrawCylinderEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.DARKGREEN)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.DrawCylinderWiresEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; .West&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;   in&lt;&#x2F;span&gt;&lt;span&gt; tile {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    end_pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;CUBE_DISTANCE_X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.DrawCylinderEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.DARKGREEN)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.DrawCylinderWiresEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; .Top&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    in&lt;&#x2F;span&gt;&lt;span&gt; tile {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        end_pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,  CUBE_DISTANCE_Z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.DrawCylinderEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.YELLOW)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.DrawCylinderWiresEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; .Bottom&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; tile {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        end_pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;CUBE_DISTANCE_Z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.DrawCylinderEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.YELLOW)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.DrawCylinderWiresEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; end of proc boilerplate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-hanging-gardens-problem&#x2F;fifth_example.png&quot; alt=&quot;final coloring&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;producing-an-image&quot;&gt;Producing an Image&lt;&#x2F;h3&gt;
&lt;p&gt;Well, now that apparently all the logic and visuals are top notch and as clear as they can be, I do not actually want a visual of the solver solving and taking for ever. I only want a final image. So I will revert &lt;code&gt;main&lt;&#x2F;code&gt; to what it was before, and adjust &lt;code&gt;grid_draw&lt;&#x2F;code&gt; so it only saves an image to disk, rather than opening a window and waiting for me to take a screenshot.&lt;&#x2F;p&gt;
&lt;p&gt;The code is mostly the same as before, only without starting a loop. &lt;code&gt;raylib&lt;&#x2F;code&gt; has functions to render a texture and save it as an image without third party libraries, so I just use those.&lt;&#x2F;p&gt;
&lt;p&gt;This is the final &lt;code&gt;grid_draw&lt;&#x2F;code&gt; and its resultant image&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grid_draw&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Grid&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rl.SetConfigFlags({.WINDOW_HIDDEN})&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rl.InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; rl.CloseWindow()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    camera&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; rl.Camera3D {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        position&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span&gt; ({&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; CENTER_POINT),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;     =&lt;&#x2F;span&gt;&lt;span&gt; CENTER_POINT,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        up&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;         =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1.0&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        fovy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;       =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 35&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        projection&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .ORTHOGRAPHIC,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    txtr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; rl.LoadRenderTexture(SCREEN_WIDTH, SCREEN_HEIGHT)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Drawing here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.BeginTextureMode(txtr)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        defer&lt;&#x2F;span&gt;&lt;span&gt; rl.EndTextureMode()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.BeginDrawing()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        defer&lt;&#x2F;span&gt;&lt;span&gt; rl.EndDrawing()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.ClearBackground(rl.Color{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 240&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 240&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 240&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 255&lt;&#x2F;span&gt;&lt;span&gt; })&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rl.BeginMode3D(camera)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        defer&lt;&#x2F;span&gt;&lt;span&gt; rl.EndMode3D()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; grid.cells[x][y][z].(Tile)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grade&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; u8(card(tile))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; rl.Vector3{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                f32(x)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; CUBE_DISTANCE_X,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                f32(y)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; CUBE_DISTANCE_Y,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                f32(z)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; CUBE_DISTANCE_Z&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; rl.Vector3{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1.0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; (max(u8)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; grade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; max(u8)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            color&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; rl.Color{r,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;, b,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 255&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            rl.DrawCubeV(pos, size, color)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            rl.DrawCubeWiresV(pos, size, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; .North&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; tile {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                end_pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, CUBE_DISTANCE_Y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                rl.DrawCylinderEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.ORANGE)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                rl.DrawCylinderWiresEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; .South&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; tile {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                end_pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;CUBE_DISTANCE_Y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                rl.DrawCylinderEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.ORANGE)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                rl.DrawCylinderWiresEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; .East&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; tile {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                end_pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; {CUBE_DISTANCE_X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                rl.DrawCylinderEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.DARKGREEN)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                rl.DrawCylinderWiresEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; .West&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; tile {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                end_pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;CUBE_DISTANCE_X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                rl.DrawCylinderEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.DARKGREEN)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                rl.DrawCylinderWiresEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; .Top&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; tile {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                end_pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;, CUBE_DISTANCE_Z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                rl.DrawCylinderEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.YELLOW)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                rl.DrawCylinderWiresEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; .Bottom&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; tile {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                end_pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; pos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;CUBE_DISTANCE_Z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                rl.DrawCylinderEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.YELLOW)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                rl.DrawCylinderWiresEx(pos, end_pos,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0.1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;, rl.BLACK)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    img&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; rl.LoadImageFromTexture(txtr.texture)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rl.ExportImage(img,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;result.png&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-hanging-gardens-problem&#x2F;packed_garden.png&quot; alt=&quot;Packed Squares Solution&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;hanging-gardens&quot;&gt;Hanging Gardens&lt;&#x2F;h2&gt;
&lt;p&gt;With the Square Gardens and the Packed Gardens done, time to return to the original problem. Much of the different pieces of the solution are already in place, and it is just a question of assembling them together.&lt;&#x2F;p&gt;
&lt;p&gt;The main problem left is how to determine the proper size of the grid. It needs to be big enough to potentially accept any variation of the problem, but small enough that it does not cause a stack overflow. When I was experimenting with it, I tried a grid of size 31x31x31 and the Odin compiler warnned&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-warning-1&quot;&gt;&lt;a href=&quot;#fn-warning&quot;&gt;8&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; me that it is so big it might cause said overflow. Or might just put it on the heap and let the OS take care of cleaning it from memory.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;frankenstein-s-monster&quot;&gt;Frankenstein&#x27;s Monster&lt;&#x2F;h3&gt;
&lt;p&gt;This is the full program, with a helpful &lt;code&gt;GRID_SIZE&lt;&#x2F;code&gt; constant that allowed me to iterate and debug a bit with a smaller grid size.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;package&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;hanging_gardens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;core:fmt&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;core:math&#x2F;rand&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;GRID_SIZE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 31&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;MID_POINT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span&gt; (GRID_SIZE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Side&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; u8 { North, East, South, West, Top, Bottom }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; distinct bit_set&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Side&lt;&#x2F;span&gt;&lt;span&gt;; u8]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Air&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; distinct struct&lt;&#x2F;span&gt;&lt;span&gt; {}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Cell&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; union&lt;&#x2F;span&gt;&lt;span&gt; { Air, Tile }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; distinct bit_set&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;; u64]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cells&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;      [GRID_SIZE][GRID_SIZE][GRID_SIZE]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Cell&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [GRID_SIZE][GRID_SIZE][GRID_SIZE]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Candidates&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;Candidate_Set&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span&gt; [Side]Candidates&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;NORTH_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 17&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 21&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 25&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 27&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 29&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 31&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 33&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 35&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 37&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 39&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 41&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 43&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 45&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 47&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 49&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 51&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 53&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 55&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 57&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 59&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;EAST_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;   ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 18&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 22&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 27&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 31&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 34&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 35&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 38&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 39&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 43&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 46&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 47&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 51&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 54&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 55&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 58&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 59&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 62&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;SOUTH_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 21&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 22&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 29&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 31&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 36&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 37&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 38&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 39&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 44&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 45&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 46&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 47&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 52&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 53&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 54&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 55&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 62&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;WEST_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;   ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 24&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 25&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 27&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 29&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 31&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 40&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 41&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 43&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 44&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 45&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 46&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 47&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 56&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 57&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 58&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 59&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 62&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;TOP_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;    ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 17&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 18&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 21&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 22&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 24&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 25&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 27&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 29&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 31&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 48&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 49&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 51&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 52&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 53&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 54&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 55&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 56&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 57&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 58&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 59&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 62&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;BOTTOM_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 33&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 34&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 35&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 36&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 37&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 38&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 39&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 40&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 41&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 43&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 44&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 45&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 46&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 47&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 48&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 49&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 51&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 52&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 53&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 54&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 55&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 56&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 57&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 58&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 59&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 62&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;NORTH_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 18&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 22&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 24&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 34&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 36&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 38&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 40&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 44&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 46&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 48&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 52&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 54&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 56&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 58&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 62&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;EAST_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;   ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 17&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 21&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 24&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 25&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 29&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 33&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 36&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 37&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 40&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 41&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 44&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 45&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 48&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 49&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 52&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 53&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 56&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 57&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;SOUTH_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 17&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 18&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 24&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 25&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 27&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 33&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 34&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 35&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 40&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 41&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 43&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 48&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 49&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 51&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 56&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 57&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 58&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 59&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;WEST_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;   ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 17&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 18&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 21&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 22&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 33&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 34&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 35&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 36&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 37&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 38&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 39&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 48&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 49&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 51&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 52&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 53&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 54&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 55&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;TOP_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;    ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 33&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 34&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 35&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 36&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 37&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 38&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 39&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 40&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 41&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 43&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 44&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 45&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 46&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 47&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;BOTTOM_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span&gt; Candidates{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 17&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 18&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 21&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 22&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 24&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 25&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 27&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 29&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 31&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tile_connections&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; (c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Cell&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Candidate_Set&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; c {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt; Tile: &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.North]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; SOUTH_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span&gt; .North&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;  in&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.East]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span&gt; WEST_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;   if&lt;&#x2F;span&gt;&lt;span&gt; .East&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;   in&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.South]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; NORTH_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span&gt; .South&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;  in&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.West]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span&gt; EAST_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;   if&lt;&#x2F;span&gt;&lt;span&gt; .West&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;   in&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.Top]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span&gt; BOTTOM_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; .Top&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    in&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.Bottom]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; TOP_CONNECTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; .Bottom&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt; Air:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.North]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; SOUTH_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.East]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span&gt; WEST_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.South]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; NORTH_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.West]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span&gt; EAST_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.Top]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span&gt; BOTTOM_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret[.Bottom]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; TOP_NOT_CONNECTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = ~&lt;&#x2F;span&gt;&lt;span&gt;{}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grid_propagate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Grid&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; bool {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Update candidates based on cells&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;GRID_SIZE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;GRID_SIZE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;GRID_SIZE {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cell&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; grid.cells[x][y][z]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; tile_connections(cell)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; North&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; GRID_SIZE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[x][y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;][z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; tc[.North]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; East&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; GRID_SIZE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;][y][z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; tc[.East]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Top&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; GRID_SIZE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[x][y][z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; tc[.Top]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; South&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[x][y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;][z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; tc[.South]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; West&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;][y][z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; tc[.West]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Bottom&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[x][y][z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; tc[.Bottom]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; if cell is a tile, make sure it is not a candidate anywhere else.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; tile, ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; cell.(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;); ok {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            cand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; Candidates{ int ( transmute(u8)tile ) }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; cand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.candidates[x][y][z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    any_collapsed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Update cells based on candidates&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;GRID_SIZE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;GRID_SIZE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;GRID_SIZE {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[x][y][z]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; cand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; {}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; illegal state reached&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; COLLAPSE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; obviously only a new collapse if it isnt collapsed already&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; grid.cells[x][y][z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; card(cand)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; cand {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            any_collapsed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F; What did actually collapse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.cells[x][y][z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Air{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; transmute(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;)i8(id)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    success&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; any_collapsed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; success&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; grid_propagate(grid) &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; success&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grid_init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; (grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Grid&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; different grid_init from before to reuse memory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid.cells&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid.cells[MID_POINT][MID_POINT][MID_POINT]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = ~&lt;&#x2F;span&gt;&lt;span&gt;Tile{}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid.candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = ~&lt;&#x2F;span&gt;&lt;span&gt;Candidates{} &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid_propagate(grid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grid_controlled_demolition&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Grid&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; bool {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; all the shuffling &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rows&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; [GRID_SIZE]int{}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;GRID_SIZE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; rows[i]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cols&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; rows&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    verts&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; cols&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rand.shuffle(rows[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rand.shuffle(cols[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rand.shuffle(verts[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ids&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; []int{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 17&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 18&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 21&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 22&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 24&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 25&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 27&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 29&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 31&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 33&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 34&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 35&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 36&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 37&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 38&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 39&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 40&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 41&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 43&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 44&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 45&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 46&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 47&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 48&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 49&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 51&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 52&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 53&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 54&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 55&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 56&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 57&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 58&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 59&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 62&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rand.shuffle(ids)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; target collapse stored here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    t_x, t_y, t_z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; tracking the minimum&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    min_card&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; max(int)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; verts&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; cols&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; rows {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; card(grid.candidates[x][y][z])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_continue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; already collapsed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; min_card {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            t_x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            t_y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            t_z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            min_card&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; min_card&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do break&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; no point in looking further in this case.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; ids&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do if&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[t_x][t_y][t_z] {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; COLLAPSE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.cells[t_x][t_y][t_z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Air{}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.candidates[t_x][t_y][t_z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; transmute(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;)i8(id)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            cand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; Candidates{ id }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.cells[t_x][t_y][t_z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; cand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.candidates[t_x][t_y][t_z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; grid_propagate(grid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;main&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; () {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; new(Grid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid_init(grid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    outer:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; max(int) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; grid_controlled_demolition(grid) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do break&lt;&#x2F;span&gt;&lt;span&gt; outer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        grid_init(grid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; fmt.eprint(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;try&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, i,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;GRID_SIZE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;GRID_SIZE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;GRID_SIZE {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        fmt.println(x, y, z, grid.candidates[x][y][z])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Running this takes &lt;em&gt;forever&lt;&#x2F;em&gt;, by the way. Even when compiling it optimized for speed with &lt;code&gt;odin build . -o:speed&lt;&#x2F;code&gt;, the first run at the solution took more than 290,000 iterations and more than 18 minutes before I gave up on it, and decided to change allocations a bit. Doubt rised in my heart whether this halts at all, or if it has a nasty bug that is difficult to find due to, well, the long runtime. Threading will probably &lt;em&gt;not&lt;&#x2F;em&gt; make this faster.&lt;&#x2F;p&gt;
&lt;p&gt;The longest time I ran it, it went for 25,771,590 iterations and around 27 hours of usertime before I shut it off.&lt;&#x2F;p&gt;
&lt;p&gt;Maybe, just maybe, completely random attempts are the wrong approach. Maybe I actually need to implement proper backtracking to ensure that the same tree is not being barked multiple times.&lt;&#x2F;p&gt;
&lt;p&gt;I have spent a few days mulling it over, and the simplest way to implement is to have a dynamic array in &lt;code&gt;Grid&lt;&#x2F;code&gt; to save every state where an arbitrary (&lt;em&gt;not&lt;&#x2F;em&gt; random) choice was made, in addition to the &lt;em&gt;index&lt;&#x2F;em&gt; of the choice. And whenever reaching an illegal state, the grid is reset to the previous state, and the index is incremented. Should the index reach a certain value (10 or whatever), then the last state is discarded and the index is incremented on the one before it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;grid-enhancements&quot;&gt;Grid Enhancements&lt;&#x2F;h3&gt;
&lt;p&gt;So, first things first, here is the new &lt;code&gt;Grid&lt;&#x2F;code&gt; struct, with a few type aliases to lighten the mood.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;Cell_Grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;      ::&lt;&#x2F;span&gt;&lt;span&gt; [GRID_SIZE][GRID_SIZE][GRID_SIZE]Cell&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;Candidate_Grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span&gt; [GRID_SIZE][GRID_SIZE][GRID_SIZE]Candidates&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Demolition_Point&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Cell_Grid&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  int,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cells&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;       &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Cell_Grid&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Candidate_Grid&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    demolitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;dynamic&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Demolition_Point&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Having the dynamic array there should, in theory, be safe. The Grid is initialized once, And whenever the controlled demolition fails, the index of the last item in &lt;code&gt;demolitions&lt;&#x2F;code&gt; is updated. &lt;em&gt;Or&lt;&#x2F;em&gt;, if it exceeds some threshold (preferably exhausting all the candidates in a cell), the last entry is removed and the second to last entry increments its index instead.&lt;&#x2F;p&gt;
&lt;p&gt;Now, for the procedures used, &lt;code&gt;grid_propagate&lt;&#x2F;code&gt; should probably be the same. While &lt;code&gt;grid_init&lt;&#x2F;code&gt; and &lt;code&gt;grid_controlled_demolition&lt;&#x2F;code&gt; should perhaps be overhauled.&lt;&#x2F;p&gt;
&lt;p&gt;A potential enhancement, to avoid the algorithm being stuck on the same start every time, is to reuse the shuffling above in initialization. Shuffling the IDs for every new &lt;code&gt;Demolition_Point&lt;&#x2F;code&gt; would be enough, unlike shuffling rows and columns. the reason for that is, if the program exhausted every candidate from a cell, then there is no point in trying other cells from the same state. This is what that would look like.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Demolition_Point&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Cell_Grid&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;         int,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ids_shuffle&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;]int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grid_init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; (grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Grid&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid.cells[MID_POINT][MID_POINT][MID_POINT]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = ~&lt;&#x2F;span&gt;&lt;span&gt;Tile{}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid.candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = ~&lt;&#x2F;span&gt;&lt;span&gt;Candidates{} &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid_propagate(grid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    start_point&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; Demolition_Point {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; grid.cells,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ids_shuffle&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; IDS,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; IDS is numbers from 0 to 63.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rand.shuffle(start_point.ids_shuffle[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    append(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;grid.demolitions, start_point)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;demolition-revision&quot;&gt;Demolition Revision&lt;&#x2F;h3&gt;
&lt;p&gt;Previously, &lt;code&gt;grid_init&lt;&#x2F;code&gt; was used to reset the state after every failed attempt. This time a different procedure is needed, which may be called &lt;code&gt;grid_backtrack&lt;&#x2F;code&gt;, or &lt;code&gt;increment&lt;&#x2F;code&gt;, who knows. This proc would only be called for a &lt;em&gt;failed&lt;&#x2F;em&gt; controlled demolition. Demolition can fail for two reasons: either the candidate chosen forced an illegal state, or all candidates from the lowest cell were exhausted. This call for an &lt;code&gt;enum&lt;&#x2F;code&gt;! &lt;code&gt;grid_controlled_demolition&lt;&#x2F;code&gt; can return this enum and based on whivh &lt;code&gt;grid_backtrack&lt;&#x2F;code&gt; decides what to do.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Demolition_Result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; { Success, Exhausted_Candidates, Illegal_State }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And this would be the new version of &lt;code&gt;grid_controlled_demolition&lt;&#x2F;code&gt;, with less shuffling and small changes:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grid_controlled_demolition&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Grid&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Demolition_Result&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    t_x, t_y, t_z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    min_card&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; max(int)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; RANKS&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; RANKS&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; RANKS {&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; RANKS is numbers 0 to 30&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; card(grid.candidates[x][y][z])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_continue&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; min_card {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            t_x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            t_y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            t_z&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; z&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            min_card&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; min_card&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do break&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    demo_pt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; grid.demolitions[len(grid.demolitions)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; should never be empty&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    exhausted&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; demo_pt.ids_shuffle&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do if&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[t_x][t_y][t_z] {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; demo_pt.idx {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F; Skip till idx is reached.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; COLLAPSE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.cells[t_x][t_y][t_z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Air{}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.candidates[t_x][t_y][t_z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; transmute(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;)i8(id)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            cand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; Candidates{ id }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.cells[t_x][t_y][t_z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; cand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid.candidates[t_x][t_y][t_z]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        exhausted&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Here is the interesting part.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; exhausted&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do return&lt;&#x2F;span&gt;&lt;span&gt; .Exhausted_Candidates&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; grid_propagate(grid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; .Success&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; .Illegal_State&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;the-main-loop&quot;&gt;The Main Loop&lt;&#x2F;h3&gt;
&lt;p&gt;Before figuring out how the supposed &lt;code&gt;grid_backtrack&lt;&#x2F;code&gt; looks like, it might help to construct how the loop looks. With a side of Odin flavoured golf:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;main&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; () {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; new(Grid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid_init(grid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; inner tag is only for readability&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    outer:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; max(int)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; inner:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; grid_controlled_demolition(grid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        switch&lt;&#x2F;span&gt;&lt;span&gt; result {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span&gt; .Success:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; grid.candidates[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do break&lt;&#x2F;span&gt;&lt;span&gt; outer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            demo_pt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; Demolition_Point {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; grid.cells,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                ids_shuffle&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; IDS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            rand.shuffle(demo_pt.ids_shuffle[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            append(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;grid.demolitions, demo_pt)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span&gt; .Exhausted_Candidates, .Illegal_State:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grid_backtrack(grid, result)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; fmt.eprint(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;try&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, i,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; debug land&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            break&lt;&#x2F;span&gt;&lt;span&gt; inner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid_draw(grid)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- later&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;the-step-back&quot;&gt;The Step Back&lt;&#x2F;h3&gt;
&lt;p&gt;For backtracking, what is done depends on the error returned. If it is an illegal state, just increment the index and restart. If it is exhausted candidates, remove the last state, then increment the index of the previous one. This is the initial idea:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grid_backtrack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt; (grid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Grid&lt;&#x2F;span&gt;&lt;span&gt;, result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; result {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt; .Success: &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        unreachable()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt; .Exhausted_Candidates:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        pop(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;grid.demolitions)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt; .Illegal_State:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; nothing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    last&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; slice.last_ptr(grid.demolitions[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    last.idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid.cells&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; last.grid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid_propagate(grid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Unfortunately, putting all these together and running it, quickly hits a segfault. I could not figure out why at first, but then peppering a few &lt;code&gt;fmt.eprint&lt;&#x2F;code&gt; around, I realized that the state of &lt;code&gt;grid.candidates&lt;&#x2F;code&gt; wasn&#x27;t being reset properly between iterations. So any changes made to it in &lt;code&gt;grid_propagate&lt;&#x2F;code&gt; would persist.&lt;&#x2F;p&gt;
&lt;p&gt;I fixed that by adding a line just before the call to &lt;code&gt;grid_propagate&lt;&#x2F;code&gt; in &lt;code&gt;grid_backtrack&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid.cells&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; last.grid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid.candidates&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = ~&lt;&#x2F;span&gt;&lt;span&gt;Candidates{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- this one&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grid_propagate(grid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ok, not segfaulting. Good news. The peppered around &lt;code&gt;fmt.eprint&lt;&#x2F;code&gt;s show behaviour that make sense.&lt;&#x2F;p&gt;
&lt;p&gt;Also, similarly to the reset the world behaviour experimented with at first, this is still taking a long time to run, with no idea whether it halts or not. Building it with &lt;code&gt;-o:speed&lt;&#x2F;code&gt; as done before, and running it overnight might give the needed answer.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;out-of-memory&quot;&gt;Out of Memory&lt;&#x2F;h3&gt;
&lt;p&gt;I woke up to this:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-hanging-gardens-problem&#x2F;out_of_memory.png&quot; alt=&quot;Uses 30GB of memory&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I spent a few days trying different things out and seeing what is causing the ballooning in memory. For whatever reason, the program seemed to be allocating a lot more memory than I expected, and the dynamic array of &lt;code&gt;demolitions&lt;&#x2F;code&gt; is ballooning uncontrollably. In theory, there would be 31x31x31 successful demolitions at most. I tested this by using Odin&#x27;s core library&#x27;s &lt;code&gt;Small_Array&lt;&#x2F;code&gt;, which is a &quot;dynamic&quot; array with a fixed capacity, giving it 31x31x31 size, and it quickly filled up and panicked as it attempted appending to a full array. This indicates, to me, a logic error somewhere.&lt;&#x2F;p&gt;
&lt;p&gt;I tried different variations of the main loop, including inlining &lt;code&gt;grid_backtrack&lt;&#x2F;code&gt;. I removed the ID shuffling per &lt;code&gt;Demolition_Point&lt;&#x2F;code&gt;. I made the &lt;code&gt;Grid&lt;&#x2F;code&gt; smaller. I tried not shuffling &lt;code&gt;IDS&lt;&#x2F;code&gt;. All of them either ran into the same memory issue or just .. kept running.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-exception-1&quot;&gt;&lt;a href=&quot;#fn-exception&quot;&gt;9&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; I am at a complete loss of what the issue might be. Clearly this approach to backtracking is not working. I am honestly out of spoons thinking about this.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;giving-up-and-lessons-learned&quot;&gt;Giving Up and Lessons Learned&lt;&#x2F;h2&gt;
&lt;p&gt;To be honest, it has been almost two months since I started this article, and I am tired of iterating on the problem. &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-hanging-gardens-problem&#x2F;#frankenstein-s-monster&quot;&gt;Frankenstein&#x27;s Monster&lt;&#x2F;a&gt; works in theory, given infintie time, and for now this is enough for me. Maybe one day I will go back to figuring how to get to a slution in human time.&lt;&#x2F;p&gt;
&lt;p&gt;The part I enjoyed the most was iterating on the graphics with &lt;code&gt;raylib&lt;&#x2F;code&gt;. The library is really easy to use, if not as flexible as I hoped. Maybe for the next project I will do some sort of game, or just use it as generative art.&lt;&#x2F;p&gt;
&lt;p&gt;I should watch more Coding Train videos.&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;The original tile set inspired a number of games by Christian Freeling. One of them is Dominions, for which I wrote &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-garden-of-odin&#x2F;&quot;&gt;an implementation in Odin&lt;&#x2F;a&gt;. &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;This is what Freeling calls a &quot;Transcendental solution&quot;. &lt;a href=&quot;#fr-2-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;This might sound heretical in Sudoku, but in well constructed Sudoku puzzles there is always at least one cell with exactly one candidate in any given puzzle state thought solving. If ever there are not any, either it is not a well constructed puzzle, or the solver is unaware of the Ring of Phistomefel. &lt;a href=&quot;#fr-3-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-edges&quot;&gt;
&lt;p&gt;Nor does it into account the edges of the Grid (where only Red faces may, well, face.) However, the edges of the Grid are unlikely to be reached, so I will ignore that for now. &lt;a href=&quot;#fr-edges-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-metaphor&quot;&gt;
&lt;p&gt;Yes I am totally mixing metaphors right now. Way beyond Quantum Mechanics and well into AEC. Roll with it. &lt;a href=&quot;#fr-metaphor-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-symmetric&quot;&gt;
&lt;p&gt;More interesting variations can include a search for only symmetrical solutions. This would require additional, more complex constraints in candidate placements. Nothing that cannot be dome but a whole lot more code. &lt;a href=&quot;#fr-symmetric-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-iterating&quot;&gt;
&lt;p&gt;Iterating on this would be a lot more pleasant if generating the solution was faster. Maybe I should not have skipped that distributing work across threads step. &lt;a href=&quot;#fr-iterating-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-warning&quot;&gt;
&lt;p&gt;&quot;&lt;code&gt;Declaration of &#x27;grid&#x27; may cause a stack overflow due to its type &#x27;Grid&#x27; having a size of 297912 bytes&lt;&#x2F;code&gt;&quot; &lt;a href=&quot;#fr-warning-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-exception&quot;&gt;
&lt;p&gt;There was one exception where it terminated in 9 seconds. I realized that &lt;code&gt;0&lt;&#x2F;code&gt; being the first ID it always tests makes it fill everything with &lt;code&gt;Air&lt;&#x2F;code&gt; tiles. &lt;a href=&quot;#fr-exception-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>My Ideal Code Editor</title>
        <published>2024-09-24T00:00:00+00:00</published>
        <updated>2024-09-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/thoughts/my-ideal-code-editor/"/>
        <id>https://ar-ms.me/thoughts/my-ideal-code-editor/</id>
        
        <content type="html" xml:base="https://ar-ms.me/thoughts/my-ideal-code-editor/">&lt;p&gt;I have been doing some thinking about what my ideal code editor should be. I currently use VSCode, both to edit this site and to play around with code. However, VSCode is actually too powerful for my needs. And it lacks one crucial feature (that&#x27;s pretty much lacking from almost every text&#x2F;code editor outside of TextEdit and Notepad): proper Arabic language and Right-to-Left (RTL) support.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-rtl-1&quot;&gt;&lt;a href=&quot;#fn-rtl&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I tried several editors (honestly none more than 5 minutes) and I always go back to VSCode because of how comfortable it is. I tried &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;helix-editor.com&quot;&gt;Helix&lt;&#x2F;a&gt;, but could not live in the Terminal or modal editing. Tried Zed .. and it honestly just felt weird. Looked at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.codeedit.app&quot;&gt;CodeEdit&lt;&#x2F;a&gt;, which is a really interesting project that brings the Xcode aesthetic down to code editor level, but it is still a work in progress, and it still doesn&#x27;t deal with RTL properly.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-cot-1&quot;&gt;&lt;a href=&quot;#fn-cot&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This post is more for my own records than anything. Whenever I start on the great My Ideal Code Editor (Code name: MICE, or KTB, or whatever), I have a nice feature list to stick to.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;has-not&quot;&gt;Has Not&lt;&#x2F;h2&gt;
&lt;p&gt;MICE lacks the following features:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;An integrated Terminal. My usual terminal works just fine.&lt;&#x2F;li&gt;
&lt;li&gt;An integrated Git GUI. I can learn a few Git commands on the terminal.&lt;&#x2F;li&gt;
&lt;li&gt;An integrated remote connection. I am a hobbyist who works solo.&lt;&#x2F;li&gt;
&lt;li&gt;Built-in support for any language. Focus merely on the text features.&lt;&#x2F;li&gt;
&lt;li&gt;Any sort of preview or built-in compiler. With a possible concession to Markdown. (I really like VSCode&#x27;s Markdown preview pane)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;has&quot;&gt;Has&lt;&#x2F;h2&gt;
&lt;p&gt;However, MICE has these nice features:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;high-level-features&quot;&gt;High Level Features:&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Native UI. I am on a Mac. I would like a native Mac UI.&lt;&#x2F;li&gt;
&lt;li&gt;Arabic text support. If I have an Arabic paragraph inside of an English document, I would like said paragraph to be right-aligned.&lt;&#x2F;li&gt;
&lt;li&gt;Tabs. Directory pane.&lt;&#x2F;li&gt;
&lt;li&gt;A command line tool to open directories, like VSCode&#x27;s &lt;code&gt;code .&lt;&#x2F;code&gt; command. No idea currently on what else it needs to do.&lt;&#x2F;li&gt;
&lt;li&gt;Rely on the the system&#x27;s spell check in &lt;code&gt;txt&lt;&#x2F;code&gt; and &lt;code&gt;md&lt;&#x2F;code&gt; files.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;coding-features&quot;&gt;Coding Features&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;LSP support: To provide IDE capabilities for any language. Intellisense, Go To Definition, Rename Symbol, Inlay Hints, the works.&lt;&#x2F;li&gt;
&lt;li&gt;Tree-Sitter support: Syntax Highlighting (with perhaps LSP fallback), Multi-Cursor stuff, Code folding, Indentation. (Maybe through WASM plugins)&lt;&#x2F;li&gt;
&lt;li&gt;Syntax Highlighting can have &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;monaspace.githubnext.com&quot;&gt;multiple typefaces in it&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Smart editor features like auto-closing parentheses and select-and-type-a-brace-to-surround-block.&lt;&#x2F;li&gt;
&lt;li&gt;While no language support is Built-In, the default installation should come with the web&#x27;s defaults: HTML, CSS, JavaScript, and some useful additions like Sass, Markdown, and some Templating language like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;keats.github.io&#x2F;tera&#x2F;&quot;&gt;Tera&lt;&#x2F;a&gt;, the one used for this site.&lt;&#x2F;li&gt;
&lt;li&gt;Easy to install &quot;packages&quot; for additional languages.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;What else? I don&#x27;t know. I might add to this page once I think of anything or start any project.&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-rtl&quot;&gt;
&lt;p&gt;There are &lt;em&gt;Markdown&lt;&#x2F;em&gt; editors that support Arabic decently enough, such as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;bear.app&quot;&gt;Bear&lt;&#x2F;a&gt; and Obsidian. But those do not handle HTML and Sass and what goes into editing a website, even ones as simple as this. &lt;a href=&quot;#fr-rtl-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-cot&quot;&gt;
&lt;p&gt;2024-09-26: I also came across &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;coteditor.com&quot;&gt;CotEditor&lt;&#x2F;a&gt;. Looks nice and has good CJK support, with vertical text. &lt;a href=&quot;#fr-cot-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Garden of Odin</title>
        <published>2024-09-01T00:00:00+00:00</published>
        <updated>2024-09-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/thoughts/the-garden-of-odin/"/>
        <id>https://ar-ms.me/thoughts/the-garden-of-odin/</id>
        
        <content type="html" xml:base="https://ar-ms.me/thoughts/the-garden-of-odin/">&lt;p&gt;In an escape from the worries of life, I have been reading recently into the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;odin-lang.org&quot;&gt;Odin programming language&lt;&#x2F;a&gt;. I wanted to learn something that is closer to the metal than Rust, and Odin seems nice.&lt;&#x2F;p&gt;
&lt;p&gt;For a project to do with the language, I figured I would build a library for the abstract board game &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mindsports.nl&#x2F;index.php&#x2F;the-pit&#x2F;526-dominions&quot;&gt;Dominions, by Christian Freeling&lt;&#x2F;a&gt;. (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;senseis.xmp.net&#x2F;?Dominions&quot;&gt;Sensei&#x27;s Library link&lt;&#x2F;a&gt;). The game can be described as a Go variant with distinct pieces, as opposed to Go itself where every &quot;piece&quot; is identical.&lt;&#x2F;p&gt;
&lt;p&gt;The game is &lt;em&gt;weird&lt;&#x2F;em&gt;. It is much less known than Freeling&#x27;s other games like Havannah (for which I wrote &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;asibahi&#x2F;w9l&quot;&gt;an implementation for in Rust&lt;&#x2F;a&gt;) and Grand Chess (which I designed and built a physical set for). Even Freeling himself does not put much stock into it, and is more interested in the tile set itself (which he calls &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mindsports.nl&#x2F;index.php&#x2F;puzzles&#x2F;tilings&#x2F;china-labyrinth&#x2F;&quot;&gt;the China Labyrinth&lt;&#x2F;a&gt;, even though they have nothing to do with China) than the game. He made other games with the tile set which you can find by browsing his site.&lt;&#x2F;p&gt;
&lt;p&gt;In code and my handwritten notes, I call the tile set &lt;strong&gt;Bustan&lt;&#x2F;strong&gt;: Arabic for Garden (hence the name of this article). Variety, branches, paths, and fences all make gardens seem like an appropriate metaphor for what is going on.&lt;&#x2F;p&gt;
&lt;p&gt;This is the sample game Freeling posted on his website:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-garden-of-odin&#x2F;dominions.png&quot; alt=&quot;A game in progress of Dominions&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I am writing this post as a way to organize my thoughts on how to represent the game in code. It is a semi organized, semi-chronologically-sorted brain dump: I am writing it as I iterate over the code. I will be talking mostly about how to represent the game in code form, leaving the rules for later. The end result can be found in the git history of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;asibahi&#x2F;bustan&quot;&gt;&lt;code&gt;bustan&lt;&#x2F;code&gt; repository&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tiles&quot;&gt;Tiles&lt;&#x2F;h2&gt;
&lt;p&gt;The most intriguing feature of Dominions, for me, is the tiles. There are many tile sets and game piece sets in the world of games: chess, dominoes, mahjong, playing cards, tarot. Dominions tiles are such a set.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-garden-of-odin&#x2F;cl-small-set.png&quot; alt=&quot;Full set of Dominions Tiles&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Each tile defines how it connects to its neighbors. They do not rotate, but they can be flipped to change controller (which is how capture happens in the game). A full set of tiles, pictured above, has 64 shapes.&lt;&#x2F;p&gt;
&lt;p&gt;A clever Id&#x2F;numbering scheme for the tiles is described by Freeling.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-garden-of-odin&#x2F;numbering.png&quot; alt=&quot;Full set of Dominions Tiles&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Each side is assigned a power of two. So each piece unique id is simply the sum of which sides it connects. Binary system!&lt;&#x2F;p&gt;
&lt;p&gt;Each player starts the game with the full set of tiles, minus the Blank, the Zero-Tile, as it does not have a role in the game. So each tile has also, an owner.&lt;&#x2F;p&gt;
&lt;p&gt;During the game, control of tiles can be flipped from the owner to the opponent. After all one wins the game by controlling more tiles.&lt;&#x2F;p&gt;
&lt;p&gt;All this neatly fits into a &lt;code&gt;u8&lt;&#x2F;code&gt;! And Odin has bit-sets native into the language. When I was asking questions in Odin&#x27;s discord, Ginger Bill (BDFL of Odin) suggested this structure.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; 0b 0 0 _ 0 0 0 _ 0 0 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;    | |   | | |   | | |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;    | |   | | |   | | Top_Right&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;    | |   | | |   | Right&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;    | |   | | |   Btm_Right&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;    | |   | | Btm_Left&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;    | |   | Left&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;    | |   Top_Left&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;    | Owner_Is_Host&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;    Controller_Is_Host&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; the two players are Guest and Host. Guest starts.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile_Flag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; u8 {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Top_Rght,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Right,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Btm_Right,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Btm_Left,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Left,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Top_Left,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Owner_Is_Host,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Controller_Is_Host,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; distinct bit_set&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile_Flag&lt;&#x2F;span&gt;&lt;span&gt;;u8]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The game starts with 126 unique tiles. Guest starts with the tiles &lt;code&gt;0b00_000_001&lt;&#x2F;code&gt; to &lt;code&gt;0b00_111_111&lt;&#x2F;code&gt; (or neatly in Octal: &lt;code&gt;0o001&lt;&#x2F;code&gt; to &lt;code&gt;0o077&lt;&#x2F;code&gt;). Host starts with the tiles &lt;code&gt;0b11_000_001&lt;&#x2F;code&gt; to &lt;code&gt;0b11_111_111&lt;&#x2F;code&gt; (&lt;code&gt;0o301&lt;&#x2F;code&gt; to &lt;code&gt;0o377&lt;&#x2F;code&gt;). The highest bit may flip during the game.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; ^ is the pointer operator in Odin.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; ~ is bitwise XOR.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tile_flip&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;^ ~=&lt;&#x2F;span&gt;&lt;span&gt; Tile{.Controller_Is_Host}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;board-representation&quot;&gt;Board Representation&lt;&#x2F;h2&gt;
&lt;p&gt;Here is where I go back and forth into reading Red Blob Games&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.redblobgames.com&#x2F;grids&#x2F;hexagons&#x2F;&quot;&gt;excellent guide to Hexagonal boards&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The board of Dominions is a 9-sided hexagon. 217 cells. Ignoring tile placement restrictions for now, how to actually place tiles onto the board?&lt;&#x2F;p&gt;
&lt;p&gt;I oscillated (heh) between a few ideas, but eventually settled on a giant big array of &lt;code&gt;[217]Tile&lt;&#x2F;code&gt;, where an empty cell has the value &lt;code&gt;0&lt;&#x2F;code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. To calculate offsets, I adapted the functions declared in the Red Blob article, and started with this neat loop (&lt;code&gt;N&lt;&#x2F;code&gt;, &lt;code&gt;CENTER&lt;&#x2F;code&gt;, and &lt;code&gt;CELL_COUNT&lt;&#x2F;code&gt; are compile-time constants based on the board&#x27;s size):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;Board&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span&gt; [CELL_COUNT]Tile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;board_get_tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(back&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span&gt;[CELL_COUNT]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;, hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hex&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;, bool) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; hex_distance(hex, CENTER)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; N {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; From RedBlob on representing Hexagonal boards with an array of arrays:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Store Hex(q, r) at array[r][q - max(0, N-r)]. Row r size is 2*N+1 - abs(N-r).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; this loop calculates r&amp;#39;s offset.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    q, r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; hex[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;], hex[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    r_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; r_idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; r {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        r_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; int(N)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; abs(int(N&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; r_idx))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; r_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; int(q&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; max(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, N&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; r))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;back[idx],&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But having this loop run every time I make a look up is .. uncertain at best. So I decided to hardcode the row offsets:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;board_get_tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(back&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span&gt;[CELL_COUNT]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;, hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hex&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;, bool) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; hex_distance(hex, CENTER)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; N {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    q, r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; hex[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;], hex[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    r_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; r {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  0&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  1&lt;&#x2F;span&gt;&lt;span&gt;: r_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;   9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  2&lt;&#x2F;span&gt;&lt;span&gt;: r_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  19&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  3&lt;&#x2F;span&gt;&lt;span&gt;: r_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  30&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  4&lt;&#x2F;span&gt;&lt;span&gt;: r_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  42&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  5&lt;&#x2F;span&gt;&lt;span&gt;: r_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  55&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  6&lt;&#x2F;span&gt;&lt;span&gt;: r_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  69&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span&gt;: r_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  84&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  8&lt;&#x2F;span&gt;&lt;span&gt;: r_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;  9&lt;&#x2F;span&gt;&lt;span&gt;: r_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 117&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;: r_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 133&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;: r_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 148&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;: r_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 162&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span&gt;: r_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 175&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span&gt;: r_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 187&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;: r_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 198&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span&gt;: r_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 208&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; r_len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; int(q&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; max(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, N&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; r))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;back[idx],&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This has the advantage of being &quot;clean&quot;, with no wasted place in the array for unused coordinates.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;#fn-2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; Cell lookup is O(1): when checking a cell, it is imperative to check its neighbors quickly to verify legal moves.&lt;&#x2F;p&gt;
&lt;p&gt;A separate data structure would be needed to track the tiles in player&#x27;s hands (not in play yet).&lt;&#x2F;p&gt;
&lt;p&gt;An alternative idea is to represent &lt;code&gt;Tile&lt;&#x2F;code&gt; itself by a struct, that holds data whether the tile is in play, and if so its location on the board. However, the only way to quickly query the tile&#x27;s neighbors is to iterate over every tile at every check to know where it is. Might as well stuff them all in an array.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hand&quot;&gt;Hand&lt;&#x2F;h2&gt;
&lt;p&gt;Following the same idea from representing the board, Hands are better implemented as a fixed array. Initializing a full set of hands for both players by transmuting a &lt;code&gt;u8&lt;&#x2F;code&gt; into a &lt;code&gt;Tile&lt;&#x2F;code&gt;. &lt;em&gt;That is&lt;&#x2F;em&gt; why I wanted &lt;code&gt;Tile&lt;&#x2F;code&gt;s to be &lt;code&gt;u8&lt;&#x2F;code&gt;s to begin with!!&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;HAND_SIZE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 63&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; distinct&lt;&#x2F;span&gt;&lt;span&gt; [HAND_SIZE]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;hands_init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (guest&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hand&lt;&#x2F;span&gt;&lt;span&gt;, host&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hand&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; u8(HAND_SIZE) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        guest[i]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; transmute(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;)(i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0o001&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        host[i]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; transmute(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;)(i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0o301&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Also, to check the legality of move, the player has to have the tile available to play, so I defined a couple of helper &lt;del&gt;methods&lt;&#x2F;del&gt; procedures.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;hand_has_tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(hand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hand&lt;&#x2F;span&gt;&lt;span&gt;, id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; u8)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; bool {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    assert(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; id,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Blank Tile is not playable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    assert(id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; HAND_SIZE,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Tile is impossible&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;tile_is_empty(hand[id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;hand_get_tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(hand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hand&lt;&#x2F;span&gt;&lt;span&gt;, id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; u8)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;, bool) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;hand_has_tile(hand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span&gt;, id)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; hand[id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    hand[id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; ret,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;About here, I thought I would like to test my logic. So I took advantage of Odin&#x27;s testing framework with a couple of simple asserts. Note that I put these in the same file as the procedures they test, and they worked just fine. They are all prefixed with &lt;code&gt;test_*&lt;&#x2F;code&gt; not to pollute the autocompletion too much.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;core:testing&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;(test)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;test_hand_get_tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span&gt;testing.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;T&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    w, _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; hands_init()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; bool&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; should be successful&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tile, ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; hand_get_tile(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;w,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    testing.expect(t,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;tile_is_empty(tile))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    testing.expect(t, ok)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; should fail. tile was emptied&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tile, ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; hand_get_tile(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;w,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    testing.expect(t, tile_is_empty(tile))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    testing.expect(t,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;ok)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; other tests go here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After that, I figured I would make sure for every weird logic I make I&#x27;d have to write a bunch of tests to .. test it, and sanity check my code.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-game-object-first-draft&quot;&gt;&lt;em&gt;The&lt;&#x2F;em&gt; Game Object - First Draft&lt;&#x2F;h2&gt;
&lt;p&gt;Now that I have the basic, naïve framework of the game&#x27;s representation, I started looking into it from the other side: top down.&lt;&#x2F;p&gt;
&lt;p&gt;Looking at different game libraries, to see which API they provide and how they allow their users to interact with the internal rules engine. The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;shakmaty&#x2F;latest&#x2F;shakmaty&#x2F;&quot;&gt;shakmaty crate&lt;&#x2F;a&gt; has been of great help in the past, as well as the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;goban&#x2F;0.18.1&#x2F;goban&#x2F;&quot;&gt;goban crate&lt;&#x2F;a&gt;. JaniM from the Rust discord also shared with me their &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;JaniM&#x2F;variant-go-server&quot;&gt;Variant Go Server&lt;&#x2F;a&gt;. I also looked back at my &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;asibahi&#x2F;w9l&quot;&gt;Havannah implementation&lt;&#x2F;a&gt; which I did last year to remember how I structured things. (Maybe I&#x27;d tool both into WASM modules. How about that?)&lt;&#x2F;p&gt;
&lt;p&gt;Most of these structure their API around a specific object: the &lt;em&gt;Game&lt;&#x2F;em&gt; object, which is interacted with by querying legal moves, making moves, and, optionally, undoing moves. That&#x27;s it. The Game object tracks the state of all elements in the game.&lt;&#x2F;p&gt;
&lt;p&gt;The most straightforward way to do that is a struct. I do not really know if this is the &quot;optimal&quot; arrangement of fields, but I am doing what makes sense to me.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Player&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; u8 {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Guest,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; White. Goes first.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Host,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;  &#x2F;&#x2F; Black&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Status&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; u8 {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Ongoing,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Guest_Win,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Host_Win,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Tie,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; The Object of attention&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Game&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    board&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;                 &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Board&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    to_play&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;               &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Player&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    status&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Status&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    guest_hand, host_hand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hand&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; ... more to come&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To inquire about moves, a &lt;code&gt;Move&lt;&#x2F;code&gt; struct is needed&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-1&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. A move is simply a placement of a &lt;code&gt;Tile&lt;&#x2F;code&gt; on &lt;code&gt;Hex&lt;&#x2F;code&gt;. Whose tile and whose turn are ideally tracked and verified by the Game object.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Move&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This misses one big thing: Groups. Dominions is a game of territory, based on Go. Tiles together make Groups. Groups have liberties, which they live and die of. Groups capture other Groups. The winner is the player with bigger Groups. Groups are important.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bitboards&quot;&gt;Bitboards&lt;&#x2F;h2&gt;
&lt;p&gt;Before talking about Groups, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bitboard&quot;&gt;Bitboards&lt;&#x2F;a&gt; warrant an introduction.&lt;&#x2F;p&gt;
&lt;p&gt;Bitboards are, at their core, based on a simple observations: a chessboard has 64 squares, and a &lt;code&gt;u64&lt;&#x2F;code&gt; has 64 bits. By tying each bit address to a specific square, &lt;em&gt;any&lt;&#x2F;em&gt; binary value can be mapped.&lt;&#x2F;p&gt;
&lt;p&gt;In chess implementations: There is a bitboard (read: a &lt;code&gt;u64&lt;&#x2F;code&gt;) to mark where all the White pieces are. There is another bitboard to mark where all the squares the Queen sees are.&lt;&#x2F;p&gt;
&lt;p&gt;The other advantage of bitboards is that, since they are just bits, they have bit operations. With a bitboard showing the white pieces are and a bitboard showing where black&#x27;s pieces can move next turn: just &lt;code&gt;AND&lt;&#x2F;code&gt; them together and there is now a new bitboard of which pieces of white are under attack. They are small, simple integers, and operating on them is as easy as integers.&lt;&#x2F;p&gt;
&lt;p&gt;Unfortunately, however, the Dominions board is decidedly &lt;em&gt;not&lt;&#x2F;em&gt; 64 cells, or any such convenient number. It is 217 cells. It would be possible to represent the whole board with a 217bit integer, should it exist, but the largest bit set Odin provides is 128 bits. But have no fear! An array of 7 bit sets can solve the problem, as 7 &lt;code&gt;u32&lt;&#x2F;code&gt; integers can fit the needed 217 bits and more (namely 224 bits). This is as small as can be. Thanks to Odin&#x27;s array programming (which is also taken advantage of for Hex math), using bitwise operations on these bitboards is as easy as they are on usual bit-sets. The additional 7 bits can be used for metadata, as well.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Bitboard&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; distinct&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;bit_set&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;;u32]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; 7 * 32 = 224&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PLAY_AREA&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Bitboard&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;~&lt;&#x2F;span&gt;&lt;span&gt;{},&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ~&lt;&#x2F;span&gt;&lt;span&gt;{},&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ~&lt;&#x2F;span&gt;&lt;span&gt;{},&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ~&lt;&#x2F;span&gt;&lt;span&gt;{},&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ~&lt;&#x2F;span&gt;&lt;span&gt;{},&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ~&lt;&#x2F;span&gt;&lt;span&gt;{},&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ~&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;25&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 27&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 29&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 31&lt;&#x2F;span&gt;&lt;span&gt;}}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;DATA_AREA&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Bitboard&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&gt; {{}, {}, {}, {}, {}, {}, {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;25&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 27&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 29&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 31&lt;&#x2F;span&gt;&lt;span&gt;}}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Extra bits for metadata&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; helper procedure for common maths&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;(private&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;file&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bit_to_col_row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; int)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (col, row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; int) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    col&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bb_set_bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(bb&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Bitboard&lt;&#x2F;span&gt;&lt;span&gt;, bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; int) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; assert here to allow an unchecked version for meta data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    assert(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; CELL_COUNT)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    col, row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; bit_to_col_row(bit)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bb&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span&gt;[row]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; {col}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bb_get_bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(bb&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Bitboard&lt;&#x2F;span&gt;&lt;span&gt;, bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; int)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; bool {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    col, row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; bit_to_col_row(bit)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; col&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; bb[row]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Not to get ahead of the topic, but merging two of these bitboards (bitwise &lt;code&gt;OR&lt;&#x2F;code&gt;) is now as simple as this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;group_capture&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(blessed, cursed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; ----- snipped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    blessed.tiles&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; cursed.tiles&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; `tiles` field is a Bitboard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; ----- snipped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As an addition, I implemented an iterator over the set bits in &lt;code&gt;Bitboard&lt;&#x2F;code&gt;. Odin has nice syntax to iterate over the set flags in a bit-set, but an array of bit-sets presents a logistical challenge. I hacked at it for a couple of hours and came up with the following. Odin&#x27;s implementation of iterators is, all considered, fairly easy.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; The State machine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Bitboard_Iterator&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bb&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;   &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Bitboard&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    next&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; int,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bb_make_iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(bb&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Bitboard&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (it&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Bitboard_Iterator&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    it.bb&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; bb&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; PLAY_AREA&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; The iterator procedure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bb_iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(it&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Bitboard_Iterator&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hex&lt;&#x2F;span&gt;&lt;span&gt;, idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; int, ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; bool) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; it.next&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; CELL_COUNT {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; bb_get_bit(it.bb, i) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; hex_from_index(i)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            it.next&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; And it is used such:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bbi&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; bb_make_iter(bitboard_from_somewhere)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; hex, idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; bb_iter(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;bbi) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; do something with this hex or its corresponding index&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With the help of the Hex to Index math mentioned earlier in &lt;code&gt;Board&lt;&#x2F;code&gt; (and I have by now extracted it to another procedure), each bit in the bitboard can be quickly mapped to its corresponding Hex.&lt;&#x2F;p&gt;
&lt;p&gt;Which would bring the topic back to Groups, but there is another detour.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;slotmaps&quot;&gt;Slotmaps&lt;&#x2F;h2&gt;
&lt;p&gt;In my implementation of Havannah (linked earlier), I used the &lt;code&gt;slotmap&lt;&#x2F;code&gt; Rust crate to track groups. Odin does not have a slotmap&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-4-1&quot;&gt;&lt;a href=&quot;#fn-4&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; in its core library. There is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;gingerBill&#x2F;7282ff54744838c52cc80c559f697051&quot;&gt;a sample showcase implementation by Ginger Bill&lt;&#x2F;a&gt;, but I wanted to try my hand at this FFI thing. With help from the Rust and Odin discords to navigate the FFI of both languages, I did the following, and it works! Almost statically type checked from both sides, too.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;use&lt;&#x2F;span&gt;&lt;span&gt; slotmap&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;DefaultKey&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Key&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;KeyData&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SlotMap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; The Rust code does not need to manipulate the object in anyway.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; Type erased `*mut c_void` is all Rust knows: only a pointer.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SmItem&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = *&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; core&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;ffi&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;c_void;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SmPtr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = *&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SlotMap&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;DefaultKey&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SmItem&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;#[no_mangle]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-storage z-type&quot;&gt;pub extern&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;C&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span&gt; slotmap_init()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SmPtr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new(SlotMap&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;_,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SmItem&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;into_raw(sm)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;#[no_mangle]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-storage z-type&quot;&gt;pub unsafe extern&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;C&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span&gt; slotmap_destroy(sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SmPtr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; unsafe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;from_raw(sm) };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;#[no_mangle]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-storage z-type&quot;&gt;pub unsafe extern&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;C&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span&gt; slotmap_insert(sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SmPtr&lt;&#x2F;span&gt;&lt;span&gt;, item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SmItem&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt; -&amp;gt; u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-entity z-name z-type z-option&quot;&gt;    let Some&lt;&#x2F;span&gt;&lt;span&gt;(sm)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;unsafe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; { sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;as_mut() })&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; handle&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;insert(item);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    handle&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;data()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;as_ffi()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;#[no_mangle]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-storage z-type&quot;&gt;pub unsafe extern&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;C&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span&gt; slotmap_contains_key(sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SmPtr&lt;&#x2F;span&gt;&lt;span&gt;, key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u64&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-primitive&quot;&gt; -&amp;gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-entity z-name z-type z-option&quot;&gt;    let Some&lt;&#x2F;span&gt;&lt;span&gt;(sm)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;unsafe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; { sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;as_mut() })&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;DefaultKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from(KeyData&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from_ffi(key));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;contains_key(key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;#[no_mangle]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-storage z-type&quot;&gt;pub unsafe extern&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;C&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span&gt; slotmap_get(sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SmPtr&lt;&#x2F;span&gt;&lt;span&gt;, key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u64&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SmItem&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-entity z-name z-type z-option&quot;&gt;    let Some&lt;&#x2F;span&gt;&lt;span&gt;(sm)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;unsafe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; { sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;as_mut() })&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; core&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;null_mut();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;DefaultKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from(KeyData&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from_ffi(key));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get(key);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;    *&lt;&#x2F;span&gt;&lt;span&gt;ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap_or(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;core&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;null_mut())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;#[no_mangle]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-storage z-type&quot;&gt;pub unsafe extern&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;C&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span&gt; slotmap_remove(sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SmPtr&lt;&#x2F;span&gt;&lt;span&gt;, key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u64&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SmItem&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-entity z-name z-type z-option&quot;&gt;    let Some&lt;&#x2F;span&gt;&lt;span&gt;(sm)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;unsafe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; { sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;as_mut() })&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; core&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;null_mut();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;DefaultKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from(KeyData&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from_ffi(key));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;remove(key)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;unwrap_or(core&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;null_mut())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And after compiling this to a &lt;code&gt;staticlib&lt;&#x2F;code&gt;, do this from the Odin side:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;foreign import&lt;&#x2F;span&gt;&lt;span&gt; slotmap&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;deps&#x2F;slotmap&#x2F;libslotmap.a&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;core:c&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Slot_Map&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; distinct&lt;&#x2F;span&gt;&lt;span&gt; rawptr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sm_Key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; distinct&lt;&#x2F;span&gt;&lt;span&gt; c.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64_t&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;Sm_Item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; :: ^&lt;&#x2F;span&gt;&lt;span&gt;Group&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;foreign&lt;&#x2F;span&gt;&lt;span&gt; slotmap {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    slotmap_init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;         ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Slot_Map&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ---&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    slotmap_destroy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;      ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Slot_Map&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ---&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    slotmap_insert&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;       ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Slot_Map&lt;&#x2F;span&gt;&lt;span&gt;, item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sm_Item&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sm_Key&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ---&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    slotmap_contains_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Slot_Map&lt;&#x2F;span&gt;&lt;span&gt;, key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sm_Key&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;   -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; c.bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ---&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    slotmap_get&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;          ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Slot_Map&lt;&#x2F;span&gt;&lt;span&gt;, key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sm_Key&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;   -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sm_Item&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ---&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    slotmap_remove&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;       ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Slot_Map&lt;&#x2F;span&gt;&lt;span&gt;, key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sm_Key&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;   -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SmItem&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ---&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Odin&#x27;s type system allows a &lt;code&gt;rawptr&lt;&#x2F;code&gt; to really be cast to .. any pointer. So here all the types I &lt;em&gt;know&lt;&#x2F;em&gt; are the same, regardless of C&#x27;s type erasure, are marked with the same alias. Even though, as far as the C ABI is concerned, both &lt;code&gt;Slot_Map&lt;&#x2F;code&gt; and &lt;code&gt;Sm_Item&lt;&#x2F;code&gt; are &lt;code&gt;rawptr&lt;&#x2F;code&gt;s, but &lt;em&gt;I&lt;&#x2F;em&gt; know the difference. Conveniently, &lt;code&gt;Sm_Item&lt;&#x2F;code&gt; can now be easily dereferenced to get the underlying Group without casting.&lt;&#x2F;p&gt;
&lt;p&gt;Having done that, and as much as I am pleased with myself for getting this to work, I do not like that the keys are &lt;code&gt;u64&lt;&#x2F;code&gt;s. They are &lt;em&gt;large&lt;&#x2F;em&gt;: much larger than any number of groups&#x2F;indices required. Even in the unlikely event of each tile placed forming its own group, there would be a maximum of 126 groups (2 x 63). Eight bits would be enough to have a unique key for every possible group in the game. Something to optimize later, perhaps?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;groups-and-game-object-second-draft&quot;&gt;Groups, and Game Object - Second Draft&lt;&#x2F;h2&gt;
&lt;p&gt;A group is, simply, two bitboards:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tiles&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;     &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Bitboard&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    liberties&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Bitboard&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Each group keeps track of its location (which hexes it occupies) and its liberties. A group&#x27;s size and liberty count is calculated by calculating the cardinality of the respective bitboards.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bb_card&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(bb&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Bitboard&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; int) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; bb&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; PLAY_AREA&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; card(temp[i])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;group_size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; int {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; bb_card(grp.tiles)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;group_life&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; int {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; bb_card(grp.liberties)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To track groups, two fields are added to the Game Object: one for each player. Additionally, a &quot;Group Map&quot; of sorts might be needed to quickly look up the group any cell belongs to. (This is the initial idea, but keeping all these things in sync seems daunting. There could be a better design that is only revealed with a concrete implementation.)&lt;&#x2F;p&gt;
&lt;p&gt;Revisiting the &lt;code&gt;Game&lt;&#x2F;code&gt; struct from before:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Game&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    board&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;                 &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Board&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    to_play&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;               &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Player&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    status&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Status&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    last_move&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;             &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Maybe&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Move&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- I will get to that&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    guest_hand, host_hand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hand&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    groups_map&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;            [CELL_COUNT]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sm_Key&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    guest_grps, host_grps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Slot_Map&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that the score is not recorded here. As with many aspects of this design, I am currently unsure if it something should be tracked and updated individually with each move, or something calculated from the game state at any given moment.&lt;&#x2F;p&gt;
&lt;p&gt;There is also no history tracking, which needs lists of &lt;code&gt;Move&lt;&#x2F;code&gt;s and past  &lt;code&gt;Board&lt;&#x2F;code&gt;s and &lt;code&gt;Hand&lt;&#x2F;code&gt;s. The slotmap, being currently the only heap allocation, complicates undoing moves trivially, so a new &lt;code&gt;Game&lt;&#x2F;code&gt; object would be constructed from past raw data of boards and games. I decided to ignore history tracking for now.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; A player&amp;#39;s territory consists of the number of their pieces&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; on the board minus the number of pieces they didn&amp;#39;t place.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;game_get_score&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(game&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Game&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (guest, host&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; int) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; game.board {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;tile_is_empty(tile))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; .Controller_Is_Host&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; tile {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            host&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            guest&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; game.guest_hand {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;tile_is_empty(tile)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; guest&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; game.host_hand {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;tile_is_empty(tile)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; host&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  -=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now the game state and its metadata at any given point are neatly encoded, it is time to start thinking about how to make moves, and how to check their legality.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-game-rules&quot;&gt;The Game Rules&lt;&#x2F;h2&gt;
&lt;p&gt;So far, I made no mention of the game&#x27;s rules, only talking about its physical properties: the tiles, the board, the game zones. But players cannot place Tiles where they choose: here are the rules summarized for your convenience:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-garden-of-odin&#x2F;cl-small-set.png&quot; alt=&quot;Full set of Dominions Tiles&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tiles-1&quot;&gt;Tiles&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Each &lt;strong&gt;Tile&lt;&#x2F;strong&gt; has a specific set of sides it can connect to, encoded, visually, on the Tile itself.&lt;&#x2F;li&gt;
&lt;li&gt;Each Tile &lt;em&gt;must&lt;&#x2F;em&gt; match its neighboring Tiles in connections. &lt;strong&gt;Connected&lt;&#x2F;strong&gt; sides must match and &lt;strong&gt;Separated&lt;&#x2F;strong&gt; sides must match.&lt;&#x2F;li&gt;
&lt;li&gt;Board edges are considered neutral Separateds.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;groups&quot;&gt;Groups&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;Group&lt;&#x2F;strong&gt; is one or more Tiles of the same color (Controller) that are connected together. Adjacencies on Separated sides do not count.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;strong&gt;Liberties&lt;&#x2F;strong&gt; of a Group are its Connected sides border empty cells.&lt;&#x2F;li&gt;
&lt;li&gt;If a Group loses its last Liberty, it is captured, and all its tiles are flipped (switched Controller).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;the-structure&quot;&gt;The Structure&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;Structure&lt;&#x2F;strong&gt; is the collective name of all the connections together, in the whole board, &lt;em&gt;regardless of Controller&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Disconnected parts of the Structure are called &lt;strong&gt;Sections&lt;&#x2F;strong&gt;, created as Tiles are placed on Separated adjacencies. A single Section can include multiple Groups (but a Group cannot belong to multiple Sections).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;placement&quot;&gt;Placement&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;em&gt;Finally&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Bears repeating: A Tile can only be placed where it matches its neighbours in Connected and Separated sides.&lt;&#x2F;li&gt;
&lt;li&gt;Firstly, the Guest, first player, starts by placing any Tile anywhere.&lt;&#x2F;li&gt;
&lt;li&gt;Afterwards, a Tile can only be placed &lt;em&gt;adjacent to an enemy Tile&lt;&#x2F;em&gt;, with one exception.&lt;&#x2F;li&gt;
&lt;li&gt;A Tile can be placed where it is not adjacent to an enemy Tile &lt;em&gt;if and only if&lt;&#x2F;em&gt; it is extending a Group that is a whole Section.&lt;&#x2F;li&gt;
&lt;li&gt;Suicide is legal. Player may place a Tile so it has no Liberties (by matching its Liberties to enemy Tiles), and is therefore immediately captured.&lt;&#x2F;li&gt;
&lt;li&gt;Lastly, it is illegal to cause &lt;strong&gt;Oscillation&lt;&#x2F;strong&gt;: a Section which has no Liberties. &lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-5-1&quot;&gt;&lt;a href=&quot;#fn-5&quot;&gt;5&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;li&gt;
&lt;li&gt;A Player may, instead of placing a Tile, pass the turn instead. Or if they have no legal moves, they &lt;em&gt;must&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;scoring&quot;&gt;Scoring&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;The Game ends when both players pass consecutively.&lt;&#x2F;li&gt;
&lt;li&gt;The winner is the Player with the highest score.&lt;&#x2F;li&gt;
&lt;li&gt;The score is the amount of Tiles controlled on the board &lt;em&gt;minus&lt;&#x2F;em&gt; the Tiles still in Hand.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;moves-and-game-object-third-draft&quot;&gt;Moves, and Game Object - Third Draft&lt;&#x2F;h2&gt;
&lt;p&gt;Back to code. As a refresher, here is &lt;code&gt;Move&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Move&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That is all a &lt;code&gt;Move&lt;&#x2F;code&gt; is: the player whose turn it is (as tracked by &lt;code&gt;Game&lt;&#x2F;code&gt;) places a &lt;code&gt;Tile&lt;&#x2F;code&gt; from their hand into a &lt;code&gt;Hex&lt;&#x2F;code&gt;, and from there follows that groups get updated and tiles get flipped and game progresses.&lt;&#x2F;p&gt;
&lt;p&gt;But as a player may (or may have to) pass the turn, and as the game ends with two successive passes, &lt;code&gt;last_move&lt;&#x2F;code&gt; is registered in &lt;code&gt;Game&lt;&#x2F;code&gt; to track whether the game is about to end.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-6-1&quot;&gt;&lt;a href=&quot;#fn-6&quot;&gt;6&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To play the game, &lt;code&gt;Game&lt;&#x2F;code&gt; needs to have the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A way to make the move&lt;&#x2F;li&gt;
&lt;li&gt;A way to query if a move is legal&lt;&#x2F;li&gt;
&lt;li&gt;A way to query the list of legal moves&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Perhaps the most straightforward way to do it is to have &lt;code&gt;game_make_move&lt;&#x2F;code&gt; do &lt;em&gt;all&lt;&#x2F;em&gt; the work. It updates the game state, naturally, but also (based on said game state) update an embedded list of legal moves in &lt;code&gt;Game&lt;&#x2F;code&gt; itself. And then to check if a move is legal, simply query the embedded list of moves. Here is what &lt;code&gt;Game&lt;&#x2F;code&gt;, and the skeleton of &lt;code&gt;game_make_move&lt;&#x2F;code&gt;, look like now:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Game&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    board&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;                 &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Board&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    to_play&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;               &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Player&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    status&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Status&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    last_move&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;             &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Maybe&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Move&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    guest_hand, host_hand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hand&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    groups_map&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;            [CELL_COUNT]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SmKey&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    guest_grps, host_grps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SlotMap&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    legal_moves&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;           [&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;dynamic&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Move&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;game_make_move&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(game&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Game&lt;&#x2F;span&gt;&lt;span&gt;, try&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Maybe&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Move&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; bool {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (game.status&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .Ongoing)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Game is over.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    move, not_pass&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; try.?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; legal move check&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;not_pass&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        slice.contains(game.legal_moves[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;], move)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        board_is_empty(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;game.board))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer if&lt;&#x2F;span&gt;&lt;span&gt; game.status&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .Ongoing {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        switch&lt;&#x2F;span&gt;&lt;span&gt; game.to_play {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span&gt; .Guest: game.to_play&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .Host&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span&gt; .Host:  game.to_play&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .Guest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        game.last_move&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; move&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        game_regen_legal_moves(game)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;not_pass {&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;     &#x2F;&#x2F; Pass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; game.last_move&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;     &#x2F;&#x2F; Game ends&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            guest, host&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; game_get_score(game)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; guest&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; host&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; game.status&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .Guest_Win&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else if&lt;&#x2F;span&gt;&lt;span&gt; guest&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; host&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; game.status&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .Host_Win&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            else do&lt;&#x2F;span&gt;&lt;span&gt; game.status&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .Tie&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    active_hand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; game.to_play {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt; .Guest: active_hand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;game.guest_hand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt; .Host:  active_hand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;game.host_hand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Make move. Already known to be legal!!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    hand_tile, removed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; hand_remove_tile(active_hand, move.tile)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    assert(removed)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; but verify&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    game.board[hex_to_index(move.hex)]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; hand_tile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    move.tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; hand_tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; probably superfluous.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; TODO: update game state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;(private)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;game_regen_legal_moves&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(game&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Game&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    clear(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;game.legal_moves)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; TODO: build them again&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The two &lt;code&gt;TODO&lt;&#x2F;code&gt;s left are probably the meat of this whole engine. It is clearer to write them out in steps, in English, before encoding them into code.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;updating-the-game-state&quot;&gt;Updating the Game State&lt;&#x2F;h2&gt;
&lt;p&gt;The key observation, I think, is that the game state change starts from the where the last move is played. No need for a global search process, but only the exact Hex being played and the surrounding groups.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;group-section-init&quot;&gt;&lt;code&gt;group_section_init&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The simplest, and shortest, game state change that is not a Pass, is a Tile that starts its own Section. This happens in two occasions: the first move, and whenever a Tile is only adjacent to other tiles via its Separated sides. This Tile by definition also starts a new Group. This procedure assumes it is only called when a move is legal.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;(private)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;group_section_init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(move&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Move&lt;&#x2F;span&gt;&lt;span&gt;, game&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Game&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group&lt;&#x2F;span&gt;&lt;span&gt;, ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Check that all Connected sides connect to empty tiles.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; AND find Liberties&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; flag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; move.tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; CONNECTION_FLAGS {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        neighbor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; move.hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; flag_dir(flag)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        t, in_bounds&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; board_get_tile(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;game.board, neighbor)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; in_bounds {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tile_is_empty(t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            bb_set_bit(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;ret.liberties, hex_to_index(neighbor))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bb_set_bit(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;ret.tiles, hex_to_index(move.hex))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; CELL_COUNT is where the Extended flag is.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bb_set_bit_unchecked(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;ret.liberties, CELL_COUNT)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And in &lt;code&gt;game_make_move&lt;&#x2F;code&gt; :&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; grp, ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; group_section_init(move, game); ok {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; new_clone(grp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; slotmap_insert(game.host_grps, grp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    game.groups_map[hex_to_index(move.hex)]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;group-attach-to-friendlies&quot;&gt;&lt;code&gt;group_attach_to_friendlies&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The second easiest to deal with is a Tile that only connects to Groups of its own color. But there are a few variations&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Extension&lt;&#x2F;em&gt;: The Tile may only extend one Group&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Merge&lt;&#x2F;em&gt;: The Tile may merge two friendly Groups into one.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Suicide&lt;&#x2F;em&gt;: The Tile may consume the remaining Liberties of the Group(s) it connects to, Suiciding the whole Group. In which case the newly formed Group is captured (flipped) as a whole, and merged with the surrounding enemy Group(s).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The last case is interesting. Note that Move legality is checked earlier, so on principle, it is &lt;em&gt;known&lt;&#x2F;em&gt; that the newly formed enemy Group has at least one Liberty left.&lt;&#x2F;p&gt;
&lt;p&gt;A funny observation here is that it is impossible for a Tile that &lt;em&gt;only connects to friendlies&lt;&#x2F;em&gt; to Capture an enemy Group, but it is entirely possible that is causes its own Group to be immediately captured.&lt;&#x2F;p&gt;
&lt;p&gt;An easy check to whether this move is a Suicide is to check whether the new Tile has any Liberties of its own. For example: if it has 2 Connections and is connected to a friendly Group from only one side of the two, and the other Connection is to an empty cell, then it is obviously &lt;em&gt;not&lt;&#x2F;em&gt; a Suicide.&lt;&#x2F;p&gt;
&lt;p&gt;Ergo, the procedure for extension or merging is as follows. It turned &lt;em&gt;way&lt;&#x2F;em&gt; longer than I expected.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;(private)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;group_extend_or_merge&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(move&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Move&lt;&#x2F;span&gt;&lt;span&gt;, game&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Game&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Bug tracker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tile_liberties_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; card(move.tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; CONNECTION_FLAGS)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Friendliness tracker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tile_control&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; move.tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; {.Controller_Is_Host}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Scratchpad: Found Groups&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    nbr_friend_grps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sm_Key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    nfg_cursor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;      int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Scratchpad: New Liberties&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    new_libs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;    [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hex&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    libs_cursor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; flag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; move.tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; CONNECTION_FLAGS {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        neighbor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; move.hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; flag_dir(flag)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        nbr_tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; board_get_tile(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;game.board, neighbor)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; tile_is_empty(nbr_tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            new_libs[libs_cursor]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; neighbor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            libs_cursor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else if&lt;&#x2F;span&gt;&lt;span&gt; nbr_tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^ &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; {.Controller_Is_Host}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; tile_control {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F; Same Controller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tile_liberties_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F; record Group of neighbor tile.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; game.groups_map[hex_to_index(neighbor)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;slice.contains(nbr_friend_grps[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;], key) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                nbr_friend_grps[nfg_cursor]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                nfg_cursor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F; Different Controller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    assert(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tile_liberties_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;quot;if this is broken there is a legality bug&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    assert(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        nfg_cursor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;quot;This proc should not be called with no friendly neighbors&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; and if this is false then this might be a Suicide&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (tile_liberties_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == Are we the Baddies?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    friendly_grps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Slot_Map&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; tile_control&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; {} {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        friendly_grps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; game.guest_grps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        friendly_grps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; game.host_grps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == Identify first group&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    blessed_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; nbr_friend_grps[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    assert(slotmap_contains_key(friendly_grps, blessed_key))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    blessed_grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; slotmap_get(friendly_grps, blessed_key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bb_set_bit(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;blessed_grp.tiles, hex_to_index(move.hex))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == Merge other groups with first group&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; nfg_cursor {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assert(slotmap_contains_key(friendly_grps, nbr_friend_grps[i]))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; slotmap_remove(friendly_grps, nbr_friend_grps[i])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        defer&lt;&#x2F;span&gt;&lt;span&gt; free(grp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.tiles&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; grp.tiles&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Only if both Groups are extendable is the new one extendable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        play_area&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; PLAY_AREA&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; (blessed_grp.liberties&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt; grp.liberties)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        data_area&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; DATA_AREA&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; (blessed_grp.liberties&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; grp.liberties)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.liberties&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; play_area&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt; data_area&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == Update liberties&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bb_unset_bit(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;blessed_grp.liberties, hex_to_index(move.hex))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; l&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; libs_cursor {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        bb_set_bit(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;blessed_grp.liberties, hex_to_index(new_libs[l]))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == Update the groupmap&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bbi&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; bb_make_iter(blessed_grp.tiles)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; _, idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; bb_iter(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;bbi) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        game.groups_map[idx]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; blessed_key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; this should be all.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, what to do if it &lt;em&gt;is&lt;&#x2F;em&gt; a potential suicide? First of all, it is not possible to know whether it is a suicide or not without doing everything already done in &lt;code&gt;group_extend_or_merge&lt;&#x2F;code&gt; anyway. If it were a Suicide, the final, coalesced Group would have no Liberties, and therefore it would be an easy decision to simply flip its Controller and swap its allegiance.&lt;&#x2F;p&gt;
&lt;p&gt;The problem lies in how to merge it with its capturing Group(s). It needs to be merged to maintain an accurate count of Liberties, as the count of Liberties is clearly being used to test whether it needs to be captured or not!! (Not in &lt;em&gt;this&lt;&#x2F;em&gt; move. but in subsequent ones.)&lt;&#x2F;p&gt;
&lt;p&gt;The naïve approach is to iterate over every Tile member of the Group and every Connection of said Tile, and compile a list of opponent-controlled neighbors, then check the Group membership of &lt;em&gt;those&lt;&#x2F;em&gt; Tiles, (similarly to how &lt;code&gt;nbr_friend_grps&lt;&#x2F;code&gt; is used,) then do the merging routine again, but this time for the opponent.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;em&gt;other&lt;&#x2F;em&gt; naïve approach is to add a third &lt;code&gt;Bitboard&lt;&#x2F;code&gt; to &lt;code&gt;Group&lt;&#x2F;code&gt; to track its surrounding enemies and just iterate over those.&lt;&#x2F;p&gt;
&lt;p&gt;Both solutions bother me for different reasons. The first seems like a time and CPU cycle waste (as I am already iterating over the same Tile&#x27;s flags multiple times ..), and the second seems adds an extra knob to keep track of.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rethinking-groups&quot;&gt;Rethinking Groups&lt;&#x2F;h2&gt;
&lt;p&gt;One idea to explore is to change &lt;code&gt;Group&lt;&#x2F;code&gt;&#x27;s representation entirely, away from Bitboards. (Yes I spent a lot of time talking about Bitboards, and they&#x27;re really cool, but hear me out). Throughout the program, the state of the game has been tracked through a number of &lt;code&gt;[CELL_COUNT]&lt;&#x2F;code&gt; arrays, of variable things, with trivial conversion from a human-readable &lt;code&gt;Hex&lt;&#x2F;code&gt; to an index within these arrays. So what&#x27;s another &lt;code&gt;[CELL_COUNT]&lt;&#x2F;code&gt; array? But what would it be an array &lt;em&gt;of&lt;&#x2F;em&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;Currently, as far as a Group is concerned, a location can be one of three states: Either a member Tile, a Liberty, or an enemy Connection. That is an enum! More things can be added to it later as needed.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hex_State&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; u8 {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Empty&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;            =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0b000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; numbers chosen for a reason&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Liberty&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;          =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0b001&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Enemy_Connection&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0b011&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Member_Tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0b111&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And this how the &lt;code&gt;Group&lt;&#x2F;code&gt; using this enum would look like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Rethought_Group&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;      [CELL_COUNT]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hex_State&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    extendable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; bool,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; sadly no clean niche to hide that&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Much cleaner! Surprisingly, Odin allows bitwise OR over enumerations.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-7-1&quot;&gt;&lt;a href=&quot;#fn-7&quot;&gt;7&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; If the resulting value has no tag assigned, it becomes a &lt;code&gt;BAD_ENUM_VALUE&lt;&#x2F;code&gt; and may potentially wreck the program. But if the numbers are assigned appropriately, it can be made to always have a valid value.&lt;&#x2F;p&gt;
&lt;p&gt;Thinking through this, it is clear that &lt;code&gt;.Empty&lt;&#x2F;code&gt; with any other tag should be, well, that other tag. &lt;code&gt;.Liberty&lt;&#x2F;code&gt;, being essentially an empty cell as well, with any of the other two tags should produce the other tag. &lt;code&gt;.Member_Tile&lt;&#x2F;code&gt; and &lt;code&gt;.Enemy_Connection&lt;&#x2F;code&gt; overlap when capturing groups, so Enemies should be converted to Members. Here is the printed &lt;code&gt;OR&lt;&#x2F;code&gt; table:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          Empty   Liberty   Enemy   Member&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Empty     Empty   Liberty   Enemy   Member&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Liberty ------&amp;gt;   Liberty   Enemy   Member&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Enemy   ----------------&amp;gt;   Enemy   Member&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Member  ------------------------&amp;gt;   Member&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Great. Looks good to me. Let&#x27;s roll with it. This is how &lt;code&gt;Group&lt;&#x2F;code&gt; works now. Should I need more states I shall think of other clever numbers to use. Then follow the compiler&#x27;s errors about missing fields and correct those as needed.&lt;&#x2F;p&gt;
&lt;p&gt;Compiler driven development !!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;back-to-updating-game-state&quot;&gt;Back to Updating Game State&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;back-to-group-attach-to-friendlies&quot;&gt;Back to &lt;code&gt;group_attach_to_friendlies&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;This above change makes the merging process much simpler. It also allowed me to delete the entire &lt;code&gt;bitboard.odin&lt;&#x2F;code&gt; file! Following the compiler&#x27;s errors leads me to this version of &lt;code&gt;group_extend_or_merge&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;(private)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;group_extend_or_merge&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(move&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Move&lt;&#x2F;span&gt;&lt;span&gt;, game&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Game&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; ----- snip: same as before, for now.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == Identify first group&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    blessed_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; nbr_friend_grps[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    assert(slotmap_contains_key(friendly_grps, blessed_key))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    blessed_grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; slotmap_get(friendly_grps, blessed_key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    blessed_grp.state[hex_to_index(move.hex)]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .Member_Tile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == Merge other groups with first group&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; nfg_cursor {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assert(slotmap_contains_key(friendly_grps, nbr_friend_grps[i]))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; slotmap_remove(friendly_grps, nbr_friend_grps[i])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        defer&lt;&#x2F;span&gt;&lt;span&gt; free(grp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; grp.state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.extendable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; grp.extendable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == Update liberties&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; l&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; libs_cursor {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.state[hex_to_index(new_libs[l])]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; .Liberty&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == Update the groupmap&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; slot, idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; blessed_grp.state {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .Member_Tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; game.groups_map[idx]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; blessed_key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, merging groups membership and liberties also merges their enemy connections as well. No additional bookkeeping! The check for potential Suicide earlier can now be removed, and writing this (larger and larger) procedure can continue:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; ----- snip: same as before + declaring pointers to enemy groups&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == Update liberties&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; l&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; libs_cursor {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.state[hex_to_index(new_libs[l])]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; .Liberty&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; tile_liberties_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;      &#x2F;&#x2F; Potential Suicide&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;       &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; group_life(blessed_grp)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Definite Suicide&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; no insertion into the enemy slotmap .. there is merging to be done!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cursed_grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; slotmap_remove(friendly_grps, blessed_key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        defer&lt;&#x2F;span&gt;&lt;span&gt; free(cursed_grp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Scratchpad&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        nbr_enemy_grps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; make([&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;dynamic&lt;&#x2F;span&gt;&lt;span&gt;]Sm_Key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        defer&lt;&#x2F;span&gt;&lt;span&gt; delete(nbr_enemy_grps)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; loc, idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; cursed_grp.state {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            #partial&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; loc {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            case&lt;&#x2F;span&gt;&lt;span&gt; .Member_Tile:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                tile_flip(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;game.board[idx])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            case&lt;&#x2F;span&gt;&lt;span&gt; .Enemy_Connection:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; game.groups_map[idx]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;slice.contains(nbr_enemy_grps[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;], key) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    append(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;nbr_enemy_grps, key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; == same steps as before&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assert(len(nbr_enemy_grps)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; or there is Oscillation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nbr_enemy_grps[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assert(slotmap_contains_key(enemy_grps, blessed_key))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; slotmap_get(enemy_grps, blessed_key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; cursed_grp.state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; len(nbr_enemy_grps) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            assert(slotmap_contains_key(enemy_grps, nbr_enemy_grps[i]))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; slotmap_remove(enemy_grps, nbr_enemy_grps[i])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            defer&lt;&#x2F;span&gt;&lt;span&gt; free(grp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            blessed_grp.state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; grp.state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; check if blessed_grp is extendable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        extendable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; loc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; blessed_grp.state {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; loc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .Enemy_Connection {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                extendable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.extendable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; extendable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == Update the groupmap&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; slot, idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; blessed_grp.state {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .Member_Tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; game.groups_map[idx]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; blessed_key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Change the procedure&#x27;s name to &lt;code&gt;group_attach_to_friendlies&lt;&#x2F;code&gt;, and &lt;em&gt;now&lt;&#x2F;em&gt; it is done. All this merging logic should really be refactored and &lt;code&gt;DRY&lt;&#x2F;code&gt;&#x27;d, but I will let it be for now. This one procedure end up about 130 lines of code.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;group-attach-to-enemies&quot;&gt;&lt;code&gt;group_attach_to_enemies&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Similarly to attaching to friendlies, this move can either be a nothing, a capture, or a suicide. The logic of the &lt;code&gt;friendlies&lt;&#x2F;code&gt; procedure might need to be repeated in this one. And the checks done and the data collected would also need to be repeated.&lt;&#x2F;p&gt;
&lt;p&gt;So why separate it at all? The idea was it would simplify handling, but it does not seem to do that. So, rethinking the move handling, allow me to try summarising the logic that &lt;em&gt;actually&lt;&#x2F;em&gt; needs to be done (this was revised in tandem with writing the code in the next section):&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Create these trackers:
&lt;ol&gt;
&lt;li&gt;Liberties of the newly placed tile,&lt;&#x2F;li&gt;
&lt;li&gt;Neighboring, connected Friendlies (tracking Groups), and&lt;&#x2F;li&gt;
&lt;li&gt;Neighboring, connected Enemies (tracking locations).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Iterate over all Connected Sides of the newly placed tile, and fill in the trackers as needed,&lt;&#x2F;li&gt;
&lt;li&gt;For every Friendly connected Group, merge them together. (If none are connected, the Tile starts its own Group with marked Liberties and Enemy neighbors.) Mark this group as &quot;Blessed&quot;.&lt;&#x2F;li&gt;
&lt;li&gt;Iterate over neighboring Enemy Groups, if any have a Liberty count of 0: &lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-8-1&quot;&gt;&lt;a href=&quot;#fn-8&quot;&gt;8&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;
&lt;ol&gt;
&lt;li&gt;They are flipped and merged with the Blessed Group.&lt;&#x2F;li&gt;
&lt;li&gt;Iterate over connections of the Blessed Group, and merge with it any friendly Groups found.&lt;&#x2F;li&gt;
&lt;li&gt;Move is over. (This is because legal moves are already screened, or a check for Oscillation would be needed.)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;The Blessed Group is checked for Liberty count. If it is 0, it is captured (flipped) and merged with its surrounding Enemy Groups.&lt;&#x2F;li&gt;
&lt;li&gt;Done&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Note that I am assuming here that this is not a recursive operation. Here is the assumption: A new Tile placement that has no liberties &lt;em&gt;but&lt;&#x2F;em&gt; takes away the last liberty of an enemy Group captures it. There is no need to check if the surrounding friendly Groups (that surrounded the surrounding Enemy Groups) would also have no Liberties, because if they had no Liberties they would not exist! A lot of weight is placed right now on the correctness of &lt;code&gt;game_regen_legal_moves&lt;&#x2F;code&gt;, which is still delayed for later.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;game-update-state-inner-second-draft&quot;&gt;&lt;code&gt;game_update_state_inner&lt;&#x2F;code&gt; - Second Draft&lt;&#x2F;h3&gt;
&lt;p&gt;A monstrous 230-ish lines of code which could really use some refactoring. This drags on but I made my best to comment my thoughts throughout. Written without Tests, as I don&#x27;t actually know &lt;em&gt;how&lt;&#x2F;em&gt; to test this yet&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;(private)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;game_update_state_inner&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(move&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Move&lt;&#x2F;span&gt;&lt;span&gt;, game&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Game&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Bug tracker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tile_liberties&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; card(move.tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; CONNECTION_FLAGS)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tile_liberties_countdown&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; tile_liberties&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Friendliness tracker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tile_control&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; move.tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; {.Controller_Is_Host}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Scratchpad: Found friendly Groups&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    nbr_friend_grps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sm_Key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    nfg_counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;     uint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Scratchpad: Found Enemy Groups&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    nbr_enemy_tiles&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hex&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    net_counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;     uint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Scratchpad: New Liberties&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    new_libs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;     [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hex&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    libs_counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; uint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; flag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; move.tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; CONNECTION_FLAGS {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        neighbor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; move.hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; flag_dir(flag)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        nbr_tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; board_get_tile(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;game.board, neighbor)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; tile_is_empty(nbr_tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            new_libs[libs_counter]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; neighbor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            libs_counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else if&lt;&#x2F;span&gt;&lt;span&gt; nbr_tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^ &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; {.Controller_Is_Host}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; tile_control {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F; Same Controller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tile_liberties_countdown&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F; record Group of neighbor tile.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; game.groups_map[hex_to_index(neighbor)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;slice.contains(nbr_friend_grps[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;], key) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                nbr_friend_grps[nfg_counter]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                nfg_counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F; Different Controller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tile_liberties_countdown&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            nbr_enemy_tiles[net_counter]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; neighbor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            net_counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    assert(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tile_liberties_countdown&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;quot;if this is broken there is a legality bug&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == Are we the Baddies?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    friendly_grps, enemy_grps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Slot_Map&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; tile_control&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; {} {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Guest Controller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        friendly_grps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; game.guest_grps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        enemy_grps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; game.host_grps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Host Controller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        friendly_grps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; game.host_grps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        enemy_grps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; game.guest_grps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; The placed Tile&amp;#39;s Group&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    blessed_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sm_Key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    blessed_grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sm_Item&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; nfg_counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; new(Group)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; slotmap_insert(friendly_grps, blessed_grp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; net_counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            blessed_grp.extendable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nbr_friend_grps[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assert(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            slotmap_contains_key(friendly_grps, blessed_key),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;Friendly slotmap does not have friendly Key&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; slotmap_get(friendly_grps, blessed_key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; == Merge other groups with blessed group&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; nfg_counter {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            assert(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                slotmap_contains_key(friendly_grps, nbr_friend_grps[i]),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;quot;Friendly slotmap does not have friendly Key&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            temp_grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; slotmap_remove(friendly_grps, nbr_friend_grps[i])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            defer&lt;&#x2F;span&gt;&lt;span&gt; free(temp_grp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            blessed_grp.state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; temp_grp.state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            blessed_grp.extendable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; temp_grp.extendable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    blessed_grp.state[hex_to_index(move.hex)]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; .Member_Tile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; == Update the groupmap&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; slot, idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; blessed_grp.state {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .Member_Tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; game.groups_map[idx]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; blessed_key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == Update liberties&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; libs_counter {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.state[hex_to_index(new_libs[i])]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; .Liberty&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == Update Enemy neighbors for blessed group&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; net_counter {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.state[hex_to_index(nbr_enemy_tiles[i])]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; .Enemy_Connection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == register surrounding Enemy Groups of blessed Group&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    surrounding_enemy_grps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; make([&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;dynamic&lt;&#x2F;span&gt;&lt;span&gt;]Sm_Key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; delete(surrounding_enemy_grps)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; slot, idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; blessed_grp.state {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (slot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .Enemy_Connection)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; game.groups_map[idx]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;slice.contains(surrounding_enemy_grps[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;], key) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            append(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;surrounding_enemy_grps, key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == if there are no surrounding enemy groups there is nothing to do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; len(surrounding_enemy_grps)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assert(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            group_life(blessed_grp)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;newly formed groups must have liberties or enemy connections&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.extendable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == these are the friendly groups that surround the dead enemy groups.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    level_2_surrounding_friendlies&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; make([&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;dynamic&lt;&#x2F;span&gt;&lt;span&gt;]Sm_Key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; delete(level_2_surrounding_friendlies)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == go over surrounding enemy groups to see if they&amp;#39;re dead.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    capture_occurance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; surrounding_enemy_grps {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assert(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            slotmap_contains_key(enemy_grps, key),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;Enemy slotmap does not have enemy Key&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        temp_grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; slotmap_get(enemy_grps, key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        temp_grp.state[hex_to_index(move.hex)]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; .Enemy_Connection&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; spoiler: there be bugs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Enemy Group is dead&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (group_life(temp_grp)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        capture_occurance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cursed_grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; slotmap_remove(enemy_grps, key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        defer&lt;&#x2F;span&gt;&lt;span&gt; free(cursed_grp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; slot, idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; cursed_grp.state {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            #partial&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; slot {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            case&lt;&#x2F;span&gt;&lt;span&gt; .Member_Tile:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                tile_flip(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;game.board[idx])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            case&lt;&#x2F;span&gt;&lt;span&gt; .Enemy_Connection:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; game.groups_map[idx]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;slice.contains(level_2_surrounding_friendlies[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;], key) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    append(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;level_2_surrounding_friendlies, key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; CAPTURE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;      |=&lt;&#x2F;span&gt;&lt;span&gt; cursed_grp.state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.extendable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; cursed_grp.extendable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == merge level 2 surrounding friendlies into blessed group&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; level_2_surrounding_friendlies {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assert(slotmap_contains_key(friendly_grps, key))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        temp_grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; slotmap_remove(friendly_grps, key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        defer&lt;&#x2F;span&gt;&lt;span&gt; free(temp_grp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; temp_grp.state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.extendable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; temp_grp.extendable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == if there is a capture, it is done.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; capture_occurance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == if blessed group&amp;#39;s liberties larger than 0, it is done capturing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; group_life(blessed_grp)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == Now the blessed group has converted.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cursed_grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; slotmap_remove(friendly_grps, blessed_key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; free(cursed_grp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    new_family&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; make([&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;dynamic&lt;&#x2F;span&gt;&lt;span&gt;]Sm_Key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; delete(new_family)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; loc, idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; blessed_grp.state {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        #partial&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; loc {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span&gt; .Member_Tile:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tile_flip(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;game.board[idx])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        case&lt;&#x2F;span&gt;&lt;span&gt; .Enemy_Connection:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; game.groups_map[idx]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;slice.contains(new_family[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;], key) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                append(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;new_family, key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    assert(len(new_family)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Oscillation&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    blessed_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; new_family[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    assert(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        slotmap_contains_key(enemy_grps, blessed_key),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;quot;Enemy key is not in enemy map&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    blessed_grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; slotmap_get(enemy_grps, blessed_key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    blessed_grp.state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; cursed_grp.state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; len(new_family) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assert(slotmap_contains_key(enemy_grps, new_family[i]))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        temp_grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; slotmap_remove(enemy_grps, new_family[i])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        defer&lt;&#x2F;span&gt;&lt;span&gt; free(temp_grp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; temp_grp.state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; check if new blessed group is extendable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    extendable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; loc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; blessed_grp.state {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; loc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .Enemy_Connection {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            extendable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    blessed_grp.extendable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; extendable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I attempted refactoring some of it out but I am not sure the result is necessarily better. I also used the &lt;code&gt;core:container&#x2F;small_array&lt;&#x2F;code&gt; library (from the Odin core lib) to smooth some of the logic.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;game-regen-legal-moves&quot;&gt;&lt;code&gt;game_regen_legal_moves&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;This is the current state of this procedure, which a lot is riding on:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-attribute&quot;&gt;(private)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;game_regen_legal_moves&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(game&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Game&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    clear(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;game.legal_moves)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; todo: build them again&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is perhaps an easier problem than it presented to me at first. The rules have a harsh restriction to placement: any Tile placed MUST be placed next to an enemy Tile, unless it extends a Group which makes its own Section (which is already being tracked by the &lt;code&gt;extendable&lt;&#x2F;code&gt; field in &lt;code&gt;Group&lt;&#x2F;code&gt;. Assuming the logic, of course, is correct.)&lt;&#x2F;p&gt;
&lt;p&gt;The naïve, crude approach is as follows: Iterate over every empty &lt;code&gt;Hex&lt;&#x2F;code&gt;, and if it has an enemy neighbor, &lt;em&gt;or&lt;&#x2F;em&gt; if it has a friendly neighbor that is part of an extendable Group &lt;em&gt;and&lt;&#x2F;em&gt; it is that Group&#x27;s liberty, add it to the candidates. Then for each &lt;code&gt;Hex&lt;&#x2F;code&gt; of the candidates, iterate over the friendly &lt;code&gt;Hand&lt;&#x2F;code&gt;, and add a &lt;code&gt;Move&lt;&#x2F;code&gt; where the &lt;code&gt;Tile&lt;&#x2F;code&gt; fits. There might be a more efficient way but this will do for now.&lt;&#x2F;p&gt;
&lt;p&gt;(Yes this does not take Oscillation into account, yet?)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;game_regen_legal_moves&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(game&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Game&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    clear(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;game.legal_moves)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == Are we the Baddies?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    friendly_grps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Slot_Map&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    friendly_hand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    enemy_grps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Slot_Map&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; game.to_play {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt; .Guest:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        friendly_grps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; game.guest_grps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        friendly_hand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;game.guest_hand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        enemy_grps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span&gt; game.host_grps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt; .Host:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        friendly_grps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; game.host_grps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        friendly_hand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-keyword z-operator&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;game.host_hand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        enemy_grps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span&gt; game.guest_grps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; get the hexes allowed to be played in&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    playable_hexes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; make([&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;dynamic&lt;&#x2F;span&gt;&lt;span&gt;]Hex)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; delete(playable_hexes)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    outer:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; key, idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; game.groups_map {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Hex must be empty. Hope Slotmap does not give a Key of 0.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; hex_from_index(idx)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; flag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; CONNECTION_FLAGS {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            nbr_hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; flag_dir(flag)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            nbr_idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; hex_to_index(nbr_hex)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            nbr_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; game.groups_map[nbr_idx]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; nbr_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; slotmap_contains_key(enemy_grps, nbr_key) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                append(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;playable_hexes, hex)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                continue&lt;&#x2F;span&gt;&lt;span&gt; outer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else if&lt;&#x2F;span&gt;&lt;span&gt; slotmap_contains_key(friendly_grps, nbr_key) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; slotmap_get(friendly_grps, nbr_key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span&gt; grp.extendable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; grp.state[idx]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .Liberty {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    append(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;playable_hexes, hex)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt; outer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                &#x2F;&#x2F; This is essentially an assert.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                panic(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;key is not 0, is not in friendly groups, not in enemy groups, ??&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; fill Tiles to go with found hexes.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    candidate_moves&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; make([&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;dynamic&lt;&#x2F;span&gt;&lt;span&gt;]Move)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; delete(candidate_moves)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; playable_hexes {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; hex_to_index(hex)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; friendly_hand {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; tile_is_empty(tile)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            score&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; if score is 6, tile is playable.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            defer if&lt;&#x2F;span&gt;&lt;span&gt; score&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; append(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;candidate_moves, Move{hex, tile})&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            for&lt;&#x2F;span&gt;&lt;span&gt; flag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; CONNECTION_FLAGS {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                nbr_hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  :=&lt;&#x2F;span&gt;&lt;span&gt; hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; flag_dir(flag)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                nbr_idx, in_bounds&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; hex_to_index(nbr_hex)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                nbr_tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; game.board[nbr_idx]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; nbr_idx == 0 when out&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                ((&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;in_bounds&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; flag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; not_in&lt;&#x2F;span&gt;&lt;span&gt; tile)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                 (in_bounds&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;  &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; (tile_is_empty(nbr_tile)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;  &#x2F;* so much rightward drift *&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;  (flag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt;     tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; flag_opposite(flag)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt;     nbr_tile)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;  &#x2F;* the line is 102 chars *&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;    (flag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; not_in&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; flag_opposite(flag)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; not_in&lt;&#x2F;span&gt;&lt;span&gt; nbr_tile))))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                score&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; todo: deal with Oscillation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;oscillation&quot;&gt;Oscillation&lt;&#x2F;h3&gt;
&lt;p&gt;Now, back to Oscillation. What&#x27;s that again?&lt;&#x2F;p&gt;
&lt;p&gt;When a Group has no Liberties, it is converted to the other side. If, upon conversion, it  &lt;em&gt;still&lt;&#x2F;em&gt; has no Liberties, it flips again, and .. well .. oscillates. That&#x27;s illegal!&lt;&#x2F;p&gt;
&lt;p&gt;So Oscillation as a result of a Move can only happen if a Group has only one Liberty and the Move is on &lt;em&gt;that&lt;&#x2F;em&gt; Hex. So I will make a number of assumptions here:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;If the Move connects only to &lt;em&gt;extendable&lt;&#x2F;em&gt; Groups (Friendly or Enemy), and takes away their last Liberty, it is Oscillation.&lt;&#x2F;li&gt;
&lt;li&gt;If the Move connects to a usual Group (Friendly or Enemy), it is &lt;em&gt;not&lt;&#x2F;em&gt; Oscillation, but either a Capture or a Suicide. (If the surrounding Groups had no other Liberties of their own, they&#x27;d be Captured already).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;I do not know if these assumptions would actually work out. A more sure approach is to actually just ... make the move, and should there be an Oscillation, reject it, and roll back the changes. While it is possible, it would make the list of legal moves &lt;em&gt;wrong&lt;&#x2F;em&gt;, as it might include these Oscillation moves.&lt;&#x2F;p&gt;
&lt;p&gt;Encoding these rules in the loop above is perhaps the best option. It would save an allocation of &lt;code&gt;candidate_moves&lt;&#x2F;code&gt;, and it is already iterating the edges and the neighbors. It could have its own tracker and score. This is how it currently looks:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; ------- same as before, minus the temporary `candidate_moves`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; playable_hexes {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; hex_to_index(hex)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; friendly_hand {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; tile_is_empty(tile)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            score&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;   :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; if score is 6, tile is playable.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            osc_pen&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; unless this is equal to Tile cardinality&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            defer if&lt;&#x2F;span&gt;&lt;span&gt; score&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; osc_pen&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span&gt; card(tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; CONNECTION_FLAGS) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                append(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;game.legal_moves, Move{hex, tile})&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            for&lt;&#x2F;span&gt;&lt;span&gt; flag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; CONNECTION_FLAGS {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                nbr_hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  :=&lt;&#x2F;span&gt;&lt;span&gt; hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; flag_dir(flag)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                nbr_idx, in_bounds&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; hex_to_index(nbr_hex)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                nbr_tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; game.board[nbr_idx]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; nbr_idx == 0 when out&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                ((&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;in_bounds&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; flag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; not_in&lt;&#x2F;span&gt;&lt;span&gt; tile)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                 (in_bounds&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; (tile_is_empty(nbr_tile)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                (flag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt;     tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; flag_opposite(flag)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt;     nbr_tile)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                (flag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; not_in&lt;&#x2F;span&gt;&lt;span&gt; tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; flag_opposite(flag)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; not_in&lt;&#x2F;span&gt;&lt;span&gt; nbr_tile))))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                score&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                &#x2F;&#x2F; Only check for Oscillation if it takes away a Liberty.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                (in_bounds&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; flag_opposite(flag)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; nbr_tile)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                nbr_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;  :=&lt;&#x2F;span&gt;&lt;span&gt; game.groups_map[nbr_idx]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span&gt; slotmap_contains_key(enemy_grps, nbr_key) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    nbr_grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; slotmap_get(enemy_grps, nbr_key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    if&lt;&#x2F;span&gt;&lt;span&gt; group_life(nbr_grp)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; nbr_grp.extendable {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        osc_pen&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else if&lt;&#x2F;span&gt;&lt;span&gt; slotmap_contains_key(friendly_grps, nbr_key) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    nbr_grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; slotmap_get(friendly_grps, nbr_key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    if&lt;&#x2F;span&gt;&lt;span&gt; group_life(nbr_grp)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; nbr_grp.extendable {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        osc_pen&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;One tiny thing, this is &lt;code&gt;flag_opposite&lt;&#x2F;code&gt; :&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flag_opposite&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(flag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile_Flag&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile_Flag&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #partial&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span&gt; flag {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt; .Top_Right: ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .Btm_Left&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt; .Right:     ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .Left&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt; .Btm_Right: ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .Top_Left&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt; .Btm_Left:  ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .Top_Right&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt; .Left:      ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .Right&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt; .Top_Left:  ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .Btm_Right&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I think it is done!! What&#x27;s left? Oh, actually using it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;first-bug&quot;&gt;First Bug&lt;&#x2F;h2&gt;
&lt;p&gt;Did not take long to find a bug.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;main&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    game&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; game_init()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; game_destroy(game)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; bool&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; game_make_move(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;        &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;game,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Move{hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}, tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tile_from_id(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;63&lt;&#x2F;span&gt;&lt;span&gt;, .Guest)}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    fmt.printfln(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;%v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, ok)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; game_make_move(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;        &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;game,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Move{hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}, tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tile_from_id(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;63&lt;&#x2F;span&gt;&lt;span&gt;, .Host)}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    fmt.printfln(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;%v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, ok)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    fmt.printfln(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;%v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, game.groups_map)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Both moves should be legal, and indeed both &lt;code&gt;ok&lt;&#x2F;code&gt;s are true. However, going over the printed output of &lt;code&gt;game.groups_map&lt;&#x2F;code&gt;, I noticed both of these tiles have the exact same Key. (And is in fact the same Key across multiple runs: 4294967297.)&lt;&#x2F;p&gt;
&lt;p&gt;This is an artifact of how the &lt;code&gt;slotmap&lt;&#x2F;code&gt; crate does its thing, as I found out. The problem is that so far I have been operating under the assumption that the Keys produced are, at least reasonably, different from each other, as I have been using this Key in no less than three places to know in which camp does a key belong. (One of them is &lt;code&gt;game_destroy&lt;&#x2F;code&gt;, where it doesn&#x27;t matter, but still!)&lt;&#x2F;p&gt;
&lt;p&gt;The easy fix would be perhaps to annotate all three lookups with companion look ups to see the owner of the &lt;code&gt;Tile&lt;&#x2F;code&gt; in the corresponding &lt;code&gt;game.board&lt;&#x2F;code&gt; index. But this feels like a bandaid, that also adds another failure point.&lt;&#x2F;p&gt;
&lt;p&gt;Trying different values I came across another bug that apparently triggered an assertion, but it was whether a &lt;code&gt;slotmap&lt;&#x2F;code&gt; contains a key or not. So a fix for this first bug is needed before any procession.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rethinking-the-need-for-slotmap&quot;&gt;Rethinking the Need for &lt;code&gt;slotmap&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Using a Rust crate for this functionality has a couple of pain points already:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;I have mentioned this before, but &lt;code&gt;u64&lt;&#x2F;code&gt; Keys are &lt;em&gt;huge&lt;&#x2F;em&gt;. They are much larger than what is needed in this game. The amount of Groups the entire game cannot actually exceed 126. (If all Tiles were played and each Tile had its own Group, which is also impossible.)&lt;&#x2F;li&gt;
&lt;li&gt;Speed of access: the slotmaps are behind pointers and the Groups are behind pointers, and this is checked and accessed multiple times per move.&lt;&#x2F;li&gt;
&lt;li&gt;Compilation: while this set up works fine on my machine &lt;small&gt;TM&lt;&#x2F;small&gt;, compiling a shim Rust crate separately from the main Odin codebase is a bit more effort than what is usually needed. If this were to be set up for users, I would need to include a build system.&lt;&#x2F;li&gt;
&lt;li&gt;WASM: Add to that, while &lt;code&gt;slotmap&lt;&#x2F;code&gt; itself can be compiled to WASM just fine, compiling two languages into one WASM module is .. not the easiest path forward.&lt;&#x2F;li&gt;
&lt;li&gt;Last but not least, undoing the Game state (something which is needed for engines) would be a &lt;em&gt;lot&lt;&#x2F;em&gt; easier if there were no pointers involved.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;So now what? Is a slotmap-like data structure even the correct decision at all, actually? Slotmap&#x27;s advantage is reusing existing allocations for deleted items, while &lt;em&gt;not&lt;&#x2F;em&gt; reusing the handles&#x2F;indices. But if it lives all on the stack, say through a &lt;code&gt;[CELL_COUNT]Group&lt;&#x2F;code&gt; array, it is not possible to grow memory dynamically as needed (since it is all statically allocated), and one would have to allocate for the worst case scenario &lt;em&gt;anyway&lt;&#x2F;em&gt; removing the main advantage there.&lt;&#x2F;p&gt;
&lt;p&gt;One option is to put Groups in a fixed array, and use indices into that array as keys, and simply stop using that index whenever a Group dies. While a real game is never getting to 126 Groups at once, and there is no game database of played Dominions games to analyze and determine the maximum number of Groups in a real game is. Using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mindsports.nl&#x2F;index.php&#x2F;dagaz&#x2F;954-dominions&quot;&gt;Mindsports&#x27; applet&lt;&#x2F;a&gt;, I managed to get to about 92 individual living &quot;groups&quot; at the same time before I got bored.&lt;&#x2F;p&gt;
&lt;p&gt;How would this look like, though? Separate arrays, one for each player? One array for both? If the second, how to distinguish between friendly and enemy groups storage?&lt;&#x2F;p&gt;
&lt;p&gt;My current thinking is to borrow the handle&#x2F;index++ idea and invent, essentially, my own handle. Honestly I just want an excuse to use Odin&#x27;s bit fields.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group_Handle&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; bit_field&lt;&#x2F;span&gt;&lt;span&gt; u8 {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;  name:  Type   | Size&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;   u8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;     |&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Player&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    valid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;   |&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;idx&lt;&#x2F;code&gt; here cannot, ever, be more than 63, which is all the address space needed for the worst case scenario, and a little bit more. The &lt;code&gt;owner&lt;&#x2F;code&gt; field is one bit, either this player or that player. The last bit is a funny one: it is just to allow using the zero value of the key (where &lt;code&gt;valid&lt;&#x2F;code&gt; is false), as a sentinel value for an empty slot. At first, I considered having the &lt;code&gt;extendable&lt;&#x2F;code&gt; boolean I have had in &lt;code&gt;Group&lt;&#x2F;code&gt;, but that just makes bookkeeping and updating &lt;code&gt;Group&lt;&#x2F;code&gt; status that much harder. &lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-9-1&quot;&gt;&lt;a href=&quot;#fn-9&quot;&gt;9&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; So now how about this?&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Rethought_Group&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;        [CELL_COUNT]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hex_State&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;    using&lt;&#x2F;span&gt;&lt;span&gt; status&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; bit_field&lt;&#x2F;span&gt;&lt;span&gt; u8 {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        extendable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        alive&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;      bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _padding&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;   u8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;   |&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;- ?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;Group_Store&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; todo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The field &lt;code&gt;_padding&lt;&#x2F;code&gt; is there to suppress a compiler warning about boolean-only bit fields being a terrible idea.&lt;&#x2F;p&gt;
&lt;p&gt;Mind you &lt;code&gt;Rethought_Group&lt;&#x2F;code&gt; has two Odin features Ginger Bill dislikes using: &lt;code&gt;using&lt;&#x2F;code&gt; and &lt;code&gt;bool&lt;&#x2F;code&gt;-only &lt;code&gt;bit_field&lt;&#x2F;code&gt;s, and uses them together, with an anonymous &lt;code&gt;bit_field&lt;&#x2F;code&gt; to boot. (I am actually pleasantly surprised this compiles and works at all.) My goal here is to essentially cram both of &lt;code&gt;extendable&lt;&#x2F;code&gt; and &lt;code&gt;alive&lt;&#x2F;code&gt; booleans into one byte, and they do not really make sense to me as their own type, and keep the nice ergonomics of using them. The advised&#x2F;Ginger Bill-authorized way to write this is the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group_Status&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span&gt; u8 {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Extendable,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Alive,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Rethought_Group&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;  [CELL_COUNT]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hex_State&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    status&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; bit_set&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group_Status&lt;&#x2F;span&gt;&lt;span&gt;; u8],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; .Extendable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; grp.status {&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; etc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But I have already been using &lt;code&gt;Group&lt;&#x2F;code&gt; throughout, and I really like just writing this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; grp.extendable {&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; etc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; AND&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grp.extendable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But what is programming if not suppressing compiler warnings and ignoring the advice of more experienced practitioners? &lt;em&gt;Especially&lt;&#x2F;em&gt; the author of the language you are writing in?&lt;&#x2F;p&gt;
&lt;p&gt;Back to business. The first thing needed is to reimplement the &lt;code&gt;slotmap&lt;&#x2F;code&gt; API for the new &lt;code&gt;Group_Store&lt;&#x2F;code&gt;. Here is the original:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    slotmap_init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;         ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Slot_Map&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ---&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    slotmap_destroy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;      ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Slot_Map&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ---&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    slotmap_insert&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;       ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Slot_Map&lt;&#x2F;span&gt;&lt;span&gt;, item&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sm_Item&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sm_Key&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ---&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    slotmap_contains_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Slot_Map&lt;&#x2F;span&gt;&lt;span&gt;, key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sm_Key&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;   -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; c.bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ---&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    slotmap_get&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;          ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Slot_Map&lt;&#x2F;span&gt;&lt;span&gt;, key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sm_Key&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;   -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sm_Item&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ---&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    slotmap_remove&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;       ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(sm&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Slot_Map&lt;&#x2F;span&gt;&lt;span&gt;, key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sm_Key&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;   -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Sm_Item&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; ---&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;init&lt;&#x2F;code&gt; and &lt;code&gt;destroy&lt;&#x2F;code&gt; are perhaps not needed, as they exist to manage heap memory. &lt;code&gt;contains_key&lt;&#x2F;code&gt; could be replaced by &lt;code&gt;get&lt;&#x2F;code&gt; (and &lt;code&gt;remove&lt;&#x2F;code&gt;) returning a success or failure value, as is idiomatic in Odin. To ascertain that &lt;code&gt;Group_Store&lt;&#x2F;code&gt; can only return keys of the appropriate Player, some type system hackery would have been of use, but alas I could not make it work. So I replaced it instead with cursed &lt;code&gt;using&lt;&#x2F;code&gt; hackery. (&lt;code&gt;Rethought_Group&lt;&#x2F;code&gt; is just &lt;code&gt;Group&lt;&#x2F;code&gt; here.)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group_Store&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;        [HAND_SIZE]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;    using&lt;&#x2F;span&gt;&lt;span&gt; _meta&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; bit_field&lt;&#x2F;span&gt;&lt;span&gt; u8 {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cursor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; u8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;     |&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        player&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Player&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;store_insert&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(store&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group_Store&lt;&#x2F;span&gt;&lt;span&gt;, group&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group_Handle&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    assert(group.alive,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;trying to insert a dead group!&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    store.data[store.cursor]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; group&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; store.cursor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; Group_Handle{idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; store.cursor, owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; store.player, valid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;store_get&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(store&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group_Store&lt;&#x2F;span&gt;&lt;span&gt;, key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group_Handle&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group&lt;&#x2F;span&gt;&lt;span&gt;, ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; bool) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (key.valid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     store.player&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; key.owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     key.idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; store.cursor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     store.data[key.idx].alive)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;store.data[key.idx],&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;store_remove&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(store&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group_Store&lt;&#x2F;span&gt;&lt;span&gt;, key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group_Handle&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group&lt;&#x2F;span&gt;&lt;span&gt;, ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; bool) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; store_get(store, player, key)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; grp.alive&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This covers it, maybe? Time to delete &lt;code&gt;slotmap.odin&lt;&#x2F;code&gt; and get going with some Compiler-Driven Development. I will not reprint all the changed code here, as it would be boring and a slog. Suffice it to say I did an admirable job at it and all the calls to &lt;code&gt;slotmap&lt;&#x2F;code&gt; were handled excellently and appropriately.&lt;&#x2F;p&gt;
&lt;p&gt;Now time to check if that effort fixes that first bug. Here is the test code again (slightly edited):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;main&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    game&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; game_init()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; game_destroy(game)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; bool&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; game_make_move(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;game, Move{hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}, tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tile_from_id(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;63&lt;&#x2F;span&gt;&lt;span&gt;, .Guest)})&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    fmt.printfln(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;%v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, ok)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; game_make_move(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;game, Move{hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}, tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tile_from_id(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;63&lt;&#x2F;span&gt;&lt;span&gt;, .Host)})&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    fmt.printfln(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;%v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, ok)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; game.groups_map {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        fmt.printf(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;%v&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;, &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, transmute(u8)key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And voila! It gives two different keys of &lt;code&gt;128&lt;&#x2F;code&gt; and &lt;code&gt;192&lt;&#x2F;code&gt; (though I can&#x27;t quite tell which is which) I caught a subtle bug while I was going through the code, which gave the need for a &lt;code&gt;valid&lt;&#x2F;code&gt; field in the key, so that it guarantees no valid key is &lt;code&gt;0&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Testing with different pairs of first moves has gone swimmingly. Things get captured when they should and get rejected when they should. But testing a whole game is more difficult to verify looking at &lt;code&gt;stdout&lt;&#x2F;code&gt; printed arrays of numbers. A different visualization is required.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;visualizing-the-board&quot;&gt;Visualizing the Board&lt;&#x2F;h2&gt;
&lt;p&gt;A hexagonal board does not quite lend itself to being nicely printed in the terminal. Even if the pieces were simple stones (or chess pieces, available nicely as Unicode code points), However, solutions as old as time, or at least as old as monospaced fonts, exist.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# pointy representation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# &amp;quot;Simply&amp;quot; shift the squares each row half a &amp;quot;square&amp;quot;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# this is the coordinate system used in the code.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -3  |   |   |   |   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    -2  |   |   |   |   |   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -1  |   |   |   |   |   |   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; 0  |   |   |   |   |   |   |   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   1  |   |   |   |   |   |   | 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     2  |   |   |   |   |   | 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       3  |   |   |   |   | 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            -3  -2  -1  0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# or _pointier_, without coordinates.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F; \ &#x2F; \ &#x2F; \ &#x2F; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;           |   |   |   |   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          &#x2F; \ &#x2F; \ &#x2F; \ &#x2F; \ &#x2F; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         |   |   |   |   |   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F; \ &#x2F; \ &#x2F; \ &#x2F; \ &#x2F; \ &#x2F; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       |   |   |   |   |   |   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &#x2F; \ &#x2F; \ &#x2F; \ &#x2F; \ &#x2F; \ &#x2F; \ &#x2F; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     |   |   |   |   |   |   |   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      \ &#x2F; \ &#x2F; \ &#x2F; \ &#x2F; \ &#x2F; \ &#x2F; \ &#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       |   |   |   |   |   |   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        \ &#x2F; \ &#x2F; \ &#x2F; \ &#x2F; \ &#x2F; \ &#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         |   |   |   |   |   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          \ &#x2F; \ &#x2F; \ &#x2F; \ &#x2F; \ &#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;           |   |   |   |   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            \ &#x2F; \ &#x2F; \ &#x2F; \ &#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# flat representation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# letter&#x2F;number coordinates system&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                __&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;             __&#x2F;  \__&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          __&#x2F;  \__&#x2F;  \__&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       __&#x2F;  \__&#x2F;  \__&#x2F;  \__&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &#x2F;  \__&#x2F;  \__&#x2F;  \__&#x2F;  \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     g\__&#x2F;  \__&#x2F;  \__&#x2F;  \__&#x2F;7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &#x2F;  \__&#x2F;  \__&#x2F;  \__&#x2F;  \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     f\__&#x2F;  \__&#x2F;  \__&#x2F;  \__&#x2F;6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &#x2F;  \__&#x2F;  \__&#x2F;  \__&#x2F;  \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     e\__&#x2F;  \__&#x2F;  \__&#x2F;  \__&#x2F;5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &#x2F;  \__&#x2F;  \__&#x2F;  \__&#x2F;  \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     d\__&#x2F;  \__&#x2F;  \__&#x2F;  \__&#x2F;4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        c\__&#x2F;  \__&#x2F;  \__&#x2F;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;           b\__&#x2F;  \__&#x2F;2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              a\__&#x2F;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;asibahi&#x2F;w9l&quot;&gt;my implementation of Havannah&lt;&#x2F;a&gt;, I went with the Flat ASCII representation. However, since the directions are defined as &lt;code&gt;TOP_RIGHT&lt;&#x2F;code&gt;, &lt;code&gt;RIGHT&lt;&#x2F;code&gt;, etc, the Pointy representation is more appropriate. The compact version above is also, well, compact. Perfect for quick visualizations and debugging, especially that the board size in Dominions is much larger.&lt;&#x2F;p&gt;
&lt;p&gt;Rendering the board is the easy part. But pieces in Dominions are distinct from each other, and it is not feasible to just &lt;em&gt;draw&lt;&#x2F;em&gt; the Tile&#x27;s shape in the terminal. Firstly, that would be a very complex endeavour, and secondly it would balloon the drawing&#x27;s size. But each tile can be represented, &lt;em&gt;is&lt;&#x2F;em&gt; represented, by a unique number from 1 to 63, plus a flag for the Owner. Using octal numbers, this can be made much nicer.&lt;&#x2F;p&gt;
&lt;p&gt;Octal numbers today are mostly useless. Every language supports them because, well, they cost nothing to add, and they have one niche use in Unix file permissions. The &lt;em&gt;reason&lt;&#x2F;em&gt; they are useful for Unix file permissions is that these come in sets of three flags. So each set can be represented neatly by one octal digit (which stands for three bits).&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-10-1&quot;&gt;&lt;a href=&quot;#fn-10&quot;&gt;10&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It just so happens that the Tiles in this game are also divided in two sets of three bits: three bits for the Right-side connections, and three to the Left-side connections, and two bits for Owner and Controller, &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-garden-of-odin&#x2F;#tiles&quot;&gt;detailed earlier&lt;&#x2F;a&gt;. This makes it so the &lt;em&gt;right&lt;&#x2F;em&gt; digit represents the &lt;em&gt;right-side&lt;&#x2F;em&gt; connections, and the middle digit, to the &lt;em&gt;left&lt;&#x2F;em&gt; represents the &lt;em&gt;left&lt;&#x2F;em&gt; side connections. The rightmost digit is either &lt;code&gt;0&lt;&#x2F;code&gt; or &lt;code&gt;1&lt;&#x2F;code&gt; donating the Owner, and using ANSI magic, the tile is colored by the Controller&#x27;s color. Neat, hah?&lt;&#x2F;p&gt;
&lt;p&gt;While this is unusable for an actual playable application meant for humans (a Graphical interface is more suited), it is very useful for debugging the game&#x27;s status at any given point. With some trial and error, this is the printing code, the result of which I do not know to show on the web without a screenshot.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;core:encoding&#x2F;ansi&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;core:fmt&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;board_print&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(board&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Board&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;    w_on_b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span&gt; ansi.CSI&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; ansi.FG_WHITE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; ansi.BG_BLACK&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; ansi.SGR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;    b_on_w&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span&gt; ansi.CSI&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; ansi.FG_BLACK&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; ansi.BG_WHITE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; ansi.SGR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;    end&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span&gt; ansi.CSI&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; ansi.RESET&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; ansi.SGR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; min(i8)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; tile, idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; board {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; hex_from_index(idx)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; hex.y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; row {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; hex.y&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; != -&lt;&#x2F;span&gt;&lt;span&gt;N&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; fmt.println(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;|&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; abs(row) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                fmt.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;  &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; tile_is_empty(tile) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            fmt.print(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;|   &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else if&lt;&#x2F;span&gt;&lt;span&gt; .Controller_Is_Host&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; tile {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            fmt.printf(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;quot;|&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; w_on_b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;%3o&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; end,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp; ~&lt;&#x2F;span&gt;&lt;span&gt;{.Controller_Is_Host}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            fmt.printf(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;|&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; b_on_w&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;%3o&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; end, tile)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    fmt.println(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;|&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-garden-of-odin&#x2F;printedboard.png&quot; alt=&quot;Printed board&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Perfect. Every other pair of opening moves I tried works as expected. So now is the time for the &lt;strong&gt;Ultimate Test&lt;&#x2F;strong&gt;: transcribe the full example game!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-example-game&quot;&gt;The Example Game&lt;&#x2F;h2&gt;
&lt;p&gt;The full list of moves for the example game is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mindsports.nl&#x2F;index.php&#x2F;the-pit&#x2F;526-dominions&quot;&gt;here, in the source code of the game&#x27;s page&lt;&#x2F;a&gt;. Parsing the moves is a fun exercise, even if I will not use the same notation eventually, so I will do that.&lt;&#x2F;p&gt;
&lt;p&gt;The first task is to know how the coordinates map from the Mindsports representation to mine. This one is straightforward, if a bit tricky. The letters are the rows, or the &lt;code&gt;hex.y&lt;&#x2F;code&gt; coordinate, so &lt;code&gt;A to Q&lt;&#x2F;code&gt; map to &lt;code&gt;8 to -8&lt;&#x2F;code&gt; (yes, backwards.) The columns map &lt;code&gt;1 to 17&lt;&#x2F;code&gt; to &lt;code&gt;-8 to 8&lt;&#x2F;code&gt;. The center hex goes from &lt;code&gt;i9&lt;&#x2F;code&gt; to &lt;code&gt;{0, 0}&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The Tile numbers do not map as neatly. &lt;code&gt;P63&lt;&#x2F;code&gt; is the same, but not the others. It is important to know how the directions map between both representations. Amusingly, I found out that the &lt;code&gt;P1&lt;&#x2F;code&gt; tile is &lt;em&gt;also&lt;&#x2F;em&gt; the same, but the Mindsports representation advances counter-clockwise, while mine does it clockwise. So &lt;code&gt;Top_Left&lt;&#x2F;code&gt;, above being &lt;code&gt;32&lt;&#x2F;code&gt;, is here marked as &lt;code&gt;2&lt;&#x2F;code&gt;, and so on. That gives us this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tile_mindsports_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; u8, player&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Player&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; {.Top_Right}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; {.Top_Left}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; {.Left}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; {.Btm_Left}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; {.Btm_Right}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;span&gt; ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; {.Right}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; player {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt; .Host: ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; HOST_FLAGS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt; .Guest:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And to parse each move:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;core:strconv&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;move_mindsports_parse&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(str&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; string)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Move&lt;&#x2F;span&gt;&lt;span&gt;, ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; bool) #optional_ok {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; move format: B[P12p15]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    player&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Player&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span&gt; str[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;W&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;: player&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .Guest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;B&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;: player&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; .Host&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; {},&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Tile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do return&lt;&#x2F;span&gt;&lt;span&gt; {},&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; id, ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; strconv.parse_uint(str[c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;len]); ok {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; len&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tile_mindsports_id(u8(id), player)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; N&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; i8(str[c]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;a&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    col&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; i8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do return&lt;&#x2F;span&gt;&lt;span&gt; {},&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; res, ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; strconv.parse_uint(str[c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;len]); ok {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            col&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; i8(res)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; N&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; {tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tile, hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {col, row}},&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ok, now it is time to play through the game, where &lt;code&gt;MOVE_LIST&lt;&#x2F;code&gt; is a defined constant:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;main&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    game&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; game_init()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; game_destroy(game)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    moves&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; strings.split(MOVE_LIST,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; m, idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; moves {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        move&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Move&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; bool&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        move, ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; move_mindsports_parse(m)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;ok {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            fmt.println(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;MOVE PARSER BROKE&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        fmt.println(idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;, m)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; game_make_move(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;game, move)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;ok {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            fmt.println(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;COULD NOT MAKE MOVE&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        board_print(game.board)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]u8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        os.read(os.stdin, buffer[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; advancing manually&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now it is possible to go through the game move by move and compare, manually, the results of this program vs the &quot;canonical&quot; game client.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;second-bug&quot;&gt;Second Bug&lt;&#x2F;h2&gt;
&lt;p&gt;Running the engine hit an assertion at move 44. All the moves prior to that, including Suicides (amusingly enough), worked fine, but move 44 has the first Capture in the game. The move right after this position, where the first player captures at &lt;code&gt;g2&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-garden-of-odin&#x2F;.&#x2F;bug2board.png&quot; alt=&quot;Dominions Position Board&quot; &#x2F;&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-garden-of-odin&#x2F;.&#x2F;bug2ascii.png&quot; alt=&quot;Dominions Position ASCII&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;(They are the same. You can even see the first player&#x27;s suicides as black numbers starting with &lt;code&gt;0&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;The capture logic can be found &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-garden-of-odin&#x2F;#game-update-state-inner-second-draft&quot;&gt;above&lt;&#x2F;a&gt;. The failure happens here:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == merge level 2 surrounding friendlies into blessed group&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; level_2_surrounding_friendlies {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        temp_grp, ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; store_remove(friendly_grps, key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assert(ok)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;--- right there.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; temp_grp.state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.extendable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; temp_grp.extendable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I am not sure what this was supposed to accomplish, to be honest; and commenting it out, amusingly, progresses the game and resolves that move, until move 50 when it crashes. Unfortunately between both moves the state is &lt;em&gt;all wrong&lt;&#x2F;em&gt;. Either way, the assert that fails is slightly ahead of that loop.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; == go over surrounding enemy groups to see if they&amp;#39;re dead.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    capture_occurance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; surrounding_enemy_grps {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        temp_grp, ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; store_get(enemy_grps, key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assert(ok,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Enemy slotmap does not have enemy Key&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;--- right here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        temp_grp.state[hex_to_index(move.hex)]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; .Enemy_Connection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; --- snip&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This part seems too important to comment out, not to mention the all wrong state. Obviously, however, there is a problem in assigning and updating &lt;code&gt;Group&lt;&#x2F;code&gt; keys. Probably some keys are persistent in &lt;code&gt;group_map&lt;&#x2F;code&gt;, and are not getting updated as new &lt;code&gt;Group&lt;&#x2F;code&gt;s happen.&lt;&#x2F;p&gt;
&lt;p&gt;So obviously the next step is to update the board visualization to include both Tiles &lt;em&gt;and&lt;&#x2F;em&gt; Group IDs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;updated-board-visualization&quot;&gt;Updated Board Visualization&lt;&#x2F;h2&gt;
&lt;p&gt;To print each row twice, each time with different data, &lt;em&gt;two&lt;&#x2F;em&gt; buffers are needed instead of printing directly. The two buffers are flushed out once per row.&lt;code&gt;string&lt;&#x2F;code&gt;s in Odin are immutable, and to have a string buffer, one needs to dip one&#x27;s toes into the Odin core library, and use a &lt;code&gt;strings.Builder&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;board_print&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(board&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Board&lt;&#x2F;span&gt;&lt;span&gt;, grp_map&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [CELL_COUNT]&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group_Handle&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;    w_on_b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span&gt; ansi.CSI&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; ansi.BG_BLACK&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; ansi.FG_WHITE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; ansi.SGR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;    b_on_w&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span&gt; ansi.CSI&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; ansi.BG_WHITE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; ansi.FG_BLACK&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; ansi.SGR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant&quot;&gt;    end&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span&gt; ansi.CSI&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; ansi.RESET&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; ansi.SGR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tiles_buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; strings.builder_make()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grps_buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; strings.builder_make()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; strings.builder_destroy(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;tiles_buffer)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; strings.builder_destroy(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;grps_buffer)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; min(i8)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; tile, idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; board {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; hex_from_index(idx)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; hex.y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; row {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; hex.y&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; != -&lt;&#x2F;span&gt;&lt;span&gt;N {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                fmt.sbprint(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;tiles_buffer,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;|&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                fmt.sbprint(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;grps_buffer,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;|&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                fmt.println(strings.to_string(tiles_buffer))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                fmt.println(strings.to_string(grps_buffer))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                strings.builder_reset(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;tiles_buffer)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                strings.builder_reset(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;grps_buffer)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            for&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ..&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; abs(row) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                fmt.sbprint(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;tiles_buffer,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;  &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                fmt.sbprint(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;grps_buffer,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;  &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; tile_is_empty(tile) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            fmt.sbprint(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;tiles_buffer,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;|   &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            fmt.sbprint(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;grps_buffer,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;|   &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else if&lt;&#x2F;span&gt;&lt;span&gt; .Controller_Is_Host&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; tile {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            fmt.sbprintf(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;tiles_buffer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;quot;|&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; w_on_b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;%3o&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; end,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                tile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp; ~&lt;&#x2F;span&gt;&lt;span&gt;{.Controller_Is_Host}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            fmt.sbprintf(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;grps_buffer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;quot;|&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; w_on_b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;%3X&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; end,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                transmute(u8)grp_map[idx]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            fmt.sbprintf(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;tiles_buffer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;quot;|&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; b_on_w&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;%3o&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; end,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                tile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            fmt.sbprintf(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;grps_buffer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;quot;|&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; b_on_w&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;%3X&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; end,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                transmute(u8)grp_map[idx]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There you go, much better.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-garden-of-odin&#x2F;.&#x2F;viz2ascii.png&quot; alt=&quot;Visualization with Group IDs&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;back-to-the-second-bug&quot;&gt;Back to the Second Bug&lt;&#x2F;h2&gt;
&lt;p&gt;Honestly, I am not enjoying debugging this. I feel it would be easier to rewrite the whole thing with the learned assumptions. But persevere I must.&lt;&#x2F;p&gt;
&lt;p&gt;Going back to move 44, where the first crash happened: All the groups that must be separate are separate, and all the ones that must be connected are connected. So, the easy assumption is that all the code paths triggered so far are correct.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-garden-of-odin&#x2F;.&#x2F;move44ascii.png&quot; alt=&quot;Move 44 in the Terminal&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The offending next move, &lt;code&gt;W[P56q10]&lt;&#x2F;code&gt; does the following, physically:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;It connects to two enemy groups, &lt;code&gt;C7&lt;&#x2F;code&gt; and &lt;code&gt;C8&lt;&#x2F;code&gt;. And to one friendly group, &lt;code&gt;88&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Groups &lt;code&gt;C7&lt;&#x2F;code&gt; and &lt;code&gt;88&lt;&#x2F;code&gt; both lose all liberties, as does the new placed Tile.&lt;&#x2F;li&gt;
&lt;li&gt;Enemy group &lt;code&gt;C7&lt;&#x2F;code&gt; is captured, as it loses all liberties and is connected, from the other side, to another friendly group &lt;code&gt;87&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The result of this is the newly placed tile, friendly groups &lt;code&gt;88&lt;&#x2F;code&gt;, &lt;code&gt;87&lt;&#x2F;code&gt;, and captured enemy group &lt;code&gt;C7&lt;&#x2F;code&gt; must now all be unified into one new group, ideally should be &lt;code&gt;88&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;So what does the code actually &lt;em&gt;do&lt;&#x2F;em&gt;? Time to use a debugger.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;setting-up-the-debugger&quot;&gt;Setting up the Debugger&lt;&#x2F;h3&gt;
&lt;p&gt;Thankfully, due to dabbling in Rust, I already had LLDB installed as a VSCode extension. All is needed for it to work is to create a &lt;code&gt;launch.json&lt;&#x2F;code&gt; file (that&#x27;s almost filled up already), and have it work on an executable built with:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; odin build .&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -debug&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Using a template from the Odin Discord server and adapting it to macOS (from Windows), I got the following two files in the &lt;code&gt;.vscode&lt;&#x2F;code&gt; directory:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; launch.json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;  &amp;quot;version&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;0.2.0&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;  &amp;quot;configurations&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;      &amp;quot;type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;lldb&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;      &amp;quot;request&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;launch&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;      &amp;quot;preLaunchTask&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Build&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;      &amp;quot;name&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Debug&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;      &amp;quot;program&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;${workspaceFolder}&#x2F;build&#x2F;debug&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;      &amp;quot;args&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;      &amp;quot;cwd&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;${workspaceFolder}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; tasks.json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;  &amp;quot;version&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;2.0.0&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;  &amp;quot;command&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;  &amp;quot;args&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;  &amp;quot;tasks&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;      &amp;quot;label&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;mkdir&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;      &amp;quot;type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;shell&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;      &amp;quot;command&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;mkdir -p build&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- Does not work on Windows.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;      &amp;quot;label&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;build&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;      &amp;quot;type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;shell&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;      &amp;quot;command&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;odin build . -debug -out:build&#x2F;debug&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;      &amp;quot;group&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;build&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;      &amp;quot;label&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;Build&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- launch task runs this&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name z-json&quot;&gt;      &amp;quot;dependsOn&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;quot;mkdir&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;  &#x2F;&#x2F; which runs this&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;quot;build&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;   &#x2F;&#x2F; then this&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now all I need to do is set breakpoints and click the VSCode button that says &lt;code&gt;Debug&lt;&#x2F;code&gt;. Yay for technology.&lt;&#x2F;p&gt;
&lt;p&gt;But how to set a conditional breakpoint based on the move number when &lt;code&gt;game_make_move&lt;&#x2F;code&gt; does not know the move number?&lt;&#x2F;p&gt;
&lt;p&gt;Normally, one would either have to set the move number as a global variable, &lt;em&gt;or&lt;&#x2F;em&gt; pass it on as an explicit parameter into every procedure, both are equally annoying. In Odin, I can just use the &lt;code&gt;context&lt;&#x2F;code&gt; system. The &lt;code&gt;Context&lt;&#x2F;code&gt; struct, which is passed implicitly by default to every Odin procedure, contains a &lt;code&gt;user_index&lt;&#x2F;code&gt; field which can be set to whatever. Inside &lt;code&gt;game_make_move&lt;&#x2F;code&gt; or any of its inner procedures, I simply check for &lt;code&gt;context.user_index&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; inside main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    context.user_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; idx&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; game_make_move(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;game, move)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; inside game_inner_update_state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; level_2_surrounding_friendlies {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; context.user_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 43&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            fmt.println(context.user_index)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- set breakpoint here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        temp_grp, ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; store_remove(friendly_grps, key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assert(ok)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                          &#x2F;&#x2F; &amp;lt;-- failing assertion&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; temp_grp.state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.extendable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; temp_grp.extendable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And that&#x27;s how it looks when reached.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;the-garden-of-odin&#x2F;.&#x2F;ss_debugger.png&quot; alt=&quot;Debugger showing breakpoint. Beware the typo.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tedious-debugging&quot;&gt;Tedious Debugging&lt;&#x2F;h3&gt;
&lt;p&gt;This part is not cohesive writing. I will be listing my findings, but it might not be the easiest thing to follow.&lt;&#x2F;p&gt;
&lt;p&gt;Going through the variables on the left of the debugger view, some things jump out. &lt;code&gt;level_2_surrounding_friendlies&lt;&#x2F;code&gt; has invalid keys. (Literally, &lt;code&gt;valid&lt;&#x2F;code&gt; is set to false.) What seems to be happening is that, earlier a bit, I am setting the just played tile as &lt;code&gt;.Enemy_Connection&lt;&#x2F;code&gt; for the neighboring enemy group. But when when the key is looked up in &lt;code&gt;game.groups_map&lt;&#x2F;code&gt;, it is still set to &lt;code&gt;0&lt;&#x2F;code&gt; as it is not added there yet.&lt;&#x2F;p&gt;
&lt;p&gt;Adding &lt;code&gt;blessed_key&lt;&#x2F;code&gt; to &lt;code&gt;group_map&lt;&#x2F;code&gt; on creation passes the &lt;code&gt;game_make_move&lt;&#x2F;code&gt; procedure fine, but trips on another assertion in &lt;code&gt;game_regen_legal_moves&lt;&#x2F;code&gt;. Apparently, the new group is not in any group store. It is getting removed somehow. Using Odin magic like adding a &lt;code&gt;loc := #caller_location&lt;&#x2F;code&gt; parameter to &lt;code&gt;store_remove&lt;&#x2F;code&gt;, I can get it to print where that remove call was made. (And yes, I could have put in a breakpoint in there too.)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;core:fmt&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;store_remove&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; ::&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; proc&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    store&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group_Store&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group_Handle&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    loc&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; #caller_location&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- Default value so call sites don&amp;#39;t change.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; (ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Group&lt;&#x2F;span&gt;&lt;span&gt;, ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; bool) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; key.idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; key.owner&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; .Guest {&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; &amp;lt;-- the offending group&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        fmt.println(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;REMOVED HERE:&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, loc)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; store_get(store, key)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; or_return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    defer&lt;&#x2F;span&gt;&lt;span&gt; grp.alive&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; grp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Running it quickly shows it is removed in that &lt;code&gt;level_2_surrounding_friendlies&lt;&#x2F;code&gt; loop. Where the first assert failed. Adding a condition to check for equality with &lt;code&gt;blessed_key&lt;&#x2F;code&gt; like the following, allows the game to hit no more asserts and continue to completion. Yay!&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; level_2_surrounding_friendlies {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; blessed_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        temp_grp, ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span&gt; store_remove(friendly_grps, key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assert(ok)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; temp_grp.state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        blessed_grp.extendable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span&gt; temp_grp.extendable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now that the example game runs to completion without hitting any assertions, time to check the state&#x27;s correctness. The final position in the game seems to be all correct, so I will consider this implementation now bug free. Maybe for part 2.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-s-left&quot;&gt;What&#x27;s left?&lt;&#x2F;h2&gt;
&lt;p&gt;Work is not done on this by any means, even if I ascertained it is 100% bug free. (the legal move generator is not thoroughly tested really.) But I have spent a month, on and off, on this and my wife is frankly sick of me. So here is a list of what is left to implement in round 2:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Undoing Moves: Necessary for engine implementations, and easy in theory. All is needed really is to copy the game&#x27;s state into a dynamic array of previous game states. To save memory, only saving previous &lt;code&gt;Board&lt;&#x2F;code&gt;s is required, as they actually have enough data to generate all the remaining fields.&lt;&#x2F;li&gt;
&lt;li&gt;An interactive interface. A way to interact with the game outside of writing procedure calls in &lt;code&gt;main()&lt;&#x2F;code&gt; Either through a wasm module or a CLI interface, or a common interface either one can use.&lt;&#x2F;li&gt;
&lt;li&gt;Nicer, graphic visualization. The ASCII visualization is useful for debugging, but it is not actually playable. This game needs beautiful art and a beautiful Graphical User Interface.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;&#x2F;h2&gt;
&lt;p&gt;So throughout working on this article (for almost a whole month) I advanced my knowledge about the following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The Odin programming language,&lt;&#x2F;li&gt;
&lt;li&gt;Interop between Odin and Rust (and any other language really),&lt;&#x2F;li&gt;
&lt;li&gt;HTML and CSS and Zola templating (in setting up this website),&lt;&#x2F;li&gt;
&lt;li&gt;Basic usage of LLDB debugging,&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;So,  this was a fun ride. But it is time to move on to something else.&lt;&#x2F;p&gt;
&lt;p&gt;The code here is in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;asibahi&#x2F;bustan&quot;&gt;&lt;code&gt;bustan&lt;&#x2F;code&gt; repository&lt;&#x2F;a&gt;. You can see the evolution of the code, and much of what is in this article, through the git history.&lt;&#x2F;p&gt;
&lt;p&gt;Until later.&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;As mentioned earlier, the Blank tile is not used in the game. This permits using a sentinel value of &lt;code&gt;0&lt;&#x2F;code&gt; (or really any value with the smallest six bits set to &lt;code&gt;0&lt;&#x2F;code&gt;) to mark an empty cell. Since Tiles are a &lt;code&gt;u8&lt;&#x2F;code&gt; bit-set anyway, why waste memory on pointers (which are wider), or &lt;code&gt;Maybe&lt;&#x2F;code&gt;, which is at least an extra byte in size? I am not thinking &lt;em&gt;too&lt;&#x2F;em&gt; hard about performance (I know nobody will use this), but it is an interesting constraint to keep in mind. &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;I should be careful not to index into &lt;code&gt;Board&lt;&#x2F;code&gt; directly, however. &lt;a href=&quot;#fr-2-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;I love that &lt;code&gt;move&lt;&#x2F;code&gt; is not a keyword here, which is really annoying in Rust. &lt;a href=&quot;#fr-3-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-4&quot;&gt;
&lt;p&gt;Generational arena, generational handles, handle-based map, a rose by any other name. &lt;a href=&quot;#fr-4-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-5&quot;&gt;
&lt;p&gt;It is &lt;em&gt;Oscillation&lt;&#x2F;em&gt; because the resulting Group has no Liberties, and therefore has no clear Controller, so it &lt;em&gt;oscillates&lt;&#x2F;em&gt; between both colors. This is way the Blank tile has no role in the game: it automatically oscillates. &lt;a href=&quot;#fr-5-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-6&quot;&gt;
&lt;p&gt;Technically, only a record of whether the last move &lt;em&gt;was&lt;&#x2F;em&gt; a pass is needed, but &lt;code&gt;last_move&lt;&#x2F;code&gt; is semantically clearer than a &lt;code&gt;last_move_was_a_pass&lt;&#x2F;code&gt; (or &lt;code&gt;pass_ends_the_game&lt;&#x2F;code&gt; or &lt;code&gt;the_end_is_nigh&lt;&#x2F;code&gt;) boolean or a &lt;code&gt;player_who_last_made_a_move&lt;&#x2F;code&gt; enum field. It may also be useful to highlight the last move in a GUI. &lt;a href=&quot;#fr-6-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-7&quot;&gt;
&lt;p&gt;Rust would &lt;em&gt;totally&lt;&#x2F;em&gt; yell at me. Then tell me to implement the trait to define the behavior myself. &lt;a href=&quot;#fr-7-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-8&quot;&gt;
&lt;p&gt;Freeling does not specify in which order captures are processed. I am assuming here the order is the same as Go. Anyway, all this needs to be verified later once (if?) the engine is implemented. &lt;a href=&quot;#fr-8-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-9&quot;&gt;
&lt;p&gt;I have been thinking of why Groups need to own their own data anyway? Group membership is clearly delineated in &lt;code&gt;Game.group_map&lt;&#x2F;code&gt; as it currently is (which would become &lt;code&gt;[CELL_COUNT]Group_Handle&lt;&#x2F;code&gt; under the new regime.) Liberties and Enemy Connections can be calculated and collected with a combination of &lt;code&gt;game.groups_map&lt;&#x2F;code&gt; and, well, &lt;code&gt;game.board&lt;&#x2F;code&gt;. But that&#x27;s another day&#x27;s battle. &lt;a href=&quot;#fr-9-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-10&quot;&gt;
&lt;p&gt;A fuller explanation of file permissions, as irrelevant as they are to this article, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.nersc.gov&#x2F;filesystems&#x2F;unix-file-permissions&#x2F;&quot;&gt;can be found here&lt;&#x2F;a&gt;. &lt;a href=&quot;#fr-10-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Thoughts on Arabic Justification</title>
        <published>2023-04-12T00:00:00+00:00</published>
        <updated>2023-04-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/thoughts/practical-arabic-justification/"/>
        <id>https://ar-ms.me/thoughts/practical-arabic-justification/</id>
        
        <content type="html" xml:base="https://ar-ms.me/thoughts/practical-arabic-justification/">&lt;p&gt;For the tl;dr, skip to &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;practical-arabic-justification&#x2F;#priority-list&quot;&gt;Priority&lt;&#x2F;a&gt;. This article is a follow up to &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;linebreaking&#x2F;&quot;&gt;this one&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;background-reading&quot;&gt;Background Reading&lt;&#x2F;h2&gt;
&lt;p&gt;Here are some links that you might want to look at:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=Ai4dgLpFMx8&quot;&gt;Deficiencies of Handling Arabic Script in OpenType. Aida Sakkal and Mamoun Sakkal. Tech Talks 2021&lt;&#x2F;a&gt;. Mamoun Sakkal is a rather well known Arabic type designer. The video goes over the practical problems of justification in detail.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;research.reading.ac.uk&#x2F;typoarabic&#x2F;on-arabic-justification-part-2-software-implementations&#x2F;&quot;&gt;On Arabic justitifcation part 2 by Titus Nemeth&lt;&#x2F;a&gt;. (Look at parts 1 and 3 as well).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;digitalkhatt.org&#x2F;about&quot;&gt;About Digital Khatt.&lt;&#x2F;a&gt; Real world (as it gets) examples of some of the ideas of Arabic justification. This is a public github project you can find &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;DigitalKhatt&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;typedrawers.com&#x2F;discussion&#x2F;3465&#x2F;making-jstf-better&quot;&gt;Making JSTF better by Simon Cozens on TypeDrawers&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;harfbuzz&#x2F;harfbuzz&#x2F;discussions&#x2F;3252&quot;&gt;Discussion at HarfBuzz Github - Support for jalt feature and target length&lt;&#x2F;a&gt; I will save you a click: &quot;HarfBuzz currently does not implement justification, because it&#x27;s a hard problem, and is under-specified in OpenType.&quot; Here is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;harfbuzz&#x2F;harfbuzz&#x2F;pull&#x2F;3259&quot;&gt;follow up discussion: API for buffer target length&lt;&#x2F;a&gt; Useful context by all parties.&lt;&#x2F;li&gt;
&lt;li&gt;More general and high level: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.w3.org&#x2F;International&#x2F;articles&#x2F;typography&#x2F;linebreak.en&quot;&gt;Approaches to Line Breaking, W3C&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.w3.org&#x2F;International&#x2F;articles&#x2F;typography&#x2F;justification&quot;&gt;Approaches to full justification&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;intro&quot;&gt;Intro&lt;&#x2F;h2&gt;
&lt;p&gt;Justification is a nasty and difficult problem. When justifying over sufficiently long lines, the &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;linebreaking&#x2F;&quot;&gt;Knuth-Plass algorithm&lt;&#x2F;a&gt; is more than enough. However, when the lines are narrow, for example in a newspaper column, there just are not enough words in a line to make small changes to the space between them unnoticeable, and you need to take more drastic measures.&lt;&#x2F;p&gt;
&lt;p&gt;For English, and Latin (and Cyrillic?) script-based languages in general, the usual solution is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hyphen#Justification_and_line-wrapping&quot;&gt;hyphenation&lt;&#x2F;a&gt;. This does not apply to every script. For example, the Japanese script have their own &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.w3.org&#x2F;TR&#x2F;jlreq&#x2F;?lang=en&quot;&gt;justification algorithm&lt;&#x2F;a&gt; that does not &quot;just&quot; add spaces between characters. Other scripts have their own rules going on.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;arabic-hyphenation&quot;&gt;Arabic Hyphenation?&lt;&#x2F;h2&gt;
&lt;p&gt;In Arabic, they &lt;em&gt;used to&lt;&#x2F;em&gt; hyphenate words around 1400 years ago. They, sadly, no longer do that, as it would make things so much simpler. In the following image, you can see the letter ا at the end (left) of the first line, and the word fragment لله at the start (right) of the second. And again at the end of the second and start of third. (Consecutive hyphenated lines - oh no). The break is not across syllabic boundaries, as an English speaker would expect, but between connected clusters.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;practical-arabic-justification&#x2F;IMG_1070.jpg&quot; alt=&quot;A page from the Quran&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If you know anything about the Arabic script, you know two things: 1. It is written from right to left, and 2. in words, the letters are connected, but not all of them! (Letters are almost never connected &lt;em&gt;across&lt;&#x2F;em&gt; words.) So for example in the word ديمقراطية, meaning Democracy, well it is one word, but there are four &quot;clusters&quot;. Like I said, we do not &quot;hyphenate&quot; (I am using the term loosely here as there are no actual hyphens) between those any more, but it is an important concept to keep in mind.&lt;&#x2F;p&gt;
&lt;p&gt;Which brings us back to the original problem statemnt: if the line width is so small that merely adjusting the spaces between words would be unseemly, what do you do? I am going to abuse my version of Microsoft Word a bit for this post. Here is an image of line of poetry justified using space stretching only. (Considering it is poetry, breaking words across lines is not even an option).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;practical-arabic-justification&#x2F;just-calibri-spaces.png&quot; alt=&quot;Space Justification&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The lines are by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Ahmed_Shawqi&quot;&gt;Ahmed Shawqi&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;par dir = &quot;rtl&quot;&gt;
&lt;p&gt;صوني جمالك عنا إننا بشر&lt;br &#x2F;&gt;
خلق التراب وهذا الحسن روحاني&lt;br &#x2F;&gt;
أو فابتغي فلكا تأوينه ملكا&lt;br &#x2F;&gt;
لم يتخذ شركا في العالم الفاني.&lt;&#x2F;p&gt;
&lt;&#x2F;par&gt;
&lt;p&gt;I have a few unhinged ideas. But let&#x27;s talk about the usual approach first.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;kashidas&quot;&gt;Kashidas&lt;&#x2F;h2&gt;
&lt;p&gt;If you have watched Mamoun Sakkal&#x27;s video. linked above, on the technical limitations of OpenType when it comes to Arabic script, you would have noticed he spends a lot of the video talking about &quot;Tatweel&quot;, or what is sometimes called by its Persian name, Kashida.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.compart.com&#x2F;en&#x2F;unicode&#x2F;U+0640&quot;&gt;Kashida is a character on all Arabic keyboards&lt;&#x2F;a&gt;. It does not have a meaning, by itself or by others, and it is merely decorartive. It is a typographinc (typesetting?) trick, that takes advantage of Arabic&#x27;s connected nature. For an Arabic reader (and this applies to literally every language that uses the Arabic script), there is literally no difference between جمل and جـــــــمـــــــــل. The second one simply looks longer. You can probably see where this is going.&lt;&#x2F;p&gt;
&lt;p&gt;The kashidas method basically inserts these characters betwen the individual letters of clusters.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;practical-arabic-justification&#x2F;just-calibri-kashida.png&quot; alt=&quot;Kashida Justification&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The main problem with this is that it is &lt;em&gt;dumb&lt;&#x2F;em&gt;. So dumb it is useless. You can see how it adds some kashidas after بشر on the first line. (Reminder: &quot;after&quot; means on the left.) This can be fixed, and this is probably a MS Word problem, but the other problem is a bit more subtle, and it is not clear with Calibri (as it was probably designed with this behavior in mind). Let us try with a different font by the same designer, Sakkal Majalla.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;practical-arabic-justification&#x2F;just-majalla-kashida.png&quot; alt=&quot;Kashida Justification&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You can see it in the second line, in the words التراب and الحسن, and in the third line in فابتغي, a bit more subtly. The font uses (and abuses) an OpenType feature called Contextual Alternates, which basically means some letters look different when followed by specific letters, and it is all over the place in every half-decent Arabic font online.&lt;&#x2F;p&gt;
&lt;p&gt;The software, for whatever reason, &lt;em&gt;does not&lt;&#x2F;em&gt; call the shaper (HarfBuzz and the like) again after inserting the kashidas, and in fonts that use cursive shaping and do not sit on the baseline, you end up with this: (Noto Nastaliq Urdu)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;practical-arabic-justification&#x2F;just-noto-kashida.png&quot; alt=&quot;Kashida &amp;quot;Justification&amp;quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is not a display typeface being misused by the way. It is meant for texts. If you want to see more dramatic failures, try the fonts &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gulzarfont.org&quot;&gt;Gulzar&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;fonts.google.com&#x2F;specimen&#x2F;Aref+Ruqaa?query=aref&quot;&gt;Aref Ruqaa&lt;&#x2F;a&gt; and set Word&#x27;s justification setting to &quot;Justify Low&quot;. This is &lt;strong&gt;not&lt;&#x2F;strong&gt; a failure of the fonts. This is a failure of the justification engine.&lt;&#x2F;p&gt;
&lt;p&gt;The way type designers protect their fonts from this fate is by making the Kashida unicode character be 0-width (aka does nothing). The font &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;fonts.ilovetypography.com&#x2F;fonts&#x2F;sakkal-design&#x2F;sakkal-kitab&quot;&gt;Sakkal Kitab&lt;&#x2F;a&gt; (which costs $120 I do not have), does not even permit you to put Kashidas manually between any two letters. Only in specific places, and only manually (or by use of stylistic sets). You can try it yourself on the webpage by copying parts of the poem above and inserting the kashida in random places.&lt;&#x2F;p&gt;
&lt;p&gt;Note that I am not saying that inserting Kashidas should never ever happen. I am saying it should never happen naively, and the engine must reshape the text after inserting Kashidas, or it will fail in spectacular ways seen above.&lt;&#x2F;p&gt;
&lt;p&gt;If you still want to insert Kashidas, the algorithm is simple enough: inser the kashidas before the letters with the &lt;code&gt;fina&lt;&#x2F;code&gt; shape, or before the &lt;code&gt;medi&lt;&#x2F;code&gt; shape. Complications would perhaps arise from trying to find out which glyphs, or HarfBuzz clusters, are final or medial (and a simple look up dictionary would not do if you want to support more than the Araic language. There are other scripts that connect too, btw: Ad&#x27;lam, N&#x27;ku, Syriac to name a couple).&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;d3qx8f8l5aa3yc.cloudfront.net&#x2F;images&#x2F;sakkal_kitab_features.pdf&quot;&gt;Sakkal Kitab PDF Specimen&lt;&#x2F;a&gt; is a very nice brief read regarding justification.&lt;&#x2F;p&gt;
&lt;p&gt;Speaking of which:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;opentype-features&quot;&gt;OpenType Features&lt;&#x2F;h2&gt;
&lt;p&gt;OpenType has a feature &lt;em&gt;specifically&lt;&#x2F;em&gt; for justification. It is not very well supported, and in fact in mainstream software only InDesign makes use of it. It is called Justification Alternates, or &lt;code&gt;jalt&lt;&#x2F;code&gt; for short.&lt;code&gt;jalt&lt;&#x2F;code&gt;s, in theory, can make the word longer &lt;em&gt;or&lt;&#x2F;em&gt; shorter, tho I have not come across examples that make them shorter. I do not have InDesign, but Sakkal Majalla helpfully has a stylistic set that does what &lt;code&gt;jalt&lt;&#x2F;code&gt; does. This how the font looks normally:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;practical-arabic-justification&#x2F;just-majalla-spaces.png&quot; alt=&quot;Space Justification&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is how it looks with Stylistic Set 3 (or for this exercise, &lt;code&gt;jalt&lt;&#x2F;code&gt;s):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;practical-arabic-justification&#x2F;just-majalla-jalt.png&quot; alt=&quot;jalt Justification&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You might reasonably point out that this does not solve the problem, and the text still has a lot of ugly spaces between the words. You would be forgetting an important fact here: I am intentionally abusing the software by forcing fully justified short lines. Poetry is a legit use case for justification, but it is an extreme case nonetheless. You can see a more real world example in Sakkal Kitab&#x27;s Specimen, linked above. Here is a handy screenshot for you:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;practical-arabic-justification&#x2F;sakkal-kitab-specimen.png&quot; alt=&quot;jalt Justification&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The real issue with &lt;code&gt;jalt&lt;&#x2F;code&gt; and font-driven justification, if you would call it that, is that apparently it is very underspecified, and the support, if it exists at all, is inconsistent.&lt;&#x2F;p&gt;
&lt;p&gt;You can see in the previous screenshot how in the paragraph with &lt;code&gt;jalt&lt;&#x2F;code&gt;, InDesign turns it on for &lt;em&gt;every word&lt;&#x2F;em&gt;, and not only when needed. This, honestly, defeats the purpose. The text looks way too loose. The manual justification sample, on the right, is more measured when using the justification alternates. (Although because InDesign does not actually let you access &lt;code&gt;jalt&lt;&#x2F;code&gt; directly, it uses stylistic sets instead.) The following page is perhaps more illustrative (the middle and right columns are identical by the way):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;practical-arabic-justification&#x2F;sakkal-kitab-specimen2.png&quot; alt=&quot;jalt Justification&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You can see here that the justification alternate, while not used &lt;em&gt;sparingly&lt;&#x2F;em&gt;, they are only used when the spaces would otherwise be too loose. You might also notice that the typesetter (who I can only assume is Sakkal himself) never applied it for two consecutive words, and never more than two times in a line. The choice of &lt;em&gt;which&lt;&#x2F;em&gt; words to stretch is probably arbitrary, based on personal taste.&lt;&#x2F;p&gt;
&lt;p&gt;I believe this process can reasonably be automated.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;using-jalts-in-a-practical-manner&quot;&gt;Using &lt;code&gt;jalt&lt;&#x2F;code&gt;s in a practical manner&lt;&#x2F;h3&gt;
&lt;p&gt;First of all you need whether the font has &lt;code&gt;jalt&lt;&#x2F;code&gt;s or not. You could even ask the user if they would like to use any other font features for justification purposes, and if they&#x27;d have a priority.&lt;&#x2F;p&gt;
&lt;p&gt;For example, if the user specifies using &lt;code&gt;ss16&lt;&#x2F;code&gt;, &lt;code&gt;ss17&lt;&#x2F;code&gt;, &lt;code&gt;ss18&lt;&#x2F;code&gt;, &lt;code&gt;ss19&lt;&#x2F;code&gt;, and &lt;code&gt;ss20&lt;&#x2F;code&gt; for justification, in this order, use those. If they don&#x27;t, use &lt;code&gt;jalt&lt;&#x2F;code&gt; if available.&lt;&#x2F;p&gt;
&lt;p&gt;Pseuorustcode time! I will be adjusting on the &lt;code&gt;build_line()&lt;&#x2F;code&gt; function from the &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;linebreaking&#x2F;&quot;&gt;linebreaking&lt;&#x2F;a&gt; article.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; build_line(input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ShapedText&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              start_bp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              end_bp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              desired_width&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: f64&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Line&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; same as before&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; b_and_g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;slice_betweeen(start_bp, end_bp);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; sum_boxes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b_and_g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;filter(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;| !&lt;&#x2F;span&gt;&lt;span&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;is_whitespace())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                           .&lt;&#x2F;span&gt;&lt;span&gt;map(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;horizontal_advance())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                           .&lt;&#x2F;span&gt;&lt;span&gt;sum();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; count_glue&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b_and_g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;filter(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;is_whitespace())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                            .&lt;&#x2F;span&gt;&lt;span&gt;count();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; pft_space&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ideal_space_width();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; min_space&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;min_space_width();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; max_space&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max_space_width();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; The math for errors being saved here for later&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; stretched_base&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sum_boxes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; (count_glue&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; max_space);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; cmprsd_bse&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sum_boxes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; (count_glue&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; min_space);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; this didn&amp;#39;t change either, assuming all jalts increase width&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; cmprsd_bse&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; desired_width {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;LineTooTight&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; new stuff !!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; first we need to split the input into words. Each &amp;quot;word&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; is a tuple of the breakpoints before and after. This is&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; probably too naive but let&amp;#39;s go with it.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; word_list&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (start_bp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;end_bp)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;map(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; (i, i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Now some insanity: we need to shuffle the words. The reason&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; for that is we do not want to apply jalt to two consecutive&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; words: it is ugly. Now only our code looks ugly.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; word_list&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; word_list&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span&gt;clone()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span&gt;step_by(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span&gt;chain(word_list&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;clone()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;skip(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;step_by(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span&gt;chain(word_list&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;clone()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;skip(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;step_by(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span&gt;rev(); &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; We assume our ShapedText type has a &amp;quot;reshape_with&amp;quot; method&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; This method takes the ShapedInput slice we have, well, &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; reshapes it, and gives it the result.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Cool Rust feature: Labeled Blocks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; words_to_change&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-lifetime&quot;&gt;outer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; First we try changing one word&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (word_start, word_end)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; word_list {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;            let&lt;&#x2F;span&gt;&lt;span&gt; word&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;slice_betweeen(word_start, word_end);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;            let&lt;&#x2F;span&gt;&lt;span&gt; reshaped&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; word&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;reshape_with(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;jalt&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;            let&lt;&#x2F;span&gt;&lt;span&gt; delta&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; reshaped&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;width()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; word&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;width();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; delta&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; stretched_base&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; desired_width {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                &#x2F;&#x2F; instead of returning with error&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                continue&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;            }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else if&lt;&#x2F;span&gt;&lt;span&gt; delta&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; cmprsd_bse&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; desired_width {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                &#x2F;&#x2F; what if the jalts are _too_ long?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                continue&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;            }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                &#x2F;&#x2F; assign the found word&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                break&lt;&#x2F;span&gt;&lt;span&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-lifetime&quot;&gt;outer&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt; vec!&lt;&#x2F;span&gt;&lt;span&gt;[(word_start, word_end)];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;       }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;       &#x2F;&#x2F; Then we try changing two words&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (fst_start, fst_end)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; word_list {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            for&lt;&#x2F;span&gt;&lt;span&gt; (snd_start, snd_end)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; word_list {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span&gt; fst_start&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; snd_start {&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; continue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;                let&lt;&#x2F;span&gt;&lt;span&gt; fst_word&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;slice_betweeen(fst_start, fst_end);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;                let&lt;&#x2F;span&gt;&lt;span&gt; fst_reshaped&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; fst_word&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;reshape_with(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;jalt&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;                let&lt;&#x2F;span&gt;&lt;span&gt; snd_word&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;slice_betweeen(snd_start, snd_end);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;                let&lt;&#x2F;span&gt;&lt;span&gt; snd_reshaped&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; snd_word&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;reshape_with(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;jalt&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;                let&lt;&#x2F;span&gt;&lt;span&gt; delta&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; fst_reshaped&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;width()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; fst_word&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;width()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                            +&lt;&#x2F;span&gt;&lt;span&gt; snd_reshaped&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;width()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; snd_word&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;width();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span&gt; (delta&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; stretched_base&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; desired_width) &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;                   ||&lt;&#x2F;span&gt;&lt;span&gt; (delta&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; cmprsd_bse&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; desired_width) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    continue&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;                }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                    &#x2F;&#x2F; assign the found words&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    break&lt;&#x2F;span&gt;&lt;span&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-lifetime&quot;&gt;outer&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-macro&quot;&gt; vec!&lt;&#x2F;span&gt;&lt;span&gt;[(fst_start, fst_end), (snd_start, snd_end)];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Then we try 3 .. this can probably be written to be better&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; NOW we return with Error. This exits the build_line() function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;LineTooLoose&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Sort our words to change based on their order.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; words_to_change&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; words_to_change&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;sort_by_key(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;(x,_)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; x);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; now we rebuild our boxes list with our new found vector,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; and also shadow (redefine) the variables b_and_g and &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; sum_boxes, from the start of the build_line() function.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;    let mut&lt;&#x2F;span&gt;&lt;span&gt; idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;    let mut&lt;&#x2F;span&gt;&lt;span&gt; segments&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt;u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-primitive&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; (s, e)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; words_to_change {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; idx {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            segments&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;push((idx, s,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            segments&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;push((s, e,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            segments&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;push((idx, e,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; e;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; end_bp {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        segments&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;push((idx, end_bp,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; b_and_g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        segments&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;map(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;(s, e, c)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; c {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;slice_betweeen(s, e)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;reshape_with(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;jalt&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;            }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;slice_betweeen(s, e)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;        })&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;reduce(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;a, b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; b);&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; concatenating the whole thing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; sum_boxes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b_and_g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;filter(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;| !&lt;&#x2F;span&gt;&lt;span&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;is_whitespace())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                           .&lt;&#x2F;span&gt;&lt;span&gt;map(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;horizontal_advance())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                           .&lt;&#x2F;span&gt;&lt;span&gt;sum();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Rest is the same. perhaps add a penalty if you get to 3 jalts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; true_width&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sum_boxes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; (count_glue&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; pft_space);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; actual_space_width&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (desired_width&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; true_width)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;count_glue&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; pft_space;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; line_cost&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Math&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;square(desired_width&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; true_width);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Here is where you place a bunch of code laying out the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; glyphs (sorry boxes) into a Line object, with the &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; actual_space_width you found, and return it!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-entity z-name z-type z-result&quot;&gt;    return Ok&lt;&#x2F;span&gt;&lt;span&gt;(final_line);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;phew! This took me a few days to express properly, and I hope the intent is clear. I am sure if you actually implement this in a code base a lot of bugs will come up, nut hey!&lt;&#x2F;p&gt;
&lt;p&gt;This code could be even expanded to take a bunch of OpenType features ( evne specified by the user) and apply them in order of priority. Let&#x27;s keep this as an exercise for the reader.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;variable-fonts&quot;&gt;Variable Fonts&lt;&#x2F;h2&gt;
&lt;p&gt;This is probably the best solution. Sadly, it is not (yet?) common in most fonts. Definitely not the ones shipping by default in operating systems.&lt;&#x2F;p&gt;
&lt;p&gt;For the uninitiated, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;fonts.google.com&#x2F;knowledge&#x2F;introducing_type&#x2F;introducing_variable_fonts&quot;&gt;here is a useful Google Fonts primer on what variable fonts are and how they work&lt;&#x2F;a&gt;. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;variable-fonts&#x2F;https-medium-com-tiro-introducing-opentype-variable-fonts-12ba6cd2369&quot;&gt;This is an article by John Hudson of Tiro Typeworks&lt;&#x2F;a&gt;. The most useful part of Variable Fonts, imo, is that font designers are free to implement any variable axis they want. The spec has five axis with a .. well .. specified behaviour, but designers are not restricted by them. The five registered axis are Weight &lt;code&gt;wght&lt;&#x2F;code&gt;, Width &lt;code&gt;wdth&lt;&#x2F;code&gt;, Optical size &lt;code&gt;opsz&lt;&#x2F;code&gt;, Italic &lt;code&gt;ital&lt;&#x2F;code&gt;, and Slant &lt;code&gt;slnt&lt;&#x2F;code&gt;. But how about &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codepen.io&#x2F;mandymichael&#x2F;pen&#x2F;pxXNbr&quot;&gt;Temprature&lt;&#x2F;a&gt;? &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.29lt.com&#x2F;product&#x2F;29lt-okaso&#x2F;&quot;&gt;Stretch&lt;&#x2F;a&gt;? &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.type-together.com&#x2F;belarius-font&quot;&gt;Serif&lt;&#x2F;a&gt;? &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;v-fonts.com&#x2F;tags&#x2F;C5&quot;&gt;The possibilities are practically endless&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For justification, one can either use the Width axis (as &lt;a href=&quot;hhttps:&#x2F;&#x2F;sites.google.com&#x2F;view&#x2F;sultanfonts&#x2F;naskh-font&#x2F;plain&quot;&gt;Sultan al-Maqtari does with his font Sultan Plain&lt;&#x2F;a&gt;), or use what is called a &lt;code&gt;GEXT&lt;&#x2F;code&gt;, a Glyph Extension axis. This &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;simoncozens.github.io&#x2F;more-on-newbreak&#x2F;&quot;&gt;article by Simon Cozens&lt;&#x2F;a&gt; has an example for an Armenian font. The simple idea is that you break the lines with a greedy algorithm (what Knuth calls first-fit), and then simply .. increase the width, or the glyph extension, of your lines to fit in the desired space.&lt;&#x2F;p&gt;
&lt;p&gt;This gives back autonomy to the font designer: the line stretchs the way they see fit. It is simpler to program for software makers than the hodgepodge of selecting &lt;code&gt;jalt&lt;&#x2F;code&gt;s above. The spaces are all at the ideal space. The text all looks neat. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jmsole&#x2F;gext-demos&quot;&gt;Here are a few demos of how this might look in practice&lt;&#x2F;a&gt;. There are no downsides!!&lt;&#x2F;p&gt;
&lt;p&gt;Well the main downside is that it is not widely available, and there is no generally agreed on axis for justification use. (That last point is why Cozens is suggesting the &lt;code&gt;GEXT&lt;&#x2F;code&gt; axis.) The other (minor) downside is is that the axis are &lt;em&gt;not&lt;&#x2F;em&gt; guaranteed to be evenly distributed. If you measure the line&#x27;s width at axis point 0, and measure it again at axis point 100, there is zero guarantee that the line width at axis point 50 would be their average. Also it is all a bit wonky in browsers. But who cares about browsers?&lt;&#x2F;p&gt;
&lt;p&gt;From a naive point of view, the typestter should do the following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Check if the font is variable,&lt;&#x2F;li&gt;
&lt;li&gt;Check if it has a &lt;code&gt;GEXT&lt;&#x2F;code&gt; axis, (and if not use the &lt;code&gt;wdth&lt;&#x2F;code&gt; axis or just ask the user!)&lt;&#x2F;li&gt;
&lt;li&gt;Use the greedy algorithm to break lines.&lt;&#x2F;li&gt;
&lt;li&gt;Stretch each line until they fit!!&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This might still fail, by the way, as not every line is guaranteed to be filled (as not every character us guaranteed to be affected by every axis.) But it is hell a lot better than inserting ugly straight line Kashidas.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;spacing-clusters&quot;&gt;Spacing Clusters&lt;&#x2F;h2&gt;
&lt;p&gt;I promised unhingedness. How about this:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;practical-arabic-justification&#x2F;just-cluster-spacing.png&quot; alt=&quot;spacing clusters justification&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Instead of spacing between words, Arabic text can increase the spacing between clusters!! Nobody does it this way but it would be cool. Do not actually do that.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;priority-list&quot;&gt;Priority list&lt;&#x2F;h2&gt;
&lt;p&gt;Before setting up rules for justification, the typesetter first and foremost should ask the user which method to use! The user know the font they are using and they know which method they prefer. If they want to justify their text by flexing spaces (aka Knuth-Plass), let them. If they want to use the &lt;em&gt;weight&lt;&#x2F;em&gt; axis instead of the &lt;em&gt;width&lt;&#x2F;em&gt; axis, sure. If they want to specify specfic OpenType features to use for justification (like using a number of Stylistic sets or Swashes), then that&#x27;s what they want.&lt;&#x2F;p&gt;
&lt;p&gt;It is perhaps the best way to go on about this, honestly. Unless they ask for Kashidas, then you crash the software.&lt;&#x2F;p&gt;
&lt;p&gt;If I were to create a priority system of justification, I would set it as follows:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;If the font is &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;practical-arabic-justification&#x2F;#variable-fonts&quot;&gt;variable&lt;&#x2F;a&gt;, check if it has an axis specified for justification. Could be &lt;code&gt;GEXT&lt;&#x2F;code&gt; or &lt;code&gt;JSTF&lt;&#x2F;code&gt; or w&#x2F;e (or ask the user!).&lt;&#x2F;li&gt;
&lt;li&gt;If it does, use it. If it does not, check for &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;practical-arabic-justification&#x2F;#opentype-features&quot;&gt;&lt;code&gt;jalt&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;s.&lt;&#x2F;li&gt;
&lt;li&gt;If they exist, use them. If they do not, well now you have to use &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;practical-arabic-justification&#x2F;#kashidas&quot;&gt;Kashidas&lt;&#x2F;a&gt;. Insert those between letters as needed. But not any letters!! There are rules!!&lt;&#x2F;li&gt;
&lt;li&gt;And for God&#x27;s sake reshape the text after inserting them Kashidas. It is what the shaper is there for.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Knuth&#x27;s Linebreaking Algorithm for non-Programmers</title>
        <published>2023-04-02T00:00:00+00:00</published>
        <updated>2023-04-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Abdul Rahman Sibahi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ar-ms.me/thoughts/linebreaking/"/>
        <id>https://ar-ms.me/thoughts/linebreaking/</id>
        
        <content type="html" xml:base="https://ar-ms.me/thoughts/linebreaking/">&lt;p&gt;I am an architect (the physical kind), not a programmer, and I am interested in Typesetting and fonts. The common wisdom online is that Knuth&#x27;s linebreaking algorithm, implemented for TeX some time back, is the be all end all way to typeset text on a printed page. But there are no clear explanations of what the algorithm &lt;em&gt;is&lt;&#x2F;em&gt;, beyond handwavey explanations of boxes and glue and penalties. I, being a lemming, strove to understand the algorithm, and I believe I can explain it succinctly. I promise not to use the phrase &quot;Dynamic Programming&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.eprg.org&#x2F;G53DOC&#x2F;pdfs&#x2F;knuth-plass-breaking.pdf&quot;&gt;Here is Donald Knuth and Michael Plass&#x27;s 1981 paper&lt;&#x2F;a&gt;. It is more thorough and rigorous than what I am writing here. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jaroslov&#x2F;knuth-plass-thoughts&#x2F;blob&#x2F;master&#x2F;plass.md&quot;&gt;Here is another article explaining the algorithm in a different manner&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For the rest of this article I will assume paragraphs are in one language and one script, so no bi-directional text complications. There is also no discussion of TeX&#x27;s other features because this is not about TeX.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;linebreaking&#x2F;Screenshot%202023-04-01%20at%203.26.51%20AM.png&quot; alt=&quot;Paragraph example&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;input&quot;&gt;Input&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;the-text&quot;&gt;The Text&lt;&#x2F;h3&gt;
&lt;p&gt;The most important input is the text. However, the algorithm does not deal with the raw encoded text. You need to process your text to extract &lt;strong&gt;boxes&lt;&#x2F;strong&gt;, &lt;strong&gt;glue&lt;&#x2F;strong&gt;, and &lt;strong&gt;breakpoints&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The first process is called &quot;Shaping&quot;. The shaper (the most famous of which is HarfBuzz), takes the input text and the font you want to use and gives you three things: what glyphs (from the font) to use, their order, and their positioning (think kerning). In other words, it gives you a series of &lt;strong&gt;boxes&lt;&#x2F;strong&gt;. The linebreaking algorithm does not care what is &lt;em&gt;inside&lt;&#x2F;em&gt; the box. It only cares about the box&#x27;s &quot;width&quot;, or the horizontal advance.&lt;&#x2F;p&gt;
&lt;p&gt;The shaper also tells you that which characters from your text are whitespace, and be stretched and squashed as needed. The space is the most famous of those, but there are others. These are called &lt;strong&gt;glue&lt;&#x2F;strong&gt;. Each glue character has a default width, a minimum width, and a maximum width. (The paper expresses the minimum and maximum as ratios, and I do not quite understand that specific part to be honest as it is mathier than what I know.) In practical terms, this says that the space can&#x27;t be so small that words are glued together, and it can&#x27;t be so large that most of the line becomes whitespace. These values can be based on the font or the script or the designer or whoever. The minimum could even be zero should the designer wishes.&lt;&#x2F;p&gt;
&lt;p&gt;Also, you need to run your input text through a &lt;strong&gt;breakpoint&lt;&#x2F;strong&gt;-finding algorithm. This is to say, you need to know &lt;em&gt;where&lt;&#x2F;em&gt; you can break your text into lines. You can&#x27;t just break the line arbitrarily anywhere, or only at glue (think hyphenation). The Unicode ICU library has the tools for that.&lt;&#x2F;p&gt;
&lt;p&gt;Knuth&#x27;s name for breakpoints is &lt;strong&gt;penalties&lt;&#x2F;strong&gt;, and that includes mandatory breakpoints, such as the end of paragraphs, and undesirable breakpoints, such as hyphenated words. In Knuth&#x27;s implementation, penalties have a width. Usually it is zero, but when you break at a hyphen, you need to add the hyphen&#x27;s width. If you want to implement trailing punctuation (a rather nifty typographic trick), you give the penalty &lt;em&gt;after&lt;&#x2F;em&gt; the punctuation a &lt;em&gt;negative&lt;&#x2F;em&gt; width. Look at the paper for more detail.&lt;&#x2F;p&gt;
&lt;p&gt;Note that boxes having a fixed width is a rather hefty assumption. It only works for Latin typesetting, and only works for fixed fonts. In other scripts, characters may have alternate shapes that may be wider or narrower. There is even an OpenType feature for that, called Justification Alternates. Many variable fonts have axis that only control specific letters. See an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.29lt.com&#x2F;product&#x2F;29lt-okaso&#x2F;&quot;&gt;Arabic and Latin example&lt;&#x2F;a&gt; and an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;simoncozens.github.io&#x2F;more-on-newbreak&#x2F;&quot;&gt;Armenian one&lt;&#x2F;a&gt;. The Knuth-Plass algorithm as usually implemented does not know how to deal with either of these features, and because Latin-centric software designers, we Arabic speakers are stuck with ugly justified text. But I am coming to that later.&lt;&#x2F;p&gt;
&lt;p&gt;Back on track: you get your text. You run through the shaper, and the Unicode ICU library, and you get two lists.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A list of glyphs, expressed as fixed width &lt;strong&gt;boxes&lt;&#x2F;strong&gt; (letters), and stretchable, squashable &lt;strong&gt;glue&lt;&#x2F;strong&gt; (white space).&lt;&#x2F;li&gt;
&lt;li&gt;A list of &lt;strong&gt;breakpoints&lt;&#x2F;strong&gt;, places you can break the line. They have an associated value called &lt;strong&gt;penalties&lt;&#x2F;strong&gt; which ranges from -100,000 (never break here) to +100,000 (must break).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;the-line-width&quot;&gt;The Line Width&lt;&#x2F;h3&gt;
&lt;p&gt;Self explanatory really. You have a specific line width you want to justify your text into. Or even a series of line widths for text (say for text typeset in a circle).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-algorithm&quot;&gt;The Algorithm&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;description&quot;&gt;Description&lt;&#x2F;h3&gt;
&lt;p&gt;This beautiful graph from the Knuth-Plass paper (linked in the intro) explains the central idea of the algorithm fairly well. Seeing it in the paper was a Eureka moment for me.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;linebreaking&#x2F;Paragraph%20Graph.png&quot; alt=&quot;Paragraph Graph&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is a directed graph from the beginning of the paragraph to the end, where the breakpoint is mandatory. The graph&#x27;s nodes are the breakpoints. The edges are the lines typeset between said breakpoint. The edge&#x27;s &lt;em&gt;cost&lt;&#x2F;em&gt;, the little number next to it, is the &quot;ugliness&quot; of the line, as it were: an evenly spaced line as the font designer intended where the distance from the beginning to the end is exactly the given line width, would have zero cost. The cost&#x27;s formula is easily findable online, adjusted by the last breakpoint&#x27;s penalty. (For example, a break at a hyphen would give a penalty of, say, -50).&lt;&#x2F;p&gt;
&lt;p&gt;The example given is fairly simple: the &lt;strong&gt;boxes&lt;&#x2F;strong&gt; are the letters; the &lt;strong&gt;glue&lt;&#x2F;strong&gt; is the spaces; and the &lt;strong&gt;breakpoints&lt;&#x2F;strong&gt; are where the spaces are in addition to any hyphenation opportunities.&lt;&#x2F;p&gt;
&lt;p&gt;Here are the rough outline of how to build the graph:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Start from the beginning. This is your root node.&lt;&#x2F;li&gt;
&lt;li&gt;Identify the first following breakpoint where the line is as loose as possible. (i.e. the glue is as stretched as can be).&lt;&#x2F;li&gt;
&lt;li&gt;Identify the last following breakpoint where the line is as tight as possible. (i.e. the glue is as squished as can be).&lt;&#x2F;li&gt;
&lt;li&gt;Add the breakpoints identified in steps 2 and 3, and every breakpoint in between, as children for the node in step 1. The edge cost between the parent node and each child is based on the line formation.&lt;&#x2F;li&gt;
&lt;li&gt;For each child node, repeat the process.&lt;&#x2F;li&gt;
&lt;li&gt;After all nodes and edges have been found and calculated, pick the path from the beginning to the end with the least cost. (I think this is called the Dijkstra algorithm? It is in every graph library.)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Often, the last line, or edge, of the directed graph always has a cost of 0. In physical terms, the last line of the paragraph is not usually justified, so wherever the last word falls is fine and the spaces will be added evenly.&lt;&#x2F;p&gt;
&lt;p&gt;The penalties attached to breakpoints can change the evaluation of each line&#x27;s cost. The simplest example is hyphenation. A breakpoint at a hyphen, having a penalty of -50 (or w&#x2F;e), adds 50 points to the cost. Two hyphens in a row adds, say, 100 to the cost of both hyphens (so it is especially discouraged.) To avoid typographic orphans, the second to last and third to last breakpoints can be assigned arbitrary large penalties. Another idea suggested in the paper is to give a penalty to lines with wildly different densities (so a tight line followed by a loose line). The penalties attached to breakpoints give you a flexible toolbox to decide which typographic &quot;behaviour&quot; to encourage or discourage.&lt;&#x2F;p&gt;
&lt;p&gt;Note that these numbers for penalties are essentially arbitrary and you should try different values for different things. You can even have the user set them!&lt;&#x2F;p&gt;
&lt;p&gt;Another thing of note is that sometimes a node can have more than one parent. In fact for the last breakpoint in the paragraph this is mandatory! So when you are building the graph, you might want to check if the child node you found is already recorded, and simply extend a new edge to it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pseudocode&quot;&gt;Pseudocode&lt;&#x2F;h3&gt;
&lt;p&gt;Here is some pseudorustcode showcasing the idea (as I am currently learning Rust):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;use&lt;&#x2F;span&gt;&lt;span&gt; made_up_graph_library;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; line_break (input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ShapedText&lt;&#x2F;span&gt;&lt;span&gt;, width&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: f64&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Line&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; bps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;breakpoints();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; paragraph start&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; graph&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Graph&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;new();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    graph&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;add_node(bps[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;AsRoot&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;bps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;len() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; if no node exists for this breakpoint, continue,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; since nodes are created by the inner loop below.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt; !&lt;&#x2F;span&gt;&lt;span&gt;graph&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;contains_node(bps[i]) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            continue&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; j&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; (i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;bps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;len() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F; a build_line() function that takes &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F; ShapedText, indices of start and end,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F; and a desired line width, and returns &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F; Result&amp;lt;Line, Error&amp;gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F; Each Line has a cost property.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;            let&lt;&#x2F;span&gt;&lt;span&gt; attempt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; build_line(input, i, j, width);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            match&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; attempt {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                &#x2F;&#x2F; if line is too loose skip to the next&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                &#x2F;&#x2F; iteration of the inner loop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;LineTooLoose&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; continue&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                &#x2F;&#x2F; if line is too tight, break the inner loop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;LineTooTight&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                &#x2F;&#x2F; if line is buildable :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type z-result&quot;&gt;                Ok&lt;&#x2F;span&gt;&lt;span&gt;(line)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                    &#x2F;&#x2F; if the bps[j] node was created in a &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                    &#x2F;&#x2F; previous iteration, update it&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;                    if&lt;&#x2F;span&gt;&lt;span&gt; graph&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;contains(bps[j]) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        graph&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;add_edge(parent&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; bps[i],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                       child&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; bps[j], &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                       edge&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; line);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                    &#x2F;&#x2F; and if it wasn&amp;#39;t, create it.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;                    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        graph&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;add_node(bps[j], &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                       AsChild(parent&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; bps[i], &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                               edge&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; line));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;                    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; bunch of imagined methods where the graph library gives me &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; the shortest path from a given start to a given end, then &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; returns a vector of the edges passed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; output&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; graph&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;shortest_path(from&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; bps[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                     to&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; bps[bps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;len()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                     eval&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-logical&quot;&gt;: |&lt;&#x2F;span&gt;&lt;span&gt;line&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; line&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;cost)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                      .&lt;&#x2F;span&gt;&lt;span&gt;edges()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                      .&lt;&#x2F;span&gt;&lt;span&gt;collect();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    output&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s it. This is the Knuth-Plass linebreaking algorithm, more or less.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;adjustments&quot;&gt;Adjustments&lt;&#x2F;h3&gt;
&lt;p&gt;Note that now there is no logic to punish two consecutive hyphenations and paragraph lengths and other cost adjustments related to the paragraph as a whole. One could add these adjustments after creating the graph, by traversing the graph and adjusting the cost of any edge between two hyphens, or any sequence of edges with disparate density, and what have you. The sky is the limit.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;real-world-example-typst&quot;&gt;Real world example: Typst&lt;&#x2F;h3&gt;
&lt;p&gt;From the little code examples I have seen, the algorithm is implemented slightly differently. Here is a real world example:&lt;&#x2F;p&gt;
&lt;p&gt;I have been looking a the line breaking algorithm implemented in Typst. It follows the same basic algorithm we are talking about, but builds the underlying graph differently, but calls it a table rather than a graph, just to confuse non-CS folks. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;typst&#x2F;typst&#x2F;blob&#x2F;cc67e5309994eefd1bd1c892f040ec7912052a4b&#x2F;library&#x2F;src&#x2F;layout&#x2F;par.rs#L819&quot;&gt;You can find the description and the code here&lt;&#x2F;a&gt;. From what I understand, it assigns each breakpoint, starting from the first, the cost of setting the paragraph up to itself, but that calculation takes into account the previous breakpoints&#x27; recorded score. If you will allow me to refer again to the beautiful graph above, look at the breakpoint &quot;so&quot; in the third line, and what is above it. To simplify the reasoning a bit, let&#x27;s assume only the breakpoints in the graph are valid, even tho the logic would be the same when you go over every breakpoint.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Beginning to the first bp &quot;a&quot; has a cost of 2357.&lt;&#x2F;li&gt;
&lt;li&gt;First bp &quot;a&quot; to second bp &quot;king&quot; has a cost of 2357 (cost of &quot;a&quot;) plus whatever the cost of &quot;a&quot; to &quot;king&quot; is. We find that Beginning to second bp &quot;king&quot; has a cost of 1734, which is less than 2357 + x, so we record that &quot;king&quot; has a cost of 1734.&lt;&#x2F;li&gt;
&lt;li&gt;Third bp &quot;was&quot; goes through the same logic with every previous breakpoint, and the graph artist already found out the lowest cost &quot;was&quot; can have is 2363 (2357 + 6), we record that for &quot;was&quot; noting that we are basing this off of &quot;a&quot;.&lt;&#x2F;li&gt;
&lt;li&gt;Fourth bp &quot;so&quot; , when connecting with &quot;a&quot; has a cost of 4633 (2276 + 2357). When connecting with &quot;king&quot; it is 6426 (4692 + 1734). So we record that for &quot;so&quot; the least value we found was 4633 while connecting through &quot;a&quot;.&lt;&#x2F;li&gt;
&lt;li&gt;etc for each following one.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;By recording the least value each breakpoint has, by the time you reach the last breakpoint, you already have the lowest cost path calculated for you with the lists of breakpoints you should, well, break at. I annotated this logic on the graph above, showing the cost of each breakpoint and highlighting the parent relationship that gave me the lowest cost (when there are multiple parents).. The path from the last breakpoint (at &quot;thing&quot;) that gives &quot;thing&quot; the lowest cost is left as an exercise to the reader. To know the cost of each path, add the path&#x27;s cost to the parent node&#x27;s cost, and pick the path that gives you the least cost.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;linebreaking&#x2F;Paragraph%20Graph%20annotated.png&quot; alt=&quot;Annotated Graph&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I find my version above easier to grok, to be honest. Either way you organize the code, you are building a graph, and then you are traversing it to find the shortest path. The main difference is where the cost is encoded. In my version, the cost is encoded in the edges themselves, where each edge carries its cost. In the Typst version, the cost is encoded on each breakpoint, by finding the smallest cost among parent nodes and their incoming edges.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-about-build-line&quot;&gt;What about &lt;code&gt;build_line()&lt;&#x2F;code&gt; ?&lt;&#x2F;h2&gt;
&lt;p&gt;You will have noticed by now that I made no mention of boxes and glue in the code snippet above. This is because, in that model, they are the domain of the &lt;code&gt;build_line()&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; Function signature&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; build_line(input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ShapedText&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              start_breakpoint&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              end_breakpoint&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              desired_linewidth&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: f64&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Line&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;How this function should work can be summarised as:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Take the input processed and shaped text.&lt;&#x2F;li&gt;
&lt;li&gt;Take a slice out of it. You know have an array (or vector) of glyphs, each has a specific width.&lt;&#x2F;li&gt;
&lt;li&gt;Mark which glyphs are glue. (i.e. mark the spaces).&lt;&#x2F;li&gt;
&lt;li&gt;Find the sum of all the boxes&#x27; widths. And find the number of the glue characters.&lt;&#x2F;li&gt;
&lt;li&gt;Calculate the sum of all boxes and glue widths, with the glue at the maximum width per space character. If it is &lt;em&gt;less&lt;&#x2F;em&gt; than the desired width return an &lt;code&gt;Error::LineTooLoose&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Repeat with the glue at the minimum width per space character. If it &lt;em&gt;more&lt;&#x2F;em&gt; than the desired width return an &lt;code&gt;Error::LineTooTight&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Now do it with the glue at the ideal (font given) width per space character. &lt;em&gt;This&lt;&#x2F;em&gt; width, and its difference from the given line width (in the function input) is what is used to calculate the line&#x27;s &lt;code&gt;cost&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Simple arithmetic should tell what the glue size for this line is.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;pseudocode-1&quot;&gt;Pseudocode&lt;&#x2F;h3&gt;
&lt;p&gt;Here is again the pseudorustcode of our function.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; build_line(input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ShapedText&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              start_bp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              end_bp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              desired_width&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-entity z-name z-type z-numeric&quot;&gt;: f64&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Line&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; trims the glue at the beginning and end.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; b_and_g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;slice_betweeen(start_bp, end_bp);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; sum_boxes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b_and_g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;filter(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;| !&lt;&#x2F;span&gt;&lt;span&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;is_whitespace())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                           .&lt;&#x2F;span&gt;&lt;span&gt;map(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;horizontal_advance())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                           .&lt;&#x2F;span&gt;&lt;span&gt;sum();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; count_glue&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b_and_g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;filter(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;is_whitespace())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                            .&lt;&#x2F;span&gt;&lt;span&gt;count();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; bear with me here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; pft_space&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ideal_space_width();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; min_space&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;min_space_width();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; max_space&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max_space_width();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; sum_boxes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; (count_glue&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; max_space)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; desired_width {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;LineTooLoose&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; sum_boxes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; (count_glue&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; min_space)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt; desired_width {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;LineTooTight&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; true_width&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sum_boxes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; (count_glue&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; pft_space);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; someone doublecheck this next line please&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; actual_space_width&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (desired_width&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; true_width)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;count_glue&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; pft_space;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; raw cost, before changes for hyphenation and the like&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; line_cost&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Math&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;square(desired_width&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; true_width);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Here is where you place a bunch of code laying out the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; glyphs (sorry boxes) into a Line object, with the &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; actual_space_width you found, and return it!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-entity z-name z-type z-result&quot;&gt;    return Ok&lt;&#x2F;span&gt;&lt;span&gt;(final_line);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-brackets z-curly&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I hope you enjoyed this read and that you found it educational. In the next post I will write how the &lt;code&gt;build_line()&lt;&#x2F;code&gt; function can be adapted for non-Latin scripts (namely Arabic because that&#x27;s all I know).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Edit on 12-Apr-2023: &lt;a href=&quot;https:&#x2F;&#x2F;ar-ms.me&#x2F;thoughts&#x2F;practical-arabic-justification&#x2F;&quot;&gt;Here is Part 2&lt;&#x2F;a&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
