<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="en">
	<title>Luciano Laratelli</title>
	<subtitle>The personal website for Luciano Laratelli, a software developer in Miami Beach.</subtitle>
	<link href="https://luciano.laratel.li/feed/feed.xml" rel="self"/>
	<link href="https://luciano.laratel.li/"/>
	<updated>2024-06-24T00:00:00Z</updated>
	<id>https://luciano.laratel.li</id>
	<author>
		<name>Luciano Laratelli</name>
		<email>luciano@laratel.li</email>
	</author>
	
	<entry>
		<title>Setting up dynamic DNS for Namecheap using Dockerized Caddy</title>
		<link href="https://luciano.laratel.li/blog/caddy-dynamic-dns/"/>
		<updated>2024-06-24T00:00:00Z</updated>
		<id>https://luciano.laratel.li/blog/caddy-dynamic-dns/</id>
		<content type="html">&lt;p&gt;The internet is unusable without ad blocking, so I route all of our network
traffic through &lt;a href=&quot;https://pi-hole.net/&quot;&gt;Pi-hole&lt;/a&gt; running on my home server to
block ads. I want that same experience when I&#39;m away from home, so I set up a
VPN with &lt;a href=&quot;https://www.wireguard.com/&quot;&gt;WireGuard&lt;/a&gt; to allow me to use my home
Pi-hole as the DNS server for my phone and laptop when on the go.&lt;/p&gt;
&lt;p&gt;This works great except for when my home network falls over, or I lose power, or
when the unexpected happens. We recently went on vacation and, of course, the
day we got there, some &amp;quot;unexpected&amp;quot; happened and I was suddenly without an ad
blocker on my phone. Before figuring out what went wrong, I quickly spun up a
similar WireGuard + Pi-hole setup on a Droplet so I could use the internet
without losing my mind.&lt;/p&gt;
&lt;p&gt;Thanks to a friend who stopped by our apartment for an unrelated reason, I
learned that the issue was that our ISP had changed our public IP on us. This is
the first time this has happened to me in the.... five? six? years I&#39;ve been running
a homelab, over four different ISPs.&lt;/p&gt;
&lt;p&gt;I thought &lt;a href=&quot;https://wiki.archlinux.org/title/Dynamic_DNS&quot;&gt;dynamic DNS&lt;/a&gt; would save
me, but it seemed clear that I&#39;d configured &lt;code&gt;ddclient&lt;/code&gt; incorrectly. Since I run
Caddy, I wondered if I could shove dynamic DNS into that. It turns out that&#39;s
possible with &lt;a href=&quot;https://github.com/mholt/caddy-dynamicdns&quot;&gt;this random &amp;quot;Caddy
app&amp;quot;&lt;/a&gt;I found, as long as I install
the right &lt;a href=&quot;https://github.com/caddy-dns&quot;&gt;Caddy DNS provider&lt;/a&gt;. I use namecheap,
so I grabbed that one.&lt;/p&gt;
&lt;p&gt;Using this Caddy app and a Caddy DNS provider involes compiling Caddy with these
modules. My home server uses Docker Compose (on Arch, btw) so I need to make an
image with the DNS provider built in. The
&lt;a href=&quot;https://hub.docker.com/_/caddy&quot;&gt;documentation&lt;/a&gt; has an example for this (under
&lt;code&gt;adding custom Caddy modules&lt;/code&gt;), which is great!&lt;/p&gt;
&lt;p&gt;My Caddy block previously looked like this:&lt;/p&gt;
&lt;pre class=&quot;language-yaml hljs&quot;&gt;&lt;code class=&quot;language-yaml hljs&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;x-common-variables:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;amp;common-variables&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;PGID:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1000&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;PUID:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1000&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;TZ:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;America/New_York&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-attr&quot;&gt;services:&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;caddy:&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;container_name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;caddy&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;image:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;caddy:2.8.4&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;restart:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;unless-stopped&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;environment:&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;lt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;*common-variables&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;HOST:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;my.host&amp;quot;&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;# an actual domain name here&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;LOCAL_IP:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;192.168&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.1&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.2&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;ports:&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;80:80&amp;quot;&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;443:443&amp;quot;&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;443:443/udp&amp;quot;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;volumes:&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;./appdata/caddy/Caddyfile:/etc/caddy/Caddyfile&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;./appdata/caddy/site:/srv&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;./appdata/caddy/data:/data&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;./appdata/caddy/config:/config&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Looking at the
&lt;a href=&quot;https://docs.docker.com/compose/compose-file/build/#illustrative-example&quot;&gt;documentation&lt;/a&gt; for Docker Compose, I want something like this:&lt;/p&gt;
&lt;pre class=&quot;language-yaml hljs&quot;&gt;&lt;code class=&quot;language-yaml hljs&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;x-common-variables:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;amp;common-variables&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;PGID:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1000&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;PUID:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1000&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;TZ:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;America/New_York&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-attr&quot;&gt;services:&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;caddy:&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;container_name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;caddy&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;restart:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;unless-stopped&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;build:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;./custom-caddy-build&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;environment:&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;lt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;*common-variables&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;HOST:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;my.host&amp;quot;&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;# an actual domain name here&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;LOCAL_IP:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;192.168&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.1&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.2&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;NAMECHEAP_SECRET_KEY:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;definitely-my-secret-key&amp;quot;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;ports:&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;80:80&amp;quot;&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;443:443&amp;quot;&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;443:443/udp&amp;quot;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;volumes:&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;./appdata/caddy/Caddyfile:/etc/caddy/Caddyfile&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;./appdata/caddy/site:/srv&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;./appdata/caddy/data:/data&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;./appdata/caddy/config:/config&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, in &lt;code&gt;custom-caddy-build/Dockerfile&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-Dockerfile hljs&quot;&gt;&lt;code class=&quot;language-Dockerfile hljs&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;FROM&lt;/span&gt; caddy:&lt;span class=&quot;hljs-number&quot;&gt;2.8&lt;/span&gt;.&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt;-builder AS builder&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;RUN&lt;/span&gt;&lt;span class=&quot;language-bash&quot;&gt; xcaddy build&#92;&lt;br&gt;    --with github.com/caddy-dns/namecheap&#92;&lt;br&gt;    --with github.com/mholt/caddy-dynamicdns&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;FROM&lt;/span&gt; caddy:&lt;span class=&quot;hljs-number&quot;&gt;2.8&lt;/span&gt;.&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;COPY&lt;/span&gt;&lt;span class=&quot;language-bash&quot;&gt; --from=builder /usr/bin/caddy /usr/bin/caddy&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I ran &lt;code&gt;sudo docker-compose up -d&lt;/code&gt; as normal and... it just worked. Neat!&lt;/p&gt;
&lt;p&gt;Now I configure the dynamic DNS plugin, in my Caddyfile:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
	dynamic_dns {
		provider namecheap {
			api_key {$NAMECHEAP_SECRET_KEY}
			user my-namecheap-user
		}
		domains {
			my.host @ www
			my.host my-subdomain
			my.host my-other-subdomain
		}
	}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I had to enable access to the &lt;a href=&quot;https://www.namecheap.com/support/api/intro/&quot;&gt;namecheap
API&lt;/a&gt; for my account before this
would work. &lt;code&gt;user&lt;/code&gt; is just my username for namecheap. To use the API, I had to
add an IP address to their allowlist. This is concerning because if my IP
address changes (the exact problem I&#39;m trying to solve), I&#39;m not sure that I&#39;ll
be able to... actually hit the namecheap API to update my dynamic DNS? We&#39;ll
cross that bridge when we inevitably get to it.&lt;/p&gt;
&lt;p&gt;Anyways, how do I check that everything worked? I set up an &lt;a href=&quot;https://www.namecheap.com/support/knowledgebase/article.aspx/43/11/how-do-i-set-up-a-host-for-dynamic-dns/&quot;&gt;A+ Dynamic DNS
record&lt;/a&gt;
pointing to 127.0.0.1. I figured if that value gets updated when I restart
Caddy, that means I&#39;ve set things up correctly. That... did not work. The A+
record would (inexplicably) get changed to an A record with the same placeholder
IP address.&lt;/p&gt;
&lt;p&gt;My next validation attempt was to change the IP address of a subdomain. I
observed a change here! The list of subdomains got a new entry for the subdomain
I changed with the correct IP address, with the old placeholder one still
present as well. This is &lt;a href=&quot;https://github.com/mholt/caddy-dynamicdns/issues/49&quot;&gt;apparently a known problem that is namecheap&#39;s
fault&lt;/a&gt; so I won&#39;t sweat it
too much, because the DNS does still work.&lt;/p&gt;
&lt;p&gt;The dynamic DNS thing (a &amp;quot;Caddy app&amp;quot;) has a &lt;code&gt;dynamic_domains&lt;/code&gt;
&lt;a href=&quot;https://github.com/mholt/caddy-dynamicdns?tab=readme-ov-file#sample-configurations&quot;&gt;feature&lt;/a&gt;
that I used originally, but it spammed a bunch of messages in my logs when I
tried to use it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;caddy  | {&amp;quot;level&amp;quot;:&amp;quot;info&amp;quot;,&amp;quot;ts&amp;quot;:1719245958.4446826,&amp;quot;logger&amp;quot;:&amp;quot;dynamic_dns&amp;quot;,&amp;quot;msg&amp;quot;:&amp;quot;domain not found in DNS&amp;quot;,&amp;quot;domain&amp;quot;:&amp;quot;atuin.my.host&amp;quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I ended up specifying my domains manually, as above. This does turn into One
More Thing I Have To Remember To Do Whenever I Add A New Service To My Home Lab but that&#39;s okay.&lt;/p&gt;
&lt;p&gt;Last thing is to format my Caddyfile:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo docker exec -it caddy caddy fmt --overwrite /etc/caddy/Caddyfile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Neat!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Setting up unattended access for our building&#39;s keypad</title>
		<link href="https://luciano.laratel.li/blog/keypad-access/"/>
		<updated>2024-03-13T00:00:00Z</updated>
		<id>https://luciano.laratel.li/blog/keypad-access/</id>
		<content type="html">&lt;p&gt;Our building has this keypad for opening the front door:&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://luciano.laratel.li/img/QO9JeDIzch-3024.avif 3024w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://luciano.laratel.li/img/QO9JeDIzch-3024.webp 3024w&quot;&gt;&lt;img alt=&quot;Picture of the keybad at our front door. It has a black receiver on the top left, a small screen just to the right of that, and a keypad on the bottom right. The whole keypad is made out of some stainless-steel looking metal.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://luciano.laratel.li/img/QO9JeDIzch-3024.jpeg&quot; width=&quot;3024&quot; height=&quot;4032&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;This keypad is half of the entry system. It allows guests to enter a code for
the unit they want to access. The computer that&#39;s hooked up to the keypad is
also connected to a phone line. When it receives a code, it maps that to a phone
number (provided manually at move-in time) and rings the designated person, who
then enters &lt;code&gt;9&lt;/code&gt; on their phone to grant access. The other half of the entry
system is for owners and residents. We use a
&lt;a href=&quot;https://web.archive.org/web/20230319133108/https://cdn.shopify.com/s/files/1/0173/0271/6516/products/TRANSPROXLinear4button_1512x.jpg?v=1586052529&quot;&gt;fob&lt;/a&gt;
to get access via doors as well as open the gate to the building&#39;s parking
garage. This system works well enough for most cases, but I had some items on my
wish list:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The system lacks &lt;em&gt;emergency access&lt;/em&gt;. If I were to lose my fob, I would have
no way to get into the building on my own; I would have to either phone a
neighbor, bother someone on the HOA board, or wait for someone to walk in or
out.&lt;/li&gt;
&lt;li&gt;Giving out the code that routes to my unit is tantamount to giving out my
phone number. After some time at our last apartment complex, I started
receiving calls from the gate even when I wasn&#39;t expecting any visitors or
deliveries. Besides being frustrating, this is also a security concern: if
I&#39;m expecting a visitor and someone tries my code around the time my visitor
should arrive, I may mistakenly allow the wrong person in.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://luciano.laratel.li/blog/keypad-access/&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;The system lacks &lt;em&gt;unattended access for trusted guests&lt;/em&gt;. I can&#39;t always pick
up the phone, even if I am home.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Two other motivating factors are that fobs cost $35 each and there&#39;s a hard cap
on the quantity of fobs the building will issue us.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://luciano.laratel.li/blog/keypad-access/&quot; id=&quot;fnref2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;I volunteer for the building by setting up the fobs and phone numbers for new
residents, which has had two main benefits. The first is that I get to meet new
folks as they come to our building, which is always nice. The second is that I
(necessarily) have access to the awful, Windows 7-running Dell PC that controls the
fob system, which means I can mess around with the values for &lt;em&gt;our&lt;/em&gt; unit
whenever I want.&lt;/p&gt;
&lt;p&gt;Here&#39;s what I did: I added a second code for our unit that calls a Twilio
number. That Twilio number is using a &lt;a href=&quot;https://www.twilio.com/docs/studio/user-guide/get-started&quot;&gt;Twilio
Flow&lt;/a&gt;, a no-code
thing, to accept input from the person at the door. It validates if that input
is a code I&#39;ve provided, then sends the Door Open signal (the number 9) back to
the keypad. The flow looks like this:&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://luciano.laratel.li/img/71KbEGNMes-1255.avif 1255w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://luciano.laratel.li/img/71KbEGNMes-1255.webp 1255w&quot;&gt;&lt;img alt=&quot;This is a screenshot of a Twilio Flow. The flow is essentially a state machine diagram. It starts with a Trigger, which transitions to a block that says &#39;hello!&#39; to the User on the &#39;incoming call&#39; trigger. After that greeting, we move to a block called &#39;Init&#39;, which asks the user to enter their code, followed by the pound key. If the user says anything or there is no input, we loop back to Init. If the user entered keys, we validate the code by sending it to a URL. If that URL returns success, we have our result: the digit 9. If not, we say &#39;Code is invalid.&#39;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://luciano.laratel.li/img/71KbEGNMes-1255.png&quot; width=&quot;1255&quot; height=&quot;1125&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;That redacted URL points at a &lt;a href=&quot;https://www.twilio.com/docs/serverless/functions-assets/functions&quot;&gt;Twilio Function&lt;/a&gt; (classic&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://luciano.laratel.li/blog/keypad-access/&quot; id=&quot;fnref3&quot;&gt;[3]&lt;/a&gt;&lt;/sup&gt;) which is not much code at all:&lt;/p&gt;
&lt;pre class=&quot;language-javascript hljs&quot;&gt;&lt;code class=&quot;language-javascript hljs&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;exports&lt;/span&gt;.&lt;span class=&quot;hljs-property&quot;&gt;handler&lt;/span&gt; = &lt;span class=&quot;hljs-keyword&quot;&gt;async&lt;/span&gt; (context, event, callback) =&amp;gt; {&lt;br&gt;  &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; good = &lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;Set&lt;/span&gt;([&lt;br&gt;    &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;123456&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-comment&quot;&gt;// definitely my real code&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;234567&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-comment&quot;&gt;// real code for my neighbor&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;345678&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-comment&quot;&gt;// absolutely the real code for a trusted friend&lt;/span&gt;&lt;br&gt;  ]);&lt;br&gt;  &lt;br&gt;  &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (good.&lt;span class=&quot;hljs-title function_&quot;&gt;has&lt;/span&gt;(event.&lt;span class=&quot;hljs-property&quot;&gt;code&lt;/span&gt;)) {&lt;br&gt;    &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;callback&lt;/span&gt;();&lt;br&gt;  } &lt;span class=&quot;hljs-keyword&quot;&gt;else&lt;/span&gt; {&lt;br&gt;    &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;callback&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;bad code&amp;#x27;&lt;/span&gt;);&lt;br&gt;  }&lt;br&gt;}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This has been a really gratifying real-world (i.e., not just software) project
for me. It has saved me &lt;em&gt;multiple&lt;/em&gt; times that I&#39;ve left my fob at home by
accident. I forget it&#39;s there until I need it and it has not failed me yet. This
setup combined with a lockbox with a key to our front door at an undisclosed
location makes it so a lot more has to go wrong for us to be locked out of our
apartment. I&#39;ve paid Twilio $41.36&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://luciano.laratel.li/blog/keypad-access/&quot; id=&quot;fnref4&quot;&gt;[4]&lt;/a&gt;&lt;/sup&gt; since February 12th, 2023 (when I set this
up) which amounts to 10.47 cents a day&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://luciano.laratel.li/blog/keypad-access/&quot; id=&quot;fnref5&quot;&gt;[5]&lt;/a&gt;&lt;/sup&gt;. It is well worth it, both for the peace of
mind and the &lt;em&gt;delight&lt;/em&gt; I get when I use it.&lt;/p&gt;
&lt;p&gt;When I started this project, I had this whole vision for some web-admin
interface to add codes dynamically for deliveries, be able to only allow them on
certain times, etc. In a rare (and maybe my first ever) moment of Technical
Maturity, I said no to that and kept it as simple as you see here.&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;These systems ostensibly allow for communication between the person at
the gate and the unit owner, but their common exposure to the elements makes
this not work well in practice. At two of the three complexes we&#39;ve lived in
with these systems, it was impossible to hear what the person at the gate was
saying. &lt;a href=&quot;https://luciano.laratel.li/blog/keypad-access/&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;This is as per the HOA rules. I know for a fact this doesn&#39;t get followed
but I&#39;m not a cop. &lt;a href=&quot;https://luciano.laratel.li/blog/keypad-access/&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;At some point before I started this, they had already come out with New
Functions and suggested not using Functions (Classic) but the classic one
seemed simpler to me at the time. &lt;a href=&quot;https://luciano.laratel.li/blog/keypad-access/&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn4&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;I&#39;ve paid them $20, $10.27, and $11.09. I have &amp;quot;auto-recharge&amp;quot; turned on, so when my balance on twilio dips below $10 I recharge up to $20. If we ever move I&#39;ll have to remember to disable the auto-recharge and then use it a bunch to not leave that money on the table. &lt;a href=&quot;https://luciano.laratel.li/blog/keypad-access/&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn5&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Computed 2024-03-13 &lt;a href=&quot;https://luciano.laratel.li/blog/keypad-access/&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
	</entry>
	
	<entry>
		<title>I rewrote this site (again [again {again (again</title>
		<link href="https://luciano.laratel.li/blog/blog-rewrite/"/>
		<updated>2024-03-12T00:00:00Z</updated>
		<id>https://luciano.laratel.li/blog/blog-rewrite/</id>
		<content type="html">&lt;p&gt;I rewrote my site again.&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://luciano.laratel.li/img/fnepcsGCjZ-680.avif 680w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://luciano.laratel.li/img/fnepcsGCjZ-680.webp 680w&quot;&gt;&lt;img alt=&quot;A two-panel comic titled &#39;Developer&#39;s side projects&#39;. The first panel has the developer sitting at their computer, saying &#39;I think I will start a blog...&#39; The second panel says &#39;looks like I will have to develop a blogging platform from scratch first.&#39;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://luciano.laratel.li/img/fnepcsGCjZ-680.png&quot; width=&quot;680&quot; height=&quot;680&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;It has gone through at least five or six lives: first it was a
&lt;a href=&quot;https://gohugo.io/&quot;&gt;Hugo&lt;/a&gt; site, then it was a &lt;a href=&quot;https://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt;
site (or maybe Jekyll was first), then I &lt;a href=&quot;https://github.com/LucianoLaratelli/laratel.li/tree/99fc8027e135f1288ae90da98bf6958338411486&quot;&gt;wrote
it&lt;/a&gt;
as a &lt;a href=&quot;https://reagent-project.github.io/&quot;&gt;reagent&lt;/a&gt; SPA, then I wrote it as a
server-rendered custom Clojure thing
(&lt;a href=&quot;https://github.com/LucianoLaratelli/laratel.li/tree/d2d5b63d40a52d603f2b6ddcde778168db3b9123&quot;&gt;first&lt;/a&gt;
with &lt;a href=&quot;https://kit-clj.github.io/&quot;&gt;Kit&lt;/a&gt;, then &lt;a href=&quot;https://github.com/LucianoLaratelli/laratel.li/tree/2afad3b8dedc2f2e2a9773d5bff64588c4c0b755&quot;&gt;another
rewrite&lt;/a&gt;
with some lessons learned from &lt;a href=&quot;https://biffweb.com/&quot;&gt;Biff&lt;/a&gt;). This latest (and,
dear god, hopefully the last) is with &lt;a href=&quot;https://www.11ty.dev/&quot;&gt;eleventy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It&#39;s hard to retrace all of my motivations for these rewrites. The initial
iterations used static site generators because I didn&#39;t know how to make a
website from HTML and CSS. I did the SPA because a) Clojure and b) my friend
Kiran had written his blog in a similar fashion. Then I switched to Kit because
of the slowness of SPAs and general difficulties authoring posts. That was bad,
too, though, so I rewrote again with a stripped-down version of Biff. That was
&lt;em&gt;fine&lt;/em&gt;, but when I went to add &lt;a href=&quot;https://luciano.laratel.li/programs/named-tab&quot;&gt;NamedTab&lt;/a&gt;, I found it not
to my tastes again. It took me way too long to get a simple one-page site up!&lt;/p&gt;
&lt;p&gt;I&#39;ve been following &lt;a href=&quot;https://fediverse.zachleat.com/@zachleat&quot;&gt;Zach Leatherman&lt;/a&gt;,
the creator and maintainer of eleventy, on Mastodon for some time. I liked what
I was seeing, loved the documentation, so I figured I&#39;d give it a go. After four
or five hours of pleasant work spread out over about a week, the new site is
ready! You&#39;re reading this post on it, in fact. I still have a few things to do
(cleaning up the image pipeline, holding the CSS stuff correctly) but I like
where it&#39;s at.&lt;/p&gt;
&lt;p&gt;This switch simplified the deployment story for this site a lot. In the most
recent iteration, publishing a new post meant:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Writing the post in org-mode&lt;/li&gt;
&lt;li&gt;Exporting it to markdown&lt;/li&gt;
&lt;li&gt;Committing and pushing to GitHub&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/LucianoLaratelli/laratel.li/blob/main/.github/workflows/deploy.yml&quot;&gt;CI&lt;/a&gt;
runs to build a
&lt;a href=&quot;https://github.com/LucianoLaratelli/laratel.li/blob/main/Dockerfile&quot;&gt;Docker&lt;/a&gt;
image that gets deployed to &lt;a href=&quot;https://fly.io/&quot;&gt;Fly.io&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This takes between a minute and 45 seconds and three minutes. You may notice
that it is also overkill for what amounts to a dumb pipe serving up some HTML
and CSS.&lt;/p&gt;
&lt;p&gt;Now it&#39;s: write blog post in either org-mode (then export it to markdown) or in markdown&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://luciano.laratel.li/blog/blog-rewrite/&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;. Then, &lt;code&gt;just deploy&lt;/code&gt;
to &lt;a href=&quot;https://srht.site/&quot;&gt;sourcehut pages&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-make hljs&quot;&gt;&lt;code class=&quot;language-make hljs&quot;&gt;&lt;span class=&quot;hljs-section&quot;&gt;install:&lt;/span&gt;&lt;br&gt;    source ${HOME}/.nvm/nvm.sh &amp;amp;&amp;amp; nvm use --reinstall-packages-from=current&lt;br&gt;    source ${HOME}/.nvm/nvm.sh &amp;amp;&amp;amp; nvm use &amp;amp;&amp;amp; yarn install&lt;br&gt;    &lt;br&gt;&lt;span class=&quot;hljs-section&quot;&gt;process:&lt;/span&gt;&lt;br&gt;    npx @11ty/eleventy&lt;br&gt;    &lt;br&gt;&lt;span class=&quot;hljs-section&quot;&gt;tar: &lt;/span&gt;&lt;br&gt;  tar -C _site -cvz . &amp;gt; site.tar.gz&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-section&quot;&gt;publish: &lt;/span&gt;&lt;br&gt;  hut pages publish -d luciano.laratel.li site.tar.gz&lt;br&gt;  &lt;br&gt;&lt;span class=&quot;hljs-section&quot;&gt;deploy:&lt;/span&gt;&lt;br&gt;  just install&lt;br&gt;  just process&lt;br&gt;  just tar&lt;br&gt;  just publish&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It&#39;s simpler, is nearly instant, and is a lot more flexible.&lt;/p&gt;
&lt;p&gt;One downside is that sourcehut &lt;a href=&quot;https://srht.site/limitations&quot;&gt;disallows&lt;/a&gt;
tracking scripts, so I can no longer use &lt;a href=&quot;https://plausible.io/&quot;&gt;plausible&lt;/a&gt; on
this site. That is entirely a vanity thing that I may be able to live without.
For the meantime, the convenience of this deployment strategy outweighs my
desire for seeing my 17 visitors a month on a slick dashboard.&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Some things (e.g. images) are just easier in markdown than trying to
wrangle &lt;a href=&quot;https://ox-hugo.scripter.co/&quot;&gt;ox-hugo&lt;/a&gt;. &lt;a href=&quot;https://luciano.laratel.li/blog/blog-rewrite/&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
	</entry>
	
	<entry>
		<title>A mental health toolkit</title>
		<link href="https://luciano.laratel.li/blog/mental-health-toolkit/"/>
		<updated>2023-09-29T15:43:00Z</updated>
		<id>https://luciano.laratel.li/blog/mental-health-toolkit/</id>
		<content type="html">&lt;p&gt;Over the course of my last regular bout of therapy, my therapist got me to learn about behaviors that he referred to as my mental health toolkit. Some of these behaviors are things we learned are necessary every day (as close as I can get to it) while others are good for times of more difficult mental health challenges than the usual. I&#39;m listing them partly to have them written down for myself, but also in the hopes someone finds a behavior that helps them too. A mental health toolkit can include behaviors that my good friend Mark calls &#39;psychic anchors&#39; — things you can do to center yourself when you find yourself in need.&lt;/p&gt;
&lt;p&gt;For my particular set of mental illnesses, the behaviors I want in my toolkit are those that induce my body to create dopamine (among other regulatory neurotransmitters). Part of the challenge is that some dopamine-creating behaviors don&#39;t go about dopamine production in a &amp;quot;sustainable&amp;quot; manner; instead, they cause a dopamine &lt;em&gt;spike&lt;/em&gt;. You might feel good, really good, for a bit, but then the crash comes and you might end up feeling worse than before. Another part is that there isn&#39;t a prescriptive set of the sustainable behaviors that we&#39;re looking for that works for everybody. One person&#39;s positive mental health behavior might be another&#39;s mental health incident trigger. You&#39;ve got to experiment.&lt;/p&gt;
&lt;p&gt;I should note I&#39;m not an expert: I&#39;m just a guy that works at Computer. I &lt;em&gt;have&lt;/em&gt; gone to many (many) years of therapy, though. This is what I&#39;ve learned works for me, and my layman analysis of what that might mean for my brain.&lt;/p&gt;
&lt;p&gt;Another important point is that these behaviors don&#39;t always work. Some days you can do everything right and still be in the mud psychologically. One of the many injustices of mental illness. But we must do what we can.&lt;/p&gt;
&lt;h2 id=&quot;physical-activity&quot; tabindex=&quot;-1&quot;&gt;Physical activity &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/mental-health-toolkit/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is an important one, and one that most people (anecdotally) find great success with. For me, just going on a long walk isn&#39;t enough. I need to get my heart rate up! Cardio and weight-lifting are great for this. I&#39;m not as consistent as I should be but I do feel a large difference in my baseline mental health even going just once.&lt;/p&gt;
&lt;h2 id=&quot;tidying-up&quot; tabindex=&quot;-1&quot;&gt;Tidying up &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/mental-health-toolkit/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It was kind of funny to find out how much this helped me. I always dreaded doing household chores (the self-sabotaging nature of ADHD is horrific) but once I realized how much better I feel when our space is neat I started actively seeking out opportunities to pick up. This positive feedback loop is very powerful:&lt;/p&gt;
&lt;pre class=&quot;language-text hljs&quot;&gt;&lt;code class=&quot;language-text hljs&quot;&gt;I feel good -&gt; let me clean up a little&lt;br&gt;     ↑                     ↓&lt;br&gt;      ↖                   ↙&lt;br&gt;         Our space is clean&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While this one is dangerous:&lt;/p&gt;
&lt;pre class=&quot;language-text hljs&quot;&gt;&lt;code class=&quot;language-text hljs&quot;&gt;I feel bad -&gt; tidying up is the worst thing I can imagine&lt;br&gt;    ↑                       ↓&lt;br&gt;     ↖                    ↙&lt;br&gt;       Our space is messy&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I wasn&#39;t able to really harness the positive feedback loop until I started taking medication &lt;em&gt;that actually worked for me&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id=&quot;medication&quot; tabindex=&quot;-1&quot;&gt;Medication &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/mental-health-toolkit/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I spent years in undergrad trying but failing to find medication that worked for me. This type of diagnosis is hard! Eventually I just stopped taking medication altogether and dealt with life raw. It was only when I started seeing my latest therapist that I was able to get a proper diagnosis. After a couple sessions with me, he blew my mind when he said I had &amp;quot;a textbook case of undiagnosed adult ADHD.&amp;quot; ADHD medication changed almost everything about how I engage with my life. It can&#39;t and won&#39;t be a solution for everyone, but if you have a therapist and doctor you trust and they recommend something, I hope it is helpful.&lt;/p&gt;
&lt;h2 id=&quot;socializing&quot; tabindex=&quot;-1&quot;&gt;Socializing &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/mental-health-toolkit/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I spent most of my life thinking I was an introvert because I felt awkward in social situations. Some of those feelings were certainly part of the process of coming into my own as a person — finding your way as a teenager and young adult can be hard! Looking back, I now recognize that many of those feelings stemmed from mental illness. That type of feeling can often push you &lt;em&gt;away&lt;/em&gt; from socializing.&lt;/p&gt;
&lt;p&gt;I learned I&#39;m not an introvert when the government began reducing COVID restrictions and people started congregating again. I&#39;ve always worked from home, but because I started working professionally in 2021, I had no ability to get out of the house for much of my early professional life. Once I had the ability to do so, I realized I &lt;em&gt;needed&lt;/em&gt; to — that social contact was deeply energizing for me in a restorative way. This is different than for my partner, who is a self-described &amp;quot;extroverted-introvert&amp;quot;. She feels the need to recharge her social batteries with some alone time after a series of repeated outings.&lt;/p&gt;
&lt;p&gt;Getting adequate amounts of socializing is tough, because working from home means I don&#39;t really have a &amp;quot;third place&amp;quot;.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://luciano.laratel.li/blog/mental-health-toolkit/&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; A potential solution is just paying for one by going to a local coffee shop or buying access to a co-working space. Though I do like to go to our local coffee shop, it isn&#39;t a perfect solution because of the ongoing costs, the un-ergonomic work environment, and the difficulties of taking meetings in a public space. Co-working spaces are even more expensive than a daily coffee or two. This is all cheaper than a daily commute, of course.&lt;/p&gt;
&lt;p&gt;&amp;quot;Just go out on weekends&amp;quot; is not an end-all solution either. Weekend outings are great, and definitely help! But they yield a big dopamine spike compared to the steady socializing you might get from a co-working space or commuting to an office.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://luciano.laratel.li/blog/mental-health-toolkit/&quot; id=&quot;fnref2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt; This isn&#39;t something I always &lt;em&gt;want&lt;/em&gt; to do, either — if my partner wants to stay in to decompress, going out means her sacrificing her social battery recharging time for my well-being (I love her for this, but it&#39;s not ideal) or it means not necessarily spending quality weekend time together. It certainly isn&#39;t a requirement that we be joined at the hip all weekend, so sometimes I go this route. Going out, of course, costs money. Very few social places remain where you can go without paying for the privilege.&lt;/p&gt;
&lt;p&gt;I have contemplated getting an in-person or hybrid job, but the Miami tech scene is not conducive to my doing so. There&#39;s a lot of reasons for this that aren&#39;t related to this post, so I won&#39;t get into them. I would also probably have to buy a car, which seems like nasty business given how much I&#39;ve enjoyed being car-free for the last couple years.&lt;/p&gt;
&lt;h2 id=&quot;journaling&quot; tabindex=&quot;-1&quot;&gt;Journaling &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/mental-health-toolkit/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;My boss at my first software job (a great person) taught me this one when I expressed I was overwhelmed with the number of tasks I had to do for a project. He told me to write everything down to get it out of my head. It is shocking how much it helps. My therapist later taught me I should be doing this for my personal things too. Especially in moments where my mental health is poor, journaling helps me to externalize those thoughts.&lt;/p&gt;
&lt;p&gt;One of my first girlfriends (my first serious girlfriend) taught me about writing a letter when you&#39;re angry at someone, explaining how you feel. Then you shred or burn it. The process of writing down how you feel while addressing it to someone is a calming exercise that helps you settle before talking to the person about how you feel (related: &amp;quot;Never send an email when you&#39;re angry.&amp;quot;)&lt;/p&gt;
&lt;p&gt;Blogging is a similar tool. &lt;em&gt;I&#39;m doing it right now!&lt;/em&gt; I think it&#39;s better for writing about things I&#39;ve learned and want to have somewhere than for my thoughts and feelings, especially when I&#39;m in a poor state of mental health — the privacy of the journal page brings a lot of psychological safety. I also don&#39;t have to edit out curse words. But having a written, public record of an idea makes you refine the thought in a way that journaling doesn&#39;t. You have to pick the right tool for the job.&lt;/p&gt;
&lt;h2 id=&quot;taking-a-shower&quot; tabindex=&quot;-1&quot;&gt;Taking a shower &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/mental-health-toolkit/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is the primary &amp;quot;psychic anchor&amp;quot; I learned from Mark. This doesn&#39;t refer to a needed shower as part of a regular hygiene schedule, though it can. This refers to the positive effect of taking a step out of the (physical, mental, emotional) space I&#39;m in and taking a quiet couple minutes in the shower. It&#39;s really effective and helps a lot for anxiety. This is more of a &amp;quot;quick fix&amp;quot; type strategy than the others, but the dopamine spike is long lasting.&lt;/p&gt;
&lt;p&gt;I&#39;ve been dabbling with cold showers recently, and have really been enjoying it. I can&#39;t explain why, but after the initial five seconds of &amp;quot;damn, that&#39;s cold!&amp;quot; I feel &lt;em&gt;good&lt;/em&gt;. It feels good to do something that involves &amp;quot;mental toughness&amp;quot; but that isn&#39;t the only aspect that&#39;s pleasant about it.&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;See &lt;a href=&quot;https://en.wikipedia.org/wiki/Third_place&quot;&gt;wikipedia&lt;/a&gt; &lt;a href=&quot;https://luciano.laratel.li/blog/mental-health-toolkit/&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;This is a huge topic on its own; I don&#39;t want to derail by getting into the 800 externalities on each side of the WFH debate. &lt;a href=&quot;https://luciano.laratel.li/blog/mental-health-toolkit/&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
	</entry>
	
	<entry>
		<title>Task ordering</title>
		<link href="https://luciano.laratel.li/blog/task-ordering/"/>
		<updated>2023-07-18T13:21:00Z</updated>
		<id>https://luciano.laratel.li/blog/task-ordering/</id>
		<content type="html">&lt;p&gt;Lily and I wear &lt;a href=&quot;https://web.archive.org/web/20230717004606/https://www.shutterstock.com/image-photo/two-invisible-dental-teeth-aligners-on-1807717714&quot;&gt;retainers&lt;/a&gt; every night. We clean them daily using a regular toothbrush and liquid hand soap. Cleaning these retainers at the end of the day, before bed, is one of my least favorite chores. I dealt with that for a long time! I would delay, put it off, getting in to bed fifteen or twenty minutes later than I would have if I would have just washed the damn things as soon as I finished flossing and brushing my teeth. For a while, I tried cleaning the retainers before the flossing and tooth brushing, but that didn&#39;t improve things. After a while I figured out a way to resolve my issue: I now clean our retainers &lt;em&gt;in the morning&lt;/em&gt;, immediately after brushing my teeth. It&#39;s the easiest thing in the world at that point in the day, but feels impossible at night.&lt;/p&gt;
&lt;p&gt;Though my issue with the nighttime retainer cleaning is probably just a classic ADHD Moment, after I got the morning thing going, it got me thinking about task ordering. It&#39;s not a novel idea that tasks have orderings. A simple example is a task where you don&#39;t have the knowledge to accomplish it yet. You can&#39;t accomplish it without getting the knowledge first. Not every ordering is &amp;quot;strict&amp;quot;, though — the retainer cleaning saga involved at least three orderings.&lt;/p&gt;
&lt;pre class=&quot;language-text hljs&quot;&gt;&lt;code class=&quot;language-text hljs&quot;&gt;floss -&gt; nighttime tooth brushing -&gt; clean retainers -&gt; get in bed&lt;br&gt;&lt;br&gt;clean retainers -&gt; floss -&gt; nighttime tooth brushing -&gt; get in bed&lt;br&gt;&lt;br&gt;wake up -&gt; random morning things -&gt; morning tooth brushing -&gt; clean retainers -&gt; [ .. the whole day .. ] -&gt; floss -&gt; nighttime tooth brushing -&gt; get in bed&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once I had noticed that, I realized I&#39;d seen variations of the concept before.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.structuredprocrastination.com/&quot;&gt;Structured Procrastination&lt;/a&gt; is well known, and one of my favorite essays of its kind. It&#39;s about ordering your tasks so that there&#39;s always something you don&#39;t want to do (but have committed to doing) at the &amp;quot;end of the list.&amp;quot;&lt;/p&gt;
&lt;p&gt;CPUs do &lt;a href=&quot;https://en.wikipedia.org/wiki/Out-of-order_execution&quot;&gt;out-of-order execution&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://charity.wtf/2017/05/11/the-engineer-manager-pendulum/&quot;&gt;The Engineer/Manager Pendulum&lt;/a&gt; is about flipping the traditional&lt;/p&gt;
&lt;pre class=&quot;language-text hljs&quot;&gt;&lt;code class=&quot;language-text hljs&quot;&gt;Start Career -&gt; IC -&gt; Management -&gt; End Career&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;order into&lt;/p&gt;
&lt;pre class=&quot;language-text hljs&quot;&gt;&lt;code class=&quot;language-text hljs&quot;&gt;Start Career -&gt; IC -&gt; Management -&gt; IC -&gt; Management -&gt; End career&lt;br&gt;                                    ↑         ↓&lt;br&gt;                                     ↖_______↙&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are algorithms that utilize &lt;a href=&quot;https://en.wikipedia.org/wiki/Amortized_analysis&quot;&gt;amortization&lt;/a&gt; to improve their average performance. C++&#39;s &lt;code&gt;std::vector&lt;/code&gt; notably &lt;a href=&quot;https://stackoverflow.com/a/5232342/5692730&quot;&gt;uses this technique&lt;/a&gt; to achieve (amortized) constant cost when growing in capacity. This is a reordering of tasks from this expensive loop:&lt;/p&gt;
&lt;pre class=&quot;language-text hljs&quot;&gt;&lt;code class=&quot;language-text hljs&quot;&gt;Make vector with capacity 1 -&gt; add item -&gt; increase capacity&lt;br&gt;                                    ↑         ↓&lt;br&gt;                                     ↖_______↙&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To one that minimizes the number of times we &lt;code&gt;increase capacity&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/DFA_minimization&quot;&gt;DFA minimization&lt;/a&gt; is an algorithm for reducing the number of states in a (deterministic and finite) automaton. We remove states if we can show they&#39;re equivalent. Now that I think about it, removal is only sort of like reordering. There&#39;s a world of difference between &amp;quot;I clean my retainers in the morning instead of at night&amp;quot; and &amp;quot;I don&#39;t clean my retainers&amp;quot;.&lt;/p&gt;
&lt;p&gt;Project management tools are all about task reordering.&lt;/p&gt;
&lt;p&gt;Task reordering isn&#39;t a magical solution. I despise washing our coffee pot and can&#39;t find a good time of day to do it. Part of the problem is that we don&#39;t use it every day; some mornings we have tea, yerba mate, or go out for coffee instead. Maybe if I worked the washing of the coffee pot into a fixed place in my daily routine, I would realize it&#39;s in the wrong place in the routine, place it correctly, and then be able to wash it as easily as I clean the retainers.&lt;/p&gt;
&lt;p&gt;Maybe part of the problem is that reordering tasks only works for low-friction tasks where the cost to start doing them is low. Some tasks are really four or five tasks dressed in a trench coat disguised as a single task, and it&#39;s not always easy to tell that from a todo list. Comparing &amp;quot;cleaning the retainers&amp;quot; to &amp;quot;washing the coffee pot&amp;quot; doesn&#39;t convey any of this context. But cleaning the retainers takes two minutes at most, while the coffee pot involves making sure there&#39;s space on the dish drying rack, ensuring there&#39;s space in the sink, putting on the dishwashing gloves, then washing the four separate pieces of the coffee pot ensemble.&lt;/p&gt;
&lt;p&gt;Those first two steps (of the single &amp;quot;washing the coffee pot&amp;quot; task!) might create a cascade of new tasks. If the dishes on the drying rack are wet, we&#39;d have to dry them then put them away. Is the sink full because the dishwasher is running? If that&#39;s the case, maybe there isn&#39;t space in the sink to wash the coffee pot. This can go on and on.&lt;/p&gt;
&lt;p&gt;Getting things done is hard, especially with executive function disorders like ADHD. Thinking about the order of tasks has helped me a great deal.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Using CLJS and shadow-cljs for serverless DigitalOcean Functions</title>
		<link href="https://luciano.laratel.li/blog/cljs-digitalocean-serverless/"/>
		<updated>2023-01-12T01:08:00Z</updated>
		<id>https://luciano.laratel.li/blog/cljs-digitalocean-serverless/</id>
		<content type="html">&lt;p&gt;DigitalOcean (DO) &lt;a href=&quot;https://www.digitalocean.com/products/functions&quot;&gt;Functions&lt;/a&gt;: &amp;quot;a serverless computing solution that runs on-demand, enabling you to focus on your code, scale instantly with confidence, and save costs by eliminating the need to maintain servers.&amp;quot; Since I&#39;m a fanatic, I would like to write some Clojure for my serverless use case. Because DO offers Node as a runtime, we&#39;re able to use ClojureScript to write code and deploy it to the serverless, er, server.&lt;/p&gt;
&lt;p&gt;Source code for this blog post is &lt;a href=&quot;https://git.sr.ht/~luciano/cljs-digitalocean-serverless-function&quot;&gt;available&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You&#39;ll need a DO account. Log in, select the appropriate team, then select &lt;code&gt;Functions&lt;/code&gt; on the left-hand column. Create a function namespace and you&#39;re ready to go.&lt;/p&gt;
&lt;p&gt;Next we need the &lt;code&gt;doctl&lt;/code&gt; binary. Here&#39;s what I did:&lt;/p&gt;
&lt;pre class=&quot;language-shell hljs&quot;&gt;&lt;code class=&quot;language-shell hljs&quot;&gt;brew install doctl&lt;br&gt;doctl auth init&lt;br&gt;doctl serverless install&lt;br&gt;doctl serverless connect&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This gets you authenticated with DO so you can deploy from the command line.&lt;/p&gt;
&lt;pre class=&quot;language-shell hljs&quot;&gt;&lt;code class=&quot;language-shell hljs&quot;&gt;npx create-cljs-project do_serverless&lt;br&gt;cd do_serverless&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, let&#39;s edit the generated &lt;code&gt;shadow.cljs&lt;/code&gt; a bit. Add this map as the value under &lt;code&gt;:builds&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-clojure hljs&quot;&gt;&lt;code class=&quot;language-clojure hljs&quot;&gt;{&lt;span class=&quot;hljs-symbol&quot;&gt;:core&lt;/span&gt; {&lt;span class=&quot;hljs-symbol&quot;&gt;:target&lt;/span&gt; &lt;span class=&quot;hljs-symbol&quot;&gt;:node-script&lt;/span&gt;&lt;br&gt;         &lt;span class=&quot;hljs-symbol&quot;&gt;:main&lt;/span&gt; core/main&lt;br&gt;         &lt;span class=&quot;hljs-symbol&quot;&gt;:output-to&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;packages/do-serverless/core/core.js&amp;quot;&lt;/span&gt;}}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create &lt;code&gt;src/main/core.cljs&lt;/code&gt; and define &lt;code&gt;main&lt;/code&gt; in it:&lt;/p&gt;
&lt;pre class=&quot;language-clojure hljs&quot;&gt;&lt;code class=&quot;language-clojure hljs&quot;&gt;(&lt;span class=&quot;hljs-name&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;ns&lt;/span&gt;&lt;/span&gt; core)&lt;br&gt;&lt;br&gt;(&lt;span class=&quot;hljs-keyword&quot;&gt;defn&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;main&lt;/span&gt; [])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create &lt;code&gt;packages/do-serverless/core/package.json&lt;/code&gt; with this in it:&lt;/p&gt;
&lt;pre class=&quot;language-json hljs&quot;&gt;&lt;code class=&quot;language-json hljs&quot;&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;core&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;&amp;quot;version&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;1.0.0&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;&amp;quot;description&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;CLJS on DO!&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;&amp;quot;main&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;core.js&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;&amp;quot;dependencies&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;&amp;quot;source-map-support&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;^0.5.21&amp;quot;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;&amp;quot;devDependencies&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lastly, create &lt;code&gt;project.yml&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-yaml hljs&quot;&gt;&lt;code class=&quot;language-yaml hljs&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;packages:&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;do-serverless&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;actions:&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;core&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;runtime:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nodejs:default&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;OK! Let&#39;s see where we&#39;re at:&lt;/p&gt;
&lt;pre class=&quot;language-shell hljs&quot;&gt;&lt;code class=&quot;language-shell hljs&quot;&gt;shadow-cljs release core&lt;br&gt;doctl serverless deploy .&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can go to the Functions tab on DO&#39;s site and run our function by first going to the function namespace, clicking on the name of the function, and hitting Run. I get this error:&lt;/p&gt;
&lt;pre class=&quot;language-txt hljs&quot;&gt;&lt;code class=&quot;language-txt hljs&quot;&gt;2023-01-12T11:14:08.172732642Z stdout: Action entrypoint &amp;#x27;main&amp;#x27; is not a function.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What tha...&lt;/p&gt;
&lt;p&gt;At this point, I dug around and found that DO maintains a bunch of sample functions. Going to the &lt;a href=&quot;https://web.archive.org/web/20220728083446/https://github.com/digitalocean/sample-functions-nodejs-qrcode/blob/main/packages/qr/qr/qr.js&quot;&gt;Node one&lt;/a&gt;, we see this:&lt;/p&gt;
&lt;pre class=&quot;language-javascript hljs&quot;&gt;&lt;code class=&quot;language-javascript hljs&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;exports&lt;/span&gt;.&lt;span class=&quot;hljs-property&quot;&gt;main&lt;/span&gt; = &lt;span class=&quot;hljs-function&quot;&gt;(&lt;span class=&quot;hljs-params&quot;&gt;args&lt;/span&gt;) =&amp;gt;&lt;/span&gt; { ... }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Huh. OK, so let&#39;s do that in our example, &lt;code&gt;src/main/core.cljs&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-clojure hljs&quot;&gt;&lt;code class=&quot;language-clojure hljs&quot;&gt;(&lt;span class=&quot;hljs-name&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;ns&lt;/span&gt;&lt;/span&gt; core)&lt;br&gt;&lt;br&gt;(&lt;span class=&quot;hljs-keyword&quot;&gt;defn&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;main&lt;/span&gt; [&amp;amp; args]&lt;br&gt;  (&lt;span class=&quot;hljs-name&quot;&gt;println&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;hello!&amp;quot;&lt;/span&gt;)&lt;br&gt;  (&lt;span class=&quot;hljs-name&quot;&gt;println&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;args: &amp;quot;&lt;/span&gt; args))&lt;br&gt;&lt;br&gt;(&lt;span class=&quot;hljs-name&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;set!&lt;/span&gt;&lt;/span&gt; js/exports.main main)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And re-build and deploy.&lt;/p&gt;
&lt;pre class=&quot;language-text hljs&quot;&gt;&lt;code class=&quot;language-text hljs&quot;&gt;2023-01-12T11:22:14.933096349Z stdout: hello!&lt;br&gt;2023-01-12T11:22:14.933797937Z stdout: args:  nil&lt;br&gt;2023-01-12T11:22:14.961195498Z stdout: hello!&lt;br&gt;2023-01-12T11:22:14.982016323Z stdout: args:  (#js {} ... // output truncated&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ok, so when our function executes, our &lt;code&gt;main&lt;/code&gt; gets executed twice. I don&#39;t know why this happens. If I run our compiled javascript file locally with &lt;code&gt;node&lt;/code&gt;, I only see one execution:&lt;/p&gt;
&lt;pre class=&quot;language-shell hljs&quot;&gt;&lt;code class=&quot;language-shell hljs&quot;&gt;&lt;span class=&quot;hljs-meta prompt_&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;language-bash&quot;&gt;node packages/do-serverless/core/core.js&lt;/span&gt;&lt;br&gt;hello!&lt;br&gt;args:  nil&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, OK, some detail that&#39;s above my head. My use case for serverless would, uh, not do well with running everything twice. So, what to do?&lt;/p&gt;
&lt;p&gt;Well, we know whatever we tell &lt;code&gt;shadow&lt;/code&gt; our &lt;code&gt;main&lt;/code&gt; is will get run. And we also know whatever we tell DO our main is (the &lt;code&gt;js/exports.main&lt;/code&gt; bit) will also run. Well, I only care about the DO side of things!&lt;/p&gt;
&lt;pre class=&quot;language-clojure hljs&quot;&gt;&lt;code class=&quot;language-clojure hljs&quot;&gt;(&lt;span class=&quot;hljs-name&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;ns&lt;/span&gt;&lt;/span&gt; core)&lt;br&gt;&lt;br&gt;(&lt;span class=&quot;hljs-keyword&quot;&gt;defn&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;my-actual-function&lt;/span&gt; [&amp;amp; args]&lt;br&gt;  (&lt;span class=&quot;hljs-name&quot;&gt;println&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;hello!&amp;quot;&lt;/span&gt;)&lt;br&gt;  (&lt;span class=&quot;hljs-name&quot;&gt;println&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;args: &amp;quot;&lt;/span&gt; args))&lt;br&gt;&lt;br&gt;(&lt;span class=&quot;hljs-keyword&quot;&gt;defn&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;main&lt;/span&gt; [])&lt;br&gt;&lt;br&gt;(&lt;span class=&quot;hljs-name&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;set!&lt;/span&gt;&lt;/span&gt; js/exports.main my-actual-function)&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-text hljs&quot;&gt;&lt;code class=&quot;language-text hljs&quot;&gt;2023-01-12T11:28:57.786063804Z stdout: hello!&lt;br&gt;2023-01-12T11:28:57.793552189Z stdout: args:  (#js {} ... // output truncated&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Neat!&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Setting up mu4e with iCloud custom domains with Doom Emacs on Arch Linux</title>
		<link href="https://luciano.laratel.li/blog/mu4e_doom_emacs/"/>
		<updated>2022-04-19T00:32:00Z</updated>
		<id>https://luciano.laratel.li/blog/mu4e_doom_emacs/</id>
		<content type="html">&lt;p&gt;Here&#39;s how I set up &lt;code&gt;mu4e&lt;/code&gt; with Doom Emacs on Arch Linux for my custom domain
hosted on iCloud. I&#39;m using &lt;code&gt;mbsync&lt;/code&gt;, &lt;code&gt;mu&lt;/code&gt;, and &lt;code&gt;msmpt&lt;/code&gt;. I originally went with
a systemd timer as detailed in the first two sections as recommended in the &lt;a href=&quot;https://wiki.archlinux.org/title/isync#Calling_mbsync_automatically&quot;&gt;Arch
wiki&lt;/a&gt;, but &lt;code&gt;mu4e&lt;/code&gt; actually has a built-in functionality to deal with this for us.
Note that what I&#39;ve written here is the &lt;em&gt;minimum&lt;/em&gt; I needed to do to actually
sync, send, and read emails from &lt;code&gt;emacs&lt;/code&gt;. There&#39;s a lot more you can do.&lt;/p&gt;
&lt;h2 id=&quot;configuration-files&quot; tabindex=&quot;-1&quot;&gt;Configuration files &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/mu4e_doom_emacs/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In &lt;code&gt;init.el&lt;/code&gt;, under &lt;code&gt;:email&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;language-lisp hljs&quot;&gt;&lt;code class=&quot;language-lisp hljs&quot;&gt;(&lt;span class=&quot;hljs-name&quot;&gt;mu4e&lt;/span&gt; +org)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;config.el&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-lisp hljs&quot;&gt;&lt;code class=&quot;language-lisp hljs&quot;&gt;(&lt;span class=&quot;hljs-name&quot;&gt;set-email-account!&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;icloud&amp;quot;&lt;/span&gt;&lt;br&gt;  &amp;#x27;((mu4e-sent-folder       . &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;/icloud/Sent&amp;quot;&lt;/span&gt;)&lt;br&gt;    (mu4e-drafts-folder     . &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;/icloud/Drafts&amp;quot;&lt;/span&gt;)&lt;br&gt;    (mu4e-trash-folder      . &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;/icloud/Trash&amp;quot;&lt;/span&gt;)&lt;br&gt;    (mu4e-refile-folder     . &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;/icloud/Archive&amp;quot;&lt;/span&gt;)&lt;br&gt;    (smtpmail-smtp-user     . &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;lucianolaratelli&amp;quot;&lt;/span&gt;)&lt;br&gt;    (mu4e-compose-signature . &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;&#92;n&#92;nLuciano&amp;quot;&lt;/span&gt;))&lt;br&gt;  &lt;span class=&quot;hljs-literal&quot;&gt;t&lt;/span&gt;)&lt;br&gt;&lt;br&gt;(&lt;span class=&quot;hljs-name&quot;&gt;after!&lt;/span&gt; mu4e&lt;br&gt;  (&lt;span class=&quot;hljs-name&quot;&gt;setq&lt;/span&gt; sendmail-program (&lt;span class=&quot;hljs-name&quot;&gt;executable-find&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;msmtp&amp;quot;&lt;/span&gt;)&lt;br&gt;        send-mail-function #&amp;#x27;smtpmail-send-it&lt;br&gt;        smtpmail-stream-type &amp;#x27;starttls&lt;br&gt;        message-sendmail-f-is-evil &lt;span class=&quot;hljs-literal&quot;&gt;t&lt;/span&gt;&lt;br&gt;        message-sendmail-extra-arguments &amp;#x27;(&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;--read-envelope-from&amp;quot;&lt;/span&gt;)&lt;br&gt;        message-send-mail-function #&amp;#x27;message-send-mail-with-sendmail))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In &lt;code&gt;$HOME/.config/system/user/mbsync.timer&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-text hljs&quot;&gt;&lt;code class=&quot;language-text hljs&quot;&gt;[Unit]&lt;br&gt;Description=Mailbox synchronization timer&lt;br&gt;&lt;br&gt;[Timer]&lt;br&gt;OnBootSec=1m&lt;br&gt;OnUnitActiveSec=5m&lt;br&gt;Unit=mbsync.service&lt;br&gt;&lt;br&gt;[Install]&lt;br&gt;WantedBy=timers.target&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;$HOME/.config/system/user/mbsync.service&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-text hljs&quot;&gt;&lt;code class=&quot;language-text hljs&quot;&gt;[Unit]&lt;br&gt;Description=Mailbox synchronization service&lt;br&gt;&lt;br&gt;[Service]&lt;br&gt;Type=oneshot&lt;br&gt;ExecStart=/usr/bin/mbsync --verbose --all&lt;br&gt;&lt;br&gt;[Install]&lt;br&gt;WantedBy=default.target&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;$HOME/.mbsyncrc&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-text hljs&quot;&gt;&lt;code class=&quot;language-text hljs&quot;&gt;# imap account information&lt;br&gt;IMAPAccount icloud&lt;br&gt;Host imap.mail.me.com&lt;br&gt;User lucianolaratelli@icloud.com&lt;br&gt;PassCmd &quot;secret-tool lookup email luciano@laratel.li&quot;&lt;br&gt;SSLType IMAPS&lt;br&gt;Port 993&lt;br&gt;&lt;br&gt;# remote storage (use the imap account specified above)&lt;br&gt;IMAPStore icloud-remote&lt;br&gt;Account icloud&lt;br&gt;&lt;br&gt;# local storage&lt;br&gt;MaildirStore icloud-local&lt;br&gt;Path ~/Dropbox/mailbox/icloud/&lt;br&gt;Inbox ~/Dropbox/mailbox/icloud*Inbox&lt;br&gt;Subfolders Verbatim&lt;br&gt;&lt;br&gt;# channel to remote storage&lt;br&gt;Channel icloud&lt;br&gt;Far :icloud-remote:&lt;br&gt;Near :icloud-local:&lt;br&gt;Patterns *&lt;br&gt;Create Near&lt;br&gt;Sync All&lt;br&gt;Expunge Both&lt;br&gt;SyncState *&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The crucial part when you&#39;re using a custom domain hosted on iCloud is to use
your &lt;strong&gt;iCloud email address&lt;/strong&gt; instead of the custom one. I thought this was a bug
with custom domains (I&#39;ve run into another one) but I called Apple&#39;s support and
they told me I needed to use the iCloud email address. You can find this on an
iPhone or iPad by going to Settings, tapping on your name up top, and tapping on
&lt;code&gt;Name, Phone Numbers, Email&lt;/code&gt;. I had &lt;code&gt;@me.com&lt;/code&gt; and &lt;code&gt;@icloud.com&lt;/code&gt; emails there. I
went with the &lt;code&gt;@icloud.com&lt;/code&gt; one. &lt;a href=&quot;https://support.apple.com/en-us/HT202304&quot;&gt;Apple&#39;s docs&lt;/a&gt; on third-party iCloud clients say
you can use just the part before the domain, but I included the whole thing just
in case. Without further ado, &lt;code&gt;$HOME/.msmptrc&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-text hljs&quot;&gt;&lt;code class=&quot;language-text hljs&quot;&gt;defaults&lt;br&gt;tls_trust_file /etc/ssl/certs/ca-certificates.crt&lt;br&gt;logfile ~/.maildir/msmtp.log&lt;br&gt;protocol smtp&lt;br&gt;&lt;br&gt;account icloud&lt;br&gt;auth on&lt;br&gt;host smtp.mail.me.com&lt;br&gt;port 587&lt;br&gt;protocol smtp&lt;br&gt;from luciano@laratel.li&lt;br&gt;user ${ICLOUD_EMAIL_ADDRESS}&lt;br&gt;passwordeval &quot;secret-tool lookup email luciano@laratel.li&quot;&lt;br&gt;tls on&lt;br&gt;tls_starttls on&lt;br&gt;&lt;br&gt;account default : icloud&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I have &lt;code&gt;tls&lt;/code&gt; and &lt;code&gt;tls_starttls&lt;/code&gt; both on. I think I only need one of these, but I
don&#39;t want to muck with testing my mail configuration to get a blog post out.
You might need one, the other, or both. Exercise for the reader!&lt;/p&gt;
&lt;p&gt;I was originally using &lt;code&gt;gpg&lt;/code&gt; as described by Erich Grunewald in his very helpful
&lt;a href=&quot;https://www.erichgrunewald.com/posts/setting-up-gmail-in-doom-emacs-using-mbsync-and-mu4e/#(optionally)-store-your-password-in-an-encrypted-file&quot;&gt;post&lt;/a&gt;, but unlocking my yubikey every five minutes became a pain and I figured my
login keychain was secure enough for my (unsophisticated) threat model.&lt;/p&gt;
&lt;h2 id=&quot;install-and-enable-packages&quot; tabindex=&quot;-1&quot;&gt;Install and enable packages &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/mu4e_doom_emacs/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;language-bash hljs&quot;&gt;&lt;code class=&quot;language-bash hljs&quot;&gt;yay mbsync&lt;br&gt;sudo pacman -S msmtp&lt;br&gt;yay mu mu4e &lt;span class=&quot;hljs-comment&quot;&gt;# impossible to find mu otherwise&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;mkdir&lt;/span&gt; -p ~/home/Dropbox/mailbox/icloud&lt;br&gt;mbsync -Va&lt;br&gt;mu init -m ~/Dropbox/mailbox --my-address luciano@laratel.li&lt;br&gt;mu index&lt;br&gt;&lt;br&gt;systemctl &lt;span class=&quot;hljs-built_in&quot;&gt;enable&lt;/span&gt; --user --now mbsync&lt;br&gt;systemctl &lt;span class=&quot;hljs-built_in&quot;&gt;enable&lt;/span&gt; --user --now mbsync.timer&lt;br&gt;&lt;br&gt;doom &lt;span class=&quot;hljs-built_in&quot;&gt;sync&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this point you can run &lt;code&gt;emacs&lt;/code&gt;, &lt;code&gt;&amp;lt;SPC&amp;gt; o m&lt;/code&gt;, and get to emailin&#39;!&lt;/p&gt;
&lt;h2 id=&quot;moving-away-from-systemd&quot; tabindex=&quot;-1&quot;&gt;Moving away from systemd &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/mu4e_doom_emacs/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This was working fine but I wasn&#39;t getting in-&lt;code&gt;emacs&lt;/code&gt; notifications when new
emails came in, even though &lt;code&gt;mbsync&lt;/code&gt; was running on schedule! So I got rid of
the &lt;code&gt;mbsync.timer&lt;/code&gt; service with &lt;code&gt;systemctl disable --now --user mbsync.timer&lt;/code&gt;. I
kept &lt;code&gt;mbsync.service&lt;/code&gt; so that my email syncs when I log in for the day. Then, in
my &lt;code&gt;config.el&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-lisp hljs&quot;&gt;&lt;code class=&quot;language-lisp hljs&quot;&gt;(&lt;span class=&quot;hljs-name&quot;&gt;after!&lt;/span&gt; mu4e (&lt;span class=&quot;hljs-name&quot;&gt;setq&lt;/span&gt; mu4e-get-mail-command &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;mbsync --verbose --all&amp;quot;&lt;/span&gt;&lt;br&gt;                   mu4e-update-interval &lt;span class=&quot;hljs-number&quot;&gt;300&lt;/span&gt;))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I restarted &lt;code&gt;emacs&lt;/code&gt; and I was good to go.&lt;/p&gt;
&lt;h2 id=&quot;resources&quot; tabindex=&quot;-1&quot;&gt;Resources &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/mu4e_doom_emacs/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Tecosaur&#39;s awe-inspiring &lt;a href=&quot;https://tecosaur.github.io/emacs-config/config.html#fetching-systemd&quot;&gt;config&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The already-mentioned &lt;a href=&quot;https://www.erichgrunewald.com/posts/setting-up-gmail-in-doom-emacs-using-mbsync-and-mu4e/#(optionally)-store-your-password-in-an-encrypted-file&quot;&gt;post&lt;/a&gt; from Erich Grunewald&lt;/li&gt;
&lt;li&gt;The Doom Emacs &lt;code&gt;mu4e&lt;/code&gt; module &lt;a href=&quot;https://github.com/hlissner/doom-emacs/tree/develop/modules/email/mu4e&quot;&gt;documentation&lt;/a&gt; (also from Tecosaur)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/kzar/davemail/blob/main/.mbsyncrc&quot;&gt;davemail&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;This &lt;a href=&quot;https://macowners.club/posts/email-emacs-mu4e-macos/#storing-trusted-root-certificates&quot;&gt;article&lt;/a&gt;, though it focuses on macOS&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>Closing Pull Requests (and Issues) on Github Without Using Github&#39;s Web UI</title>
		<link href="https://luciano.laratel.li/blog/github_merging_PRs/"/>
		<updated>2021-04-04T00:00:00Z</updated>
		<id>https://luciano.laratel.li/blog/github_merging_PRs/</id>
		<content type="html">&lt;h2 id=&quot;motivation&quot; tabindex=&quot;-1&quot;&gt;Motivation &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/github_merging_PRs/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I like to use &lt;a href=&quot;https://magit.vc/&quot;&gt;magit&lt;/a&gt; to interact with git. I wanted to figure out how exactly the command-line version of git (which &lt;code&gt;magit&lt;/code&gt; is running under the hood) interacts with pull requests on GitHub, because the workflow at my job is to make commits on feature branches, then merge them onto &lt;code&gt;develop&lt;/code&gt; following a PR (which provides time for code review.)&lt;/p&gt;
&lt;h2 id=&quot;closing-a-pr-but-not-issues&quot; tabindex=&quot;-1&quot;&gt;Closing a PR (but not issues) &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/github_merging_PRs/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&#39;m making the assumption you have a PR to merge a branch &lt;code&gt;test&lt;/code&gt; onto a branch &lt;code&gt;develop&lt;/code&gt;, with some linked issues. Here&#39;s how you close PR when you merge. Note that this doesn&#39;t close the associated issues. First, checkout your local copy of &lt;code&gt;develop&lt;/code&gt;: &lt;code&gt;b c develop&lt;/code&gt;, then and pull any changes from your remote with &lt;code&gt;F origin/develop&lt;/code&gt;. Merge &lt;code&gt;test&lt;/code&gt; into &lt;code&gt;develop&lt;/code&gt; with &lt;code&gt;m m test&lt;/code&gt;. Finally, push the changes to the remote: &lt;code&gt;p origin/develop&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;closing-the-pr-and-the-issues&quot; tabindex=&quot;-1&quot;&gt;Closing the PR and the issues &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/github_merging_PRs/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To get the issues to close, you must edit the commit message &lt;em&gt;for the merge&lt;/em&gt; with &lt;code&gt;m e test&lt;/code&gt; after checking out &lt;code&gt;develop&lt;/code&gt;. The merge commit must mention each of the issues you wish to close. I usually go for a commit message like this:&lt;/p&gt;
&lt;pre class=&quot;language-text hljs&quot;&gt;&lt;code class=&quot;language-text hljs&quot;&gt;Merge branch &#39;test&#39;&lt;br&gt;&lt;br&gt;* test:&lt;br&gt;  commit 1&lt;br&gt;&lt;br&gt;Closes #14&lt;br&gt;Closes #16&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;what-doesn-t-work&quot; tabindex=&quot;-1&quot;&gt;What doesn&#39;t work &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/github_merging_PRs/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Sadly, you can&#39;t use the PR number in the &lt;code&gt;Closes&lt;/code&gt; string to close the associated issues. You have to enumerate the issues explicitly. You also can&#39;t do &lt;code&gt;Closes #1, #2, #3&lt;/code&gt;. Each issue has to have its own closing keyword.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Generating LLVM IR For Classes Using LLVM&#39;s C++ API</title>
		<link href="https://luciano.laratel.li/blog/llvm_classes/"/>
		<updated>2020-07-03T20:13:25Z</updated>
		<id>https://luciano.laratel.li/blog/llvm_classes/</id>
		<content type="html">&lt;h2 id=&quot;introduction&quot; tabindex=&quot;-1&quot;&gt;Introduction &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/llvm_classes/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&#39;m spending my summer using LLVM to generate code for DJ, the programming language &lt;a href=&quot;https://www.cse.usf.edu/~ligatti/&quot;&gt;Dr. Ligatti&lt;/a&gt; devised for the spring 2020 Compilers course at USF. This post will demonstrate how to use LLVM&#39;s C++ API to generate LLVM IR for DJ Code that is similar to this C example:&lt;/p&gt;
&lt;pre class=&quot;language-c hljs&quot;&gt;&lt;code class=&quot;language-c hljs&quot;&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-class&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;B&lt;/span&gt; {&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-class&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;B&lt;/span&gt; *&lt;span class=&quot;hljs-title&quot;&gt;a&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; b;&lt;br&gt;};&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt; {&lt;br&gt;  &lt;span class=&quot;hljs-class&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;B&lt;/span&gt; *&lt;span class=&quot;hljs-title&quot;&gt;b&lt;/span&gt; =&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;malloc&lt;/span&gt;(&lt;span class=&quot;hljs-keyword&quot;&gt;sizeof&lt;/span&gt;(&lt;span class=&quot;hljs-keyword&quot;&gt;struct&lt;/span&gt; B));&lt;br&gt;&lt;br&gt;  b-&amp;gt;b = &lt;span class=&quot;hljs-number&quot;&gt;2020&lt;/span&gt;;&lt;br&gt;  &lt;span class=&quot;hljs-built_in&quot;&gt;printf&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;%d&#92;n&amp;quot;&lt;/span&gt;, b-&amp;gt;b);&lt;br&gt;}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this point, you may be wondering why I&#39;m not showing you a C++ example that actually uses a class. Let&#39;s try it:&lt;/p&gt;
&lt;pre class=&quot;language-cpp hljs&quot;&gt;&lt;code class=&quot;language-cpp hljs&quot;&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;cstdio&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;B&lt;/span&gt; {&lt;br&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;public&lt;/span&gt;:&lt;br&gt;  &lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; a;&lt;br&gt;  &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{ &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;2&lt;/span&gt;; }&lt;br&gt;};&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{&lt;br&gt;  B *b = &lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;B&lt;/span&gt;();&lt;br&gt;  b-&amp;gt;a = &lt;span class=&quot;hljs-number&quot;&gt;2018&lt;/span&gt;;&lt;br&gt;  &lt;span class=&quot;hljs-built_in&quot;&gt;printf&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;%d&#92;n&amp;quot;&lt;/span&gt;, b-&amp;gt;a + b-&amp;gt;&lt;span class=&quot;hljs-built_in&quot;&gt;method&lt;/span&gt;());&lt;br&gt;}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When I started working on generating classes, I noticed something in the LLVM IR for the C++ example:&lt;/p&gt;
&lt;pre class=&quot;language-llvm hljs&quot;&gt;&lt;code class=&quot;language-llvm hljs&quot;&gt;&lt;span class=&quot;hljs-variable&quot;&gt;%class.B&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; { &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; }&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;linkonce_odr&lt;/span&gt; dso_local &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;@_ZN1B6methodEv&lt;/span&gt;(&lt;span class=&quot;hljs-variable&quot;&gt;%class.B&lt;/span&gt;* &lt;span class=&quot;hljs-variable&quot;&gt;%0&lt;/span&gt;) &lt;span class=&quot;hljs-variable&quot;&gt;#4&lt;/span&gt; comdat &lt;span class=&quot;hljs-keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;2&lt;/span&gt; {&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%2&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;alloca&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%class.B&lt;/span&gt;*&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;8&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-keyword&quot;&gt;store&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%class.B&lt;/span&gt;* &lt;span class=&quot;hljs-variable&quot;&gt;%0&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%class.B&lt;/span&gt;** &lt;span class=&quot;hljs-variable&quot;&gt;%2&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;8&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%3&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%class.B&lt;/span&gt;*&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%class.B&lt;/span&gt;** &lt;span class=&quot;hljs-variable&quot;&gt;%2&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;8&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-keyword&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;2&lt;/span&gt;&lt;br&gt;}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;LLVM (and probably everyone else) separates class definitions from method declarations!&lt;/em&gt; Realizing this was a crucial moment for me; up until that point, I had been searching endlessly: &amp;quot;how does LLVM generate code for classes&amp;quot;, &amp;quot;LLVM IR class code gen&amp;quot;, &amp;quot;LLVM class generation&amp;quot;. &lt;a href=&quot;https://lists.llvm.org/pipermail/llvm-dev/2017-June/113607.html&quot;&gt;This message&lt;/a&gt; from the LLVM-dev mailing list pushed me to think in terms of how LLVM lowers &lt;em&gt;C&lt;/em&gt; to its IR, instead of C++. I realized that meant I should be looking for &lt;em&gt;struct&lt;/em&gt; methods, which were not hard to &lt;a href=&quot;http://llvm.org/doxygen/classllvm_1_1StructType.html&quot;&gt;find&lt;/a&gt;, and was finally able to get started.&lt;/p&gt;
&lt;h2 id=&quot;learning-from-clang&quot; tabindex=&quot;-1&quot;&gt;Learning From Clang &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/llvm_classes/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;My first step when trying to determine what LLVM is doing is to first use &lt;code&gt;clang&lt;/code&gt; to generate some LLVM IR for me, by running &lt;code&gt;clang -S -O0 -emit-llvm example.c&lt;/code&gt;. This outputs the LLVM IR to a file &lt;code&gt;example.ll&lt;/code&gt;, which will let us see exactly what&#39;s happening by asking &lt;code&gt;clang&lt;/code&gt; to not do any optimizations. Here&#39;s the IR for the C example above, cleaned up a bit for brevity:&lt;/p&gt;
&lt;pre class=&quot;language-llvm hljs&quot;&gt;&lt;code class=&quot;language-llvm hljs&quot;&gt;&lt;span class=&quot;hljs-variable&quot;&gt;%struct.B&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; { &lt;span class=&quot;hljs-variable&quot;&gt;%struct.B&lt;/span&gt;*&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; }&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;define&lt;/span&gt; dso_local &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;@main&lt;/span&gt;() &lt;span class=&quot;hljs-variable&quot;&gt;#0&lt;/span&gt; {&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%1&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;alloca&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%struct.B&lt;/span&gt;*&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;8&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%2&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;noalias&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;* &lt;span class=&quot;hljs-title&quot;&gt;@malloc&lt;/span&gt;(&lt;span class=&quot;hljs-type&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;16&lt;/span&gt;) &lt;span class=&quot;hljs-variable&quot;&gt;#3&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%3&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;bitcast&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;* &lt;span class=&quot;hljs-variable&quot;&gt;%2&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%struct.B&lt;/span&gt;*&lt;br&gt;  &lt;span class=&quot;hljs-keyword&quot;&gt;store&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%struct.B&lt;/span&gt;* &lt;span class=&quot;hljs-variable&quot;&gt;%3&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%struct.B&lt;/span&gt;** &lt;span class=&quot;hljs-variable&quot;&gt;%1&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;8&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%4&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%struct.B&lt;/span&gt;*&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%struct.B&lt;/span&gt;** &lt;span class=&quot;hljs-variable&quot;&gt;%1&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;8&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%5&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;getelementptr&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;inbounds&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%struct.B&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%struct.B&lt;/span&gt;* &lt;span class=&quot;hljs-variable&quot;&gt;%4&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-keyword&quot;&gt;store&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;2020&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt;* &lt;span class=&quot;hljs-variable&quot;&gt;%5&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;8&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%6&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%struct.B&lt;/span&gt;*&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%struct.B&lt;/span&gt;** &lt;span class=&quot;hljs-variable&quot;&gt;%1&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;8&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%7&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;getelementptr&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;inbounds&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%struct.B&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%struct.B&lt;/span&gt;* &lt;span class=&quot;hljs-variable&quot;&gt;%6&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%8&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt;* &lt;span class=&quot;hljs-variable&quot;&gt;%7&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;8&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%9&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; (&lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;*&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; ...) &lt;span class=&quot;hljs-title&quot;&gt;@printf&lt;/span&gt;(&lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;* &lt;span class=&quot;hljs-keyword&quot;&gt;getelementptr&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;inbounds&lt;/span&gt; ([&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;]&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; [&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;]* &lt;span class=&quot;hljs-title&quot;&gt;@.str&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;)&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%8&lt;/span&gt;)&lt;br&gt;  &lt;span class=&quot;hljs-keyword&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;br&gt;}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&#39;s walk through what&#39;s happening here.&lt;/p&gt;
&lt;p&gt;The struct declaration is in global scope, consisting of its name and the types that make it up. We create a variable of &lt;em&gt;pointer to the struct&lt;/em&gt; using &lt;code&gt;alloca&lt;/code&gt;. &lt;code&gt;malloc&lt;/code&gt; allocates space for the pointer; the pointer returned from malloc gets cast to the struct type and ends up in the variable we declared. Lastly, the &lt;a href=&quot;https://llvm.org/docs/GetElementPtr.html#what-is-dereferenced-by-gep&quot;&gt;&lt;code&gt;getelementptr&lt;/code&gt; (GEP)&lt;/a&gt; instruction gets us a pointer to a requested field (the &lt;code&gt;i32 1&lt;/code&gt; at the end there is getting the 1th field in the struct).&lt;/p&gt;
&lt;p&gt;With these steps acting as a guide, let&#39;s build an example program that will generate equivalent IR from scratch.&lt;/p&gt;
&lt;h2 id=&quot;implementation&quot; tabindex=&quot;-1&quot;&gt;Implementation &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/llvm_classes/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We&#39;ll be building a file &lt;code&gt;example.cpp&lt;/code&gt; step-by-step. I haven&#39;t included snippets that involve declaring &lt;code&gt;main&lt;/code&gt; or &lt;code&gt;printf&lt;/code&gt;, since we&#39;ve seen those before; find those in the full code listing below.&lt;/p&gt;
&lt;p&gt;After including the requisite LLVM headers and declaring any data structures, we start by allocating a struct using &lt;code&gt;StructType::create()&lt;/code&gt;. After this, we tell LLVM what members compose this struct; in our case, we have a pointer of the struct&#39;s type and an integer. &lt;code&gt;PointerType::getUnqual&lt;/code&gt; uses the default address space; we could just as easily use &lt;code&gt;PointerType::get()&lt;/code&gt; by getting the address space using &lt;code&gt;PointerType::getAddressSpace()&lt;/code&gt;, or passing &lt;code&gt;0&lt;/code&gt; to it for the default address space.&lt;/p&gt;
&lt;pre class=&quot;language-cpp hljs&quot;&gt;&lt;code class=&quot;language-cpp hljs&quot;&gt;std::map&amp;lt;std::string, StructType *&amp;gt; allocatedClasses;&lt;br&gt;allocatedClasses[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;B&amp;quot;&lt;/span&gt;] = StructType::&lt;span class=&quot;hljs-built_in&quot;&gt;create&lt;/span&gt;(TheContext, &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;B&amp;quot;&lt;/span&gt;);&lt;br&gt;std::vector&amp;lt;Type *&amp;gt; structMembers = {&lt;br&gt;    PointerType::&lt;span class=&quot;hljs-built_in&quot;&gt;getUnqual&lt;/span&gt;(allocatedClasses[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;B&amp;quot;&lt;/span&gt;]),&lt;br&gt;    Type::&lt;span class=&quot;hljs-built_in&quot;&gt;getInt32Ty&lt;/span&gt;(TheContext)};&lt;br&gt;allocatedClasses[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;B&amp;quot;&lt;/span&gt;]-&amp;gt;&lt;span class=&quot;hljs-built_in&quot;&gt;setBody&lt;/span&gt;(structMembers);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once we have a pointer to the struct&#39;s type, we can create a variable of it:&lt;/p&gt;
&lt;pre class=&quot;language-cpp hljs&quot;&gt;&lt;code class=&quot;language-cpp hljs&quot;&gt;&lt;span class=&quot;hljs-type&quot;&gt;static&lt;/span&gt; std::map&amp;lt;std::string, AllocaInst *&amp;gt; NamedValues;&lt;br&gt;NamedValues[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;] = Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateAlloca&lt;/span&gt;(&lt;br&gt;    PointerType::&lt;span class=&quot;hljs-built_in&quot;&gt;getUnqual&lt;/span&gt;(allocatedClasses[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;B&amp;quot;&lt;/span&gt;]), NamedValues[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;]);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can allocate space for a struct using &lt;code&gt;CallInst::CreateMalloc()&lt;/code&gt;. &lt;strong&gt;&lt;em&gt;Using &lt;code&gt;Builder.Insert()&lt;/code&gt; is crucial here.&lt;/em&gt;&lt;/strong&gt; You&#39;ll notice it&#39;s hidden in the &lt;code&gt;Builder.CreateStore()&lt;/code&gt; call. Some LLVM API methods that return &lt;code&gt;Instruction&lt;/code&gt;s &lt;a href=&quot;https://llvm.org/doxygen/classllvm_1_1CallInst.html#ab16e984b0e40d0ca395b70075b8ca251&quot;&gt;don&#39;t insert them for you&lt;/a&gt;!&lt;/p&gt;
&lt;pre class=&quot;language-cpp hljs&quot;&gt;&lt;code class=&quot;language-cpp hljs&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;auto&lt;/span&gt; typeSize = ConstantExpr::&lt;span class=&quot;hljs-built_in&quot;&gt;getSizeOf&lt;/span&gt;(allocatedClasses[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;B&amp;quot;&lt;/span&gt;]);&lt;br&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;auto&lt;/span&gt; I = CallInst::&lt;span class=&quot;hljs-built_in&quot;&gt;CreateMalloc&lt;/span&gt;(&lt;br&gt;    Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;GetInsertBlock&lt;/span&gt;(), Type::&lt;span class=&quot;hljs-built_in&quot;&gt;getInt64Ty&lt;/span&gt;(TheContext),&lt;br&gt;    allocatedClasses[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;B&amp;quot;&lt;/span&gt;], typeSize, &lt;span class=&quot;hljs-literal&quot;&gt;nullptr&lt;/span&gt;, &lt;span class=&quot;hljs-literal&quot;&gt;nullptr&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;);&lt;br&gt;Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateStore&lt;/span&gt;(Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;Insert&lt;/span&gt;(I), NamedValues[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;]);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once we&#39;ve allocated space, we can assign to it using the infamous GEP instruction. GEP does pointer arithmetic for us. The first zero is always required; it&#39;s dereferencing the struct pointer we get from &lt;code&gt;allocatedClasses&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-cpp hljs&quot;&gt;&lt;code class=&quot;language-cpp hljs&quot;&gt;std::vector&amp;lt;Value *&amp;gt; elementIndex = {&lt;br&gt;    ConstantInt::&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;(TheContext, &lt;span class=&quot;hljs-built_in&quot;&gt;APInt&lt;/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;)),&lt;br&gt;    ConstantInt::&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;(TheContext, &lt;span class=&quot;hljs-built_in&quot;&gt;APInt&lt;/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;))};&lt;br&gt;Value *GEP =&lt;br&gt;    Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateGEP&lt;/span&gt;(Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateLoad&lt;/span&gt;(NamedValues[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;]), elementIndex);&lt;br&gt;&lt;br&gt;Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateStore&lt;/span&gt;(ConstantInt::&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;(TheContext, &lt;span class=&quot;hljs-built_in&quot;&gt;APInt&lt;/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot;&gt;2020&lt;/span&gt;)), GEP);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we&#39;ve stored to the variable, we can read from it, using GEP again. We reuse &lt;code&gt;elementIndex&lt;/code&gt; from above.&lt;/p&gt;
&lt;pre class=&quot;language-cpp hljs&quot;&gt;&lt;code class=&quot;language-cpp hljs&quot;&gt;GEP = Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateGEP&lt;/span&gt;(Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateLoad&lt;/span&gt;(NamedValues[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;]), elementIndex);&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;auto&lt;/span&gt; loaded = Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateLoad&lt;/span&gt;(GEP);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we&#39;re done! At this point we proceed with the &lt;code&gt;printf&lt;/code&gt; calls as before, using &lt;code&gt;loaded&lt;/code&gt; as the second argument. You can check out the full IR output of this program down below.&lt;/p&gt;
&lt;h2 id=&quot;caveats&quot; tabindex=&quot;-1&quot;&gt;Caveats &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/llvm_classes/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are some differences between the LLVM IR generated by our example and &lt;code&gt;clang&lt;/code&gt;&#39;s. My struct type is just &lt;code&gt;B&lt;/code&gt;; it seems they&#39;ve prepended &lt;code&gt;struct.&lt;/code&gt; to their type name (they appear to do this for class types as well.) When &lt;code&gt;clang&lt;/code&gt; allocates, they always align. I haven&#39;t taken the time to learn how to do this yet, so the example does not align. Struct size computation is not done in the &lt;code&gt;clang&lt;/code&gt;-generated IR; mine does the computation at runtime.&lt;/p&gt;
&lt;p&gt;Beyond these, I am pretty happy with how similar they turned out! This shows how powerful LLVM&#39;s API is.&lt;/p&gt;
&lt;h2 id=&quot;changelog&quot; tabindex=&quot;-1&quot;&gt;Changelog &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/llvm_classes/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;2020-07-27&quot; tabindex=&quot;-1&quot;&gt;2020-07-27 &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/llvm_classes/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I updated the read and store operations to use &lt;a href=&quot;https://llvm.org/doxygen/classllvm_1_1IRBuilderBase.html#a8b1b619e109f326267438a91991ad27b&quot;&gt;&lt;code&gt;IRBuilder::CreateGEP&lt;/code&gt;&lt;/a&gt; instead of using &lt;code&gt;GetElementPtrInst::Create&lt;/code&gt; and then &lt;code&gt;IRBuilder::Insert&lt;/code&gt; as I did originally. This is much cleaner.&lt;/p&gt;
&lt;h2 id=&quot;full-code-listing&quot; tabindex=&quot;-1&quot;&gt;Full Code Listing &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/llvm_classes/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;c-code&quot; tabindex=&quot;-1&quot;&gt;C++ Code &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/llvm_classes/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;To compile and run this example, save it as &lt;code&gt;example.cpp&lt;/code&gt; and then run:&lt;/em&gt;&lt;/p&gt;
&lt;pre class=&quot;language-shell hljs&quot;&gt;&lt;code class=&quot;language-shell hljs&quot;&gt;clang++ `llvm-config --cxxflags --ldflags --system-libs --libs all` example.cpp&lt;br&gt;./a.out &amp;gt; example.ll&lt;br&gt;clang example.ll&lt;br&gt;./a.out&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I used &lt;code&gt;clang&lt;/code&gt; version &lt;code&gt;10.0.0-4ubuntu1&lt;/code&gt; (on x86) with version &lt;code&gt;10.0.0&lt;/code&gt; of the LLVM libraries. You can check with &lt;code&gt;clang --version&lt;/code&gt; and &lt;code&gt;llvm-config --version&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-cpp hljs&quot;&gt;&lt;code class=&quot;language-cpp hljs&quot;&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;llvm/ADT/APInt.h&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;llvm/IR/BasicBlock.h&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;llvm/IR/Function.h&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;llvm/IR/IRBuilder.h&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;llvm/IR/Module.h&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;llvm/Support/raw_ostream.h&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;map&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;memory&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;namespace&lt;/span&gt; llvm;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-type&quot;&gt;static&lt;/span&gt; LLVMContext TheContext; &lt;span class=&quot;hljs-type&quot;&gt;static&lt;/span&gt; IRBuilder&amp;lt;&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;Builder&lt;/span&gt;(TheContext);&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{&lt;br&gt;  &lt;span class=&quot;hljs-type&quot;&gt;static&lt;/span&gt; std::unique_ptr&amp;lt;Module&amp;gt; TheModule =&lt;br&gt;      std::&lt;span class=&quot;hljs-built_in&quot;&gt;make_unique&lt;/span&gt;&amp;lt;Module&amp;gt;(&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;example.cpp&amp;quot;&lt;/span&gt;, TheContext);&lt;br&gt;&lt;br&gt;  std::map&amp;lt;std::string, StructType *&amp;gt; allocatedClasses;&lt;br&gt;  allocatedClasses[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;B&amp;quot;&lt;/span&gt;] = StructType::&lt;span class=&quot;hljs-built_in&quot;&gt;create&lt;/span&gt;(TheContext, &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;B&amp;quot;&lt;/span&gt;);&lt;br&gt;  std::vector&amp;lt;Type *&amp;gt; structMembers = {&lt;br&gt;      PointerType::&lt;span class=&quot;hljs-built_in&quot;&gt;getUnqual&lt;/span&gt;(allocatedClasses[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;B&amp;quot;&lt;/span&gt;]),&lt;br&gt;      Type::&lt;span class=&quot;hljs-built_in&quot;&gt;getInt32Ty&lt;/span&gt;(TheContext)};&lt;br&gt;  allocatedClasses[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;B&amp;quot;&lt;/span&gt;]-&amp;gt;&lt;span class=&quot;hljs-built_in&quot;&gt;setBody&lt;/span&gt;(structMembers);&lt;br&gt;&lt;br&gt;  std::vector&amp;lt;Type *&amp;gt; args;&lt;br&gt;  args.&lt;span class=&quot;hljs-built_in&quot;&gt;push_back&lt;/span&gt;(Type::&lt;span class=&quot;hljs-built_in&quot;&gt;getInt8PtrTy&lt;/span&gt;(TheContext));&lt;br&gt;  FunctionType *printfType =&lt;br&gt;      FunctionType::&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;(Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;getInt32Ty&lt;/span&gt;(), args, &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;);&lt;br&gt;  Function::&lt;span class=&quot;hljs-built_in&quot;&gt;Create&lt;/span&gt;(printfType, Function::ExternalLinkage, &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;printf&amp;quot;&lt;/span&gt;,&lt;br&gt;                   TheModule.&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;());&lt;br&gt;&lt;br&gt;  FunctionType *mainType = FunctionType::&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;(Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;getInt32Ty&lt;/span&gt;(), &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;);&lt;br&gt;  Function *main = Function::&lt;span class=&quot;hljs-built_in&quot;&gt;Create&lt;/span&gt;(mainType, Function::ExternalLinkage, &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;main&amp;quot;&lt;/span&gt;,&lt;br&gt;                                    TheModule.&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;());&lt;br&gt;  BasicBlock *entry = BasicBlock::&lt;span class=&quot;hljs-built_in&quot;&gt;Create&lt;/span&gt;(TheContext, &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;entry&amp;quot;&lt;/span&gt;, main);&lt;br&gt;  Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;SetInsertPoint&lt;/span&gt;(entry);&lt;br&gt;&lt;br&gt;  &lt;span class=&quot;hljs-type&quot;&gt;static&lt;/span&gt; std::map&amp;lt;std::string, AllocaInst *&amp;gt; NamedValues;&lt;br&gt;  NamedValues[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;] = Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateAlloca&lt;/span&gt;(&lt;br&gt;      PointerType::&lt;span class=&quot;hljs-built_in&quot;&gt;getUnqual&lt;/span&gt;(allocatedClasses[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;B&amp;quot;&lt;/span&gt;]), NamedValues[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;]);&lt;br&gt;&lt;br&gt;  &lt;span class=&quot;hljs-keyword&quot;&gt;auto&lt;/span&gt; typeSize = ConstantExpr::&lt;span class=&quot;hljs-built_in&quot;&gt;getSizeOf&lt;/span&gt;(allocatedClasses[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;B&amp;quot;&lt;/span&gt;]);&lt;br&gt;  &lt;span class=&quot;hljs-keyword&quot;&gt;auto&lt;/span&gt; I = CallInst::&lt;span class=&quot;hljs-built_in&quot;&gt;CreateMalloc&lt;/span&gt;(&lt;br&gt;      Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;GetInsertBlock&lt;/span&gt;(), Type::&lt;span class=&quot;hljs-built_in&quot;&gt;getInt64Ty&lt;/span&gt;(TheContext),&lt;br&gt;      allocatedClasses[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;B&amp;quot;&lt;/span&gt;], typeSize, &lt;span class=&quot;hljs-literal&quot;&gt;nullptr&lt;/span&gt;, &lt;span class=&quot;hljs-literal&quot;&gt;nullptr&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;);&lt;br&gt;  Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateStore&lt;/span&gt;(Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;Insert&lt;/span&gt;(I), NamedValues[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;]);&lt;br&gt;&lt;br&gt;  std::vector&amp;lt;Value *&amp;gt; elementIndex = {&lt;br&gt;      ConstantInt::&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;(TheContext, &lt;span class=&quot;hljs-built_in&quot;&gt;APInt&lt;/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;)),&lt;br&gt;      ConstantInt::&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;(TheContext, &lt;span class=&quot;hljs-built_in&quot;&gt;APInt&lt;/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;))};&lt;br&gt;  Value *GEP =&lt;br&gt;      Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateGEP&lt;/span&gt;(Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateLoad&lt;/span&gt;(NamedValues[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;]), elementIndex);&lt;br&gt;&lt;br&gt;  Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateStore&lt;/span&gt;(ConstantInt::&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;(TheContext, &lt;span class=&quot;hljs-built_in&quot;&gt;APInt&lt;/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot;&gt;2020&lt;/span&gt;)), GEP);&lt;br&gt;&lt;br&gt;  GEP = Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateGEP&lt;/span&gt;(Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateLoad&lt;/span&gt;(NamedValues[&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;]), elementIndex);&lt;br&gt;&lt;br&gt;  &lt;span class=&quot;hljs-keyword&quot;&gt;auto&lt;/span&gt; loaded = Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateLoad&lt;/span&gt;(GEP);&lt;br&gt;&lt;br&gt;  &lt;span class=&quot;hljs-comment&quot;&gt;/*Set up printf arguments*/&lt;/span&gt;&lt;br&gt;  std::vector&amp;lt;Value *&amp;gt; printArgs;&lt;br&gt;  Value *formatStr = Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateGlobalStringPtr&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;%d&#92;n&amp;quot;&lt;/span&gt;);&lt;br&gt;  printArgs.&lt;span class=&quot;hljs-built_in&quot;&gt;push_back&lt;/span&gt;(formatStr);&lt;br&gt;  printArgs.&lt;span class=&quot;hljs-built_in&quot;&gt;push_back&lt;/span&gt;(loaded);&lt;br&gt;  Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateCall&lt;/span&gt;(TheModule-&amp;gt;&lt;span class=&quot;hljs-built_in&quot;&gt;getFunction&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;printf&amp;quot;&lt;/span&gt;), printArgs);&lt;br&gt;  &lt;span class=&quot;hljs-comment&quot;&gt;/*return value for `main`*/&lt;/span&gt;&lt;br&gt;  Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateRet&lt;/span&gt;(ConstantInt::&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;(TheContext, &lt;span class=&quot;hljs-built_in&quot;&gt;APInt&lt;/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;)));&lt;br&gt;  &lt;span class=&quot;hljs-comment&quot;&gt;/*Emit the LLVM IR to the console*/&lt;/span&gt;&lt;br&gt;  TheModule-&amp;gt;&lt;span class=&quot;hljs-built_in&quot;&gt;print&lt;/span&gt;(&lt;span class=&quot;hljs-built_in&quot;&gt;outs&lt;/span&gt;(), &lt;span class=&quot;hljs-literal&quot;&gt;nullptr&lt;/span&gt;);&lt;br&gt;}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;llvm-ir&quot; tabindex=&quot;-1&quot;&gt;LLVM IR &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/llvm_classes/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;pre class=&quot;language-llvm hljs&quot;&gt;&lt;code class=&quot;language-llvm hljs&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;; ModuleID = &amp;#x27;example.cpp&amp;#x27;&lt;/span&gt;&lt;br&gt;source_filename &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;example.cpp&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-variable&quot;&gt;%B&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; { &lt;span class=&quot;hljs-variable&quot;&gt;%B&lt;/span&gt;*&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; }&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-title&quot;&gt;@0&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;unnamed_addr&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;constant&lt;/span&gt; [&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;] &lt;span class=&quot;hljs-keyword&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;%d&#92;0A&lt;span class=&quot;hljs-char escape_&quot;&gt;&#92;00&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;declare&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;@printf&lt;/span&gt;(&lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;*&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; ...)&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;@main&lt;/span&gt;() {&lt;br&gt;&lt;span class=&quot;hljs-symbol&quot;&gt;entry:&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%0&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;alloca&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%B&lt;/span&gt;*&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%malloccall&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;tail&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;* &lt;span class=&quot;hljs-title&quot;&gt;@malloc&lt;/span&gt;(&lt;span class=&quot;hljs-type&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;ptrtoint&lt;/span&gt; (&lt;span class=&quot;hljs-variable&quot;&gt;%B&lt;/span&gt;* &lt;span class=&quot;hljs-keyword&quot;&gt;getelementptr&lt;/span&gt; (&lt;span class=&quot;hljs-variable&quot;&gt;%B&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%B&lt;/span&gt;* &lt;span class=&quot;hljs-keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;) &lt;span class=&quot;hljs-keyword&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i64&lt;/span&gt;))&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%1&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;bitcast&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;* &lt;span class=&quot;hljs-variable&quot;&gt;%malloccall&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%B&lt;/span&gt;*&lt;br&gt;  &lt;span class=&quot;hljs-keyword&quot;&gt;store&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%B&lt;/span&gt;* &lt;span class=&quot;hljs-variable&quot;&gt;%1&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%B&lt;/span&gt;** &lt;span class=&quot;hljs-variable&quot;&gt;%0&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%2&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%B&lt;/span&gt;*&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%B&lt;/span&gt;** &lt;span class=&quot;hljs-variable&quot;&gt;%0&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%3&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;getelementptr&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%B&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%B&lt;/span&gt;* &lt;span class=&quot;hljs-variable&quot;&gt;%2&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-keyword&quot;&gt;store&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;2020&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt;* &lt;span class=&quot;hljs-variable&quot;&gt;%3&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%4&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%B&lt;/span&gt;*&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%B&lt;/span&gt;** &lt;span class=&quot;hljs-variable&quot;&gt;%0&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%5&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;getelementptr&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%B&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%B&lt;/span&gt;* &lt;span class=&quot;hljs-variable&quot;&gt;%4&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%6&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt;* &lt;span class=&quot;hljs-variable&quot;&gt;%5&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%7&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; (&lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;*&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; ...) &lt;span class=&quot;hljs-title&quot;&gt;@printf&lt;/span&gt;(&lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;* &lt;span class=&quot;hljs-keyword&quot;&gt;getelementptr&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;inbounds&lt;/span&gt; ([&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;]&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; [&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;]* &lt;span class=&quot;hljs-title&quot;&gt;@0&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;)&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%6&lt;/span&gt;)&lt;br&gt;  &lt;span class=&quot;hljs-keyword&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;declare&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;noalias&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;* &lt;span class=&quot;hljs-title&quot;&gt;@malloc&lt;/span&gt;(&lt;span class=&quot;hljs-type&quot;&gt;i64&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;
</content>
	</entry>
	
	<entry>
		<title>Generating Calls to scanf From LLVM IR</title>
		<link href="https://luciano.laratel.li/blog/llvm_read/"/>
		<updated>2020-06-15T15:41:03Z</updated>
		<id>https://luciano.laratel.li/blog/llvm_read/</id>
		<content type="html">&lt;h2 id=&quot;introduction&quot; tabindex=&quot;-1&quot;&gt;Introduction &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/llvm_read/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&#39;m spending my summer using LLVM to generate code for DJ, the programming language &lt;a href=&quot;https://www.cse.usf.edu/~ligatti/&quot;&gt;Dr. Ligatti&lt;/a&gt; devised for the spring 2020 Compilers course at USF.&lt;/p&gt;
&lt;p&gt;DJ provides a &lt;code&gt;readNat&lt;/code&gt; function, which reads a natural number from the console and returns its value. In the course, this function was readily available in the instruction set our compilers generated (this was also devised by Dr. Ligatti.) Because &lt;code&gt;readNat&lt;/code&gt; is in this sense provided by the runtime, I had to make it available in some fashion from my LLVM-backed compiler. While this function is similar enough to &lt;a href=&quot;https://luciano.laratel.li/#/posts/Generating-Calls-to-printf-From-LLVM-IR&quot;&gt;printNat&lt;/a&gt;, it presents some added difficulty. This is due to my choice to use &lt;code&gt;scanf&lt;/code&gt; as &lt;code&gt;readNat&lt;/code&gt;&#39;s backend, which requires a memory location in which to store the value.&lt;/p&gt;
&lt;p&gt;The example below generates IR which is equivalent to the pseudocode &lt;code&gt;printNat(readNat())&lt;/code&gt;. This way, we can verify that the read succeeded!&lt;/p&gt;
&lt;h2 id=&quot;the-code&quot; tabindex=&quot;-1&quot;&gt;The code &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/llvm_read/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;language-cpp hljs&quot;&gt;&lt;code class=&quot;language-cpp hljs&quot;&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;llvm/ADT/APInt.h&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;llvm/IR/BasicBlock.h&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;llvm/IR/Function.h&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;llvm/IR/IRBuilder.h&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;llvm/IR/Module.h&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;llvm/Support/raw_ostream.h&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;memory&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;namespace&lt;/span&gt; llvm;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-type&quot;&gt;static&lt;/span&gt; LLVMContext TheContext;&lt;br&gt;&lt;span class=&quot;hljs-type&quot;&gt;static&lt;/span&gt; IRBuilder&amp;lt;&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;Builder&lt;/span&gt;(TheContext);&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{&lt;br&gt;  &lt;span class=&quot;hljs-type&quot;&gt;static&lt;/span&gt; std::unique_ptr&amp;lt;Module&amp;gt; TheModule;&lt;br&gt;&lt;br&gt;  TheModule = std::&lt;span class=&quot;hljs-built_in&quot;&gt;make_unique&lt;/span&gt;&amp;lt;Module&amp;gt;(&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;inputFile&amp;quot;&lt;/span&gt;, TheContext);&lt;br&gt;&lt;br&gt;  &lt;span class=&quot;hljs-comment&quot;&gt;/*set up the function prototype for printf and scanf*/&lt;/span&gt;&lt;br&gt;  std::vector&amp;lt;Type *&amp;gt; runTimeFuncArgs = {Type::&lt;span class=&quot;hljs-built_in&quot;&gt;getInt8PtrTy&lt;/span&gt;(TheContext)};&lt;br&gt;  &lt;span class=&quot;hljs-comment&quot;&gt;/*true specifies the function as variadic*/&lt;/span&gt;&lt;br&gt;  FunctionType *runTimeFuncType =&lt;br&gt;      FunctionType::&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;(Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;getInt32Ty&lt;/span&gt;(), runTimeFuncArgs, &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;);&lt;br&gt;&lt;br&gt;  Function::&lt;span class=&quot;hljs-built_in&quot;&gt;Create&lt;/span&gt;(runTimeFuncType, Function::ExternalLinkage, &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;printf&amp;quot;&lt;/span&gt;,&lt;br&gt;                   TheModule.&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;());&lt;br&gt;  Function::&lt;span class=&quot;hljs-built_in&quot;&gt;Create&lt;/span&gt;(runTimeFuncType, Function::ExternalLinkage, &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;scanf&amp;quot;&lt;/span&gt;,&lt;br&gt;                   TheModule.&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;());&lt;br&gt;&lt;br&gt;  &lt;span class=&quot;hljs-comment&quot;&gt;/*set up and declare main; begin inserting into it*/&lt;/span&gt;&lt;br&gt;  FunctionType *mainType = FunctionType::&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;(Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;getInt32Ty&lt;/span&gt;(), &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;);&lt;br&gt;  Function *main = Function::&lt;span class=&quot;hljs-built_in&quot;&gt;Create&lt;/span&gt;(mainType, Function::ExternalLinkage, &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;main&amp;quot;&lt;/span&gt;,&lt;br&gt;                                    TheModule.&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;());&lt;br&gt;  BasicBlock *entry = BasicBlock::&lt;span class=&quot;hljs-built_in&quot;&gt;Create&lt;/span&gt;(TheContext, &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;entry&amp;quot;&lt;/span&gt;, main);&lt;br&gt;  Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;SetInsertPoint&lt;/span&gt;(entry);&lt;br&gt;&lt;br&gt;  Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;GetInsertBlock&lt;/span&gt;()-&amp;gt;&lt;span class=&quot;hljs-built_in&quot;&gt;getParent&lt;/span&gt;();&lt;br&gt;  &lt;span class=&quot;hljs-comment&quot;&gt;/*set up scanf arguments*/&lt;/span&gt;&lt;br&gt;  Value *scanfFormat = Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateGlobalStringPtr&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;%u&amp;quot;&lt;/span&gt;);&lt;br&gt;  AllocaInst *Alloca =&lt;br&gt;      Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateAlloca&lt;/span&gt;(Type::&lt;span class=&quot;hljs-built_in&quot;&gt;getInt32Ty&lt;/span&gt;(TheContext), &lt;span class=&quot;hljs-literal&quot;&gt;nullptr&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;temp&amp;quot;&lt;/span&gt;);&lt;br&gt;  std::vector&amp;lt;Value *&amp;gt; scanfArgs = {scanfFormat, Alloca};&lt;br&gt;&lt;br&gt;  Function *theScanf = TheModule-&amp;gt;&lt;span class=&quot;hljs-built_in&quot;&gt;getFunction&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;scanf&amp;quot;&lt;/span&gt;);&lt;br&gt;  Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateCall&lt;/span&gt;(theScanf, scanfArgs);&lt;br&gt;&lt;br&gt;  &lt;span class=&quot;hljs-comment&quot;&gt;/*set up printf arguments, loading the value that was read in from Alloca*/&lt;/span&gt;&lt;br&gt;  Function *thePrintf = TheModule-&amp;gt;&lt;span class=&quot;hljs-built_in&quot;&gt;getFunction&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;printf&amp;quot;&lt;/span&gt;);&lt;br&gt;  Value *printfFormat = Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateGlobalStringPtr&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;%u&#92;n&amp;quot;&lt;/span&gt;);&lt;br&gt;  std::vector&amp;lt;Value *&amp;gt; printfArgs = {printfFormat, Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateLoad&lt;/span&gt;(Alloca)};&lt;br&gt;  Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateCall&lt;/span&gt;(thePrintf, printfArgs);&lt;br&gt;&lt;br&gt;  &lt;span class=&quot;hljs-comment&quot;&gt;/*return value for `main`*/&lt;/span&gt;&lt;br&gt;  Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateRet&lt;/span&gt;(Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateLoad&lt;/span&gt;(Alloca));&lt;br&gt;  &lt;span class=&quot;hljs-comment&quot;&gt;/*Emit the LLVM IR to the console*/&lt;/span&gt;&lt;br&gt;  TheModule-&amp;gt;&lt;span class=&quot;hljs-built_in&quot;&gt;print&lt;/span&gt;(&lt;span class=&quot;hljs-built_in&quot;&gt;outs&lt;/span&gt;(), &lt;span class=&quot;hljs-literal&quot;&gt;nullptr&lt;/span&gt;);&lt;br&gt;}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The main takeaway here is the use of the &lt;code&gt;CreateAlloca&lt;/code&gt; method to create a named value to store the value that &lt;code&gt;scanf&lt;/code&gt; reads in.&lt;/p&gt;
&lt;h3 id=&quot;compiling&quot; tabindex=&quot;-1&quot;&gt;Compiling &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/llvm_read/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I am using clang/llvm versions 10.0.0 at the time of this writing. I compile the above as &lt;code&gt;clang++ `llvm-config --cxxflags --ldflags --system-libs --libs all` test.cpp&lt;/code&gt;. When run, it generates the following IR:&lt;/p&gt;
&lt;pre class=&quot;language-llvm hljs&quot;&gt;&lt;code class=&quot;language-llvm hljs&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;; ModuleID = &amp;#x27;inputFile&amp;#x27;&lt;/span&gt;&lt;br&gt;source_filename &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;inputFile&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-title&quot;&gt;@0&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;unnamed_addr&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;constant&lt;/span&gt; [&lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;] &lt;span class=&quot;hljs-keyword&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;%u&lt;span class=&quot;hljs-char escape_&quot;&gt;&#92;00&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-title&quot;&gt;@1&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;unnamed_addr&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;constant&lt;/span&gt; [&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;] &lt;span class=&quot;hljs-keyword&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;%u&#92;0A&lt;span class=&quot;hljs-char escape_&quot;&gt;&#92;00&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;declare&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;@printf&lt;/span&gt;(&lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;*&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; ...)&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;declare&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;@scanf&lt;/span&gt;(&lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;*&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; ...)&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;@main&lt;/span&gt;() {&lt;br&gt;&lt;span class=&quot;hljs-symbol&quot;&gt;entry:&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%temp&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;alloca&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%0&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; (&lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;*&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; ...) &lt;span class=&quot;hljs-title&quot;&gt;@scanf&lt;/span&gt;(&lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;* &lt;span class=&quot;hljs-keyword&quot;&gt;getelementptr&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;inbounds&lt;/span&gt; ([&lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;]&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; [&lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;]* &lt;span class=&quot;hljs-title&quot;&gt;@0&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;)&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt;* &lt;span class=&quot;hljs-variable&quot;&gt;%temp&lt;/span&gt;)&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%1&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt;* &lt;span class=&quot;hljs-variable&quot;&gt;%temp&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%2&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; (&lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;*&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; ...) &lt;span class=&quot;hljs-title&quot;&gt;@printf&lt;/span&gt;(&lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;* &lt;span class=&quot;hljs-keyword&quot;&gt;getelementptr&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;inbounds&lt;/span&gt; ([&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;]&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; [&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;]* &lt;span class=&quot;hljs-title&quot;&gt;@1&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;)&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%1&lt;/span&gt;)&lt;br&gt;  &lt;span class=&quot;hljs-variable&quot;&gt;%3&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt;* &lt;span class=&quot;hljs-variable&quot;&gt;%temp&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;hljs-keyword&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;%3&lt;/span&gt;&lt;br&gt;}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Just like last time, we throw the output IR into a file &lt;code&gt;test.ll&lt;/code&gt; and compile it with &lt;code&gt;clang&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-shell hljs&quot;&gt;&lt;code class=&quot;language-shell hljs&quot;&gt;&lt;span class=&quot;hljs-meta prompt_&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;language-bash&quot;&gt;clang test.ll&lt;/span&gt;&lt;br&gt;warning: overriding the module target triple with x86_64-pc-linux-gnu [-Woverride-module]&lt;br&gt;1 warning generated.&lt;br&gt;&lt;span class=&quot;hljs-meta prompt_&quot;&gt;&lt;br&gt;$ &lt;/span&gt;&lt;span class=&quot;language-bash&quot;&gt;./a.out&lt;/span&gt;&lt;br&gt;4&lt;br&gt;4&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;considerations&quot; tabindex=&quot;-1&quot;&gt;Considerations &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/llvm_read/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;scanf&lt;/code&gt; is &lt;a href=&quot;https://www.quora.com/Why-is-scanf-in-C-considered-harmful-or-bad&quot;&gt;generally&lt;/a&gt; &lt;a href=&quot;https://stackoverflow.com/questions/2430303/disadvantages-of-scanf&quot;&gt;considered&lt;/a&gt; &lt;a href=&quot;https://en.wikipedia.org/wiki/Scanf_format_string#Vulnerabilities&quot;&gt;to&lt;/a&gt; &lt;a href=&quot;http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html&quot;&gt;be&lt;/a&gt; &lt;a href=&quot;https://www.quora.com/Is-using-scanf-in-C-programming-secure&quot;&gt;unsafe.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here&#39;s what happens when we feed our example a string:&lt;/p&gt;
&lt;pre class=&quot;language-shell hljs&quot;&gt;&lt;code class=&quot;language-shell hljs&quot;&gt;&lt;span class=&quot;hljs-meta prompt_&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;language-bash&quot;&gt;./a.out&lt;/span&gt;&lt;br&gt;fasd&lt;br&gt;0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And some floats:&lt;/p&gt;
&lt;pre class=&quot;language-shell hljs&quot;&gt;&lt;code class=&quot;language-shell hljs&quot;&gt;&lt;span class=&quot;hljs-meta prompt_&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;language-bash&quot;&gt;./a.out&lt;/span&gt;&lt;br&gt;2.3333333&lt;br&gt;2&lt;br&gt;&lt;span class=&quot;hljs-meta prompt_&quot;&gt;&lt;br&gt;$ &lt;/span&gt;&lt;span class=&quot;language-bash&quot;&gt;./a.out&lt;/span&gt;&lt;br&gt;2.666666666666667&lt;br&gt;2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You&#39;ll also notice the format strings for &lt;code&gt;printf&lt;/code&gt; and &lt;code&gt;scanf&lt;/code&gt; differ by a newline. I noticed that using the &lt;code&gt;printf&lt;/code&gt; format string (with the newline) for &lt;code&gt;scanf&lt;/code&gt; resulted in the following behavior:&lt;/p&gt;
&lt;pre class=&quot;language-shell hljs&quot;&gt;&lt;code class=&quot;language-shell hljs&quot;&gt;&lt;span class=&quot;hljs-meta prompt_&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;language-bash&quot;&gt;./a.out&lt;/span&gt;&lt;br&gt;2 # normal readNat input&lt;br&gt;3 # entered by me&lt;br&gt;2 # printNat output&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It&#39;s been a while since I&#39;d used &lt;code&gt;scanf&lt;/code&gt; (it&#39;s unsafe!) so I had forgotten how it deals with &lt;a href=&quot;https://stackoverflow.com/a/19499406/5692730&quot;&gt;trailing&lt;/a&gt; &lt;a href=&quot;https://stackoverflow.com/questions/41767371/scanf-and-newlines-in-c/41767965#41767965&quot;&gt;whitespace.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A solution to this would be to implement &lt;code&gt;readNat&lt;/code&gt; directly in the compiler, as suggested by the LLVM &lt;a href=&quot;https://llvm.org/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.html#full-code-listing&quot;&gt;tutorial.&lt;/a&gt; This would make it simple to implement error checking in &lt;code&gt;readNat&lt;/code&gt;. I have not done this myself; when I attempted to follow their suggestion I ran into problems calling the function from the IR and opted to find an alternate method.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Generating Calls to printf From LLVM IR</title>
		<link href="https://luciano.laratel.li/blog/llvm_print/"/>
		<updated>2020-06-03T02:22:22Z</updated>
		<id>https://luciano.laratel.li/blog/llvm_print/</id>
		<content type="html">&lt;h2 id=&quot;introduction&quot; tabindex=&quot;-1&quot;&gt;Introduction &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/llvm_print/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&#39;m spending my summer using LLVM to generate code for DJ, the programming language &lt;a href=&quot;https://www.cse.usf.edu/~ligatti/&quot;&gt;Dr. Ligatti&lt;/a&gt; devised for the spring 2020 Compilers course at USF. DJ provides a &lt;code&gt;printNat&lt;/code&gt; function, which prints a natural number to the console. In the course, this function was readily available in the instruction set our compilers generated (this was also devised by Dr. Ligatti.) Because &lt;code&gt;printNat&lt;/code&gt; is in this sense provided by the runtime, I had to make it available in some fashion from my LLVM-backed compiler. I wasn&#39;t able to succeed in doing this the way the LLVM &lt;a href=&quot;https://llvm.org/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.html&quot;&gt;Kaleidoscope&lt;/a&gt; tutorial suggests, so &lt;a href=&quot;https://stackoverflow.com/questions/35526075/llvm-how-to-implement-print-function-in-my-language&quot;&gt;after&lt;/a&gt; &lt;a href=&quot;https://the-ravi-programming-language.readthedocs.io/en/latest/ravi-jit-initial.html&quot;&gt;some&lt;/a&gt; &lt;a href=&quot;https://stackoverflow.com/questions/28168815/adding-a-function-call-in-my-ir-code-in-llvm&quot;&gt;research&lt;/a&gt;, I implemented the functionality as in the example below.&lt;/p&gt;
&lt;h2 id=&quot;the-code&quot; tabindex=&quot;-1&quot;&gt;The code &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/llvm_print/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;language-cpp hljs&quot;&gt;&lt;code class=&quot;language-cpp hljs&quot;&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;llvm/ADT/APInt.h&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;llvm/IR/BasicBlock.h&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;llvm/IR/Function.h&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;llvm/IR/IRBuilder.h&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;llvm/IR/Module.h&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;llvm/Support/raw_ostream.h&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;memory&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;namespace&lt;/span&gt; llvm;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-type&quot;&gt;static&lt;/span&gt; LLVMContext TheContext;&lt;br&gt;&lt;span class=&quot;hljs-type&quot;&gt;static&lt;/span&gt; IRBuilder&amp;lt;&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;Builder&lt;/span&gt;(TheContext);&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;{&lt;br&gt;  &lt;span class=&quot;hljs-type&quot;&gt;static&lt;/span&gt; std::unique_ptr&amp;lt;Module&amp;gt; TheModule;&lt;br&gt;  TheModule = std::&lt;span class=&quot;hljs-built_in&quot;&gt;make_unique&lt;/span&gt;&amp;lt;Module&amp;gt;(&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;inputFile&amp;quot;&lt;/span&gt;, TheContext);&lt;br&gt;  &lt;span class=&quot;hljs-comment&quot;&gt;/*Declare that printf exists and has signature int (i8*, ...)**/&lt;/span&gt;&lt;br&gt;  std::vector&amp;lt;Type *&amp;gt; args;&lt;br&gt;  args.&lt;span class=&quot;hljs-built_in&quot;&gt;push_back&lt;/span&gt;(Type::&lt;span class=&quot;hljs-built_in&quot;&gt;getInt8PtrTy&lt;/span&gt;(TheContext));&lt;br&gt;  &lt;span class=&quot;hljs-comment&quot;&gt;/*`true` specifies the function as variadic*/&lt;/span&gt;&lt;br&gt;  FunctionType *printfType =&lt;br&gt;      FunctionType::&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;(Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;getInt32Ty&lt;/span&gt;(), args, &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;);&lt;br&gt;  Function::&lt;span class=&quot;hljs-built_in&quot;&gt;Create&lt;/span&gt;(printfType, Function::ExternalLinkage, &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;printf&amp;quot;&lt;/span&gt;,&lt;br&gt;                   TheModule.&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;());&lt;br&gt;  &lt;span class=&quot;hljs-comment&quot;&gt;/*begin codegen for `main`*/&lt;/span&gt;&lt;br&gt;  FunctionType *mainType = FunctionType::&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;(Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;getInt32Ty&lt;/span&gt;(), &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;);&lt;br&gt;  Function *main = Function::&lt;span class=&quot;hljs-built_in&quot;&gt;Create&lt;/span&gt;(mainType, Function::ExternalLinkage, &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;main&amp;quot;&lt;/span&gt;,&lt;br&gt;                                    TheModule.&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;());&lt;br&gt;  BasicBlock *entry = BasicBlock::&lt;span class=&quot;hljs-built_in&quot;&gt;Create&lt;/span&gt;(TheContext, &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;entry&amp;quot;&lt;/span&gt;, main);&lt;br&gt;  Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;SetInsertPoint&lt;/span&gt;(entry);&lt;br&gt;  &lt;span class=&quot;hljs-comment&quot;&gt;/*Set up printf arguments*/&lt;/span&gt;&lt;br&gt;  std::vector&amp;lt;Value *&amp;gt; printArgs;&lt;br&gt;  Value *formatStr = Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateGlobalStringPtr&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;%d&#92;n&amp;quot;&lt;/span&gt;);&lt;br&gt;  printArgs.&lt;span class=&quot;hljs-built_in&quot;&gt;push_back&lt;/span&gt;(formatStr);&lt;br&gt;  &lt;span class=&quot;hljs-comment&quot;&gt;/*We will be printing &amp;quot;20&amp;quot;*/&lt;/span&gt;&lt;br&gt;  printArgs.&lt;span class=&quot;hljs-built_in&quot;&gt;push_back&lt;/span&gt;(ConstantInt::&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;(TheContext, &lt;span class=&quot;hljs-built_in&quot;&gt;APInt&lt;/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot;&gt;20&lt;/span&gt;)));&lt;br&gt;  Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateCall&lt;/span&gt;(TheModule-&amp;gt;&lt;span class=&quot;hljs-built_in&quot;&gt;getFunction&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;printf&amp;quot;&lt;/span&gt;), printArgs);&lt;br&gt;  &lt;span class=&quot;hljs-comment&quot;&gt;/*return value for `main`*/&lt;/span&gt;&lt;br&gt;  Builder.&lt;span class=&quot;hljs-built_in&quot;&gt;CreateRet&lt;/span&gt;(ConstantInt::&lt;span class=&quot;hljs-built_in&quot;&gt;get&lt;/span&gt;(TheContext, &lt;span class=&quot;hljs-built_in&quot;&gt;APInt&lt;/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;)));&lt;br&gt;  &lt;span class=&quot;hljs-comment&quot;&gt;/*Emit the LLVM IR to the console*/&lt;/span&gt;&lt;br&gt;  TheModule-&amp;gt;&lt;span class=&quot;hljs-built_in&quot;&gt;print&lt;/span&gt;(&lt;span class=&quot;hljs-built_in&quot;&gt;outs&lt;/span&gt;(), &lt;span class=&quot;hljs-literal&quot;&gt;nullptr&lt;/span&gt;);&lt;br&gt;}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;compiling&quot; tabindex=&quot;-1&quot;&gt;Compiling &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/llvm_print/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I am using clang/llvm versions 10.0.0 at the time of this writing. I compile the above as &lt;code&gt;clang++ `llvm-config --cxxflags --ldflags --system-libs --libs all` test.cpp&lt;/code&gt;. When run, it generates the following IR:&lt;/p&gt;
&lt;pre class=&quot;language-llvm hljs&quot;&gt;&lt;code class=&quot;language-llvm hljs&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;; ModuleID = &amp;#x27;inputFile&amp;#x27;&lt;/span&gt;&lt;br&gt;source_filename &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;inputFile&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-title&quot;&gt;@0&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;unnamed_addr&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;constant&lt;/span&gt; [&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;] &lt;span class=&quot;hljs-keyword&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;%d&#92;0A&lt;span class=&quot;hljs-char escape_&quot;&gt;&#92;00&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;declare&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;@printf&lt;/span&gt;(&lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;&#92;*&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; ...)&lt;br&gt;&lt;br&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;@main&lt;/span&gt;() {&lt;br&gt;&lt;span class=&quot;hljs-symbol&quot;&gt;entry:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-variable&quot;&gt;%0&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; (&lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;*&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; ...) &lt;span class=&quot;hljs-title&quot;&gt;@printf&lt;/span&gt;(&lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;* &lt;span class=&quot;hljs-keyword&quot;&gt;getelementptr&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;inbounds&lt;/span&gt; ([&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;]&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; [&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;]&#92;* &lt;span class=&quot;hljs-title&quot;&gt;@0&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;)&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;20&lt;/span&gt;)&lt;br&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;br&gt;}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instead of writing a whole output pass (see &lt;a href=&quot;https://llvm.org/docs/tutorial/MyFirstLanguageFrontend/LangImpl08.html&quot;&gt;here&lt;/a&gt; for that,) we can throw the output IR into a file &lt;code&gt;test.ll&lt;/code&gt; and compile it with &lt;code&gt;clang&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-shell hljs&quot;&gt;&lt;code class=&quot;language-shell hljs&quot;&gt;&lt;span class=&quot;hljs-meta prompt_&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;language-bash&quot;&gt;clang test.ll&lt;/span&gt;&lt;br&gt;warning: overriding the module target triple with x86_64-pc-linux-gnu [-Woverride-module]&lt;br&gt;1 warning generated.&lt;br&gt;&lt;span class=&quot;hljs-meta prompt_&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;language-bash&quot;&gt;./a.out&lt;/span&gt;&lt;br&gt;20&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;a-caveat-and-potential-solution&quot; tabindex=&quot;-1&quot;&gt;A caveat and potential solution &lt;a class=&quot;header-anchor&quot; href=&quot;https://luciano.laratel.li/blog/llvm_print/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Of course, a program won&#39;t only have one print statement in it! Using the example above as part of a &lt;code&gt;codegen&lt;/code&gt; method for a print statement node in your AST will result in having a new constant declared for each print statement in the program:&lt;/p&gt;
&lt;pre class=&quot;language-llvm hljs&quot;&gt;&lt;code class=&quot;language-llvm hljs&quot;&gt;...&lt;br&gt;&lt;span class=&quot;hljs-title&quot;&gt;@0&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;unnamed_addr&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;constant&lt;/span&gt; [&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;] &lt;span class=&quot;hljs-keyword&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;%d&#92;0A&lt;span class=&quot;hljs-char escape_&quot;&gt;&#92;00&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-title&quot;&gt;@1&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;unnamed_addr&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;constant&lt;/span&gt; [&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;] &lt;span class=&quot;hljs-keyword&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;%d&#92;0A&lt;span class=&quot;hljs-char escape_&quot;&gt;&#92;00&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-title&quot;&gt;@2&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;unnamed_addr&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;constant&lt;/span&gt; [&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;] &lt;span class=&quot;hljs-keyword&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;%d&#92;0A&lt;span class=&quot;hljs-char escape_&quot;&gt;&#92;00&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;hljs-title&quot;&gt;@3&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;unnamed_addr&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;constant&lt;/span&gt; [&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;] &lt;span class=&quot;hljs-keyword&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;&amp;quot;%d&#92;0A&lt;span class=&quot;hljs-char escape_&quot;&gt;&#92;00&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;br&gt;...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I haven&#39;t resolved this issue in my own code base yet. I did attempt having the &lt;code&gt;formatStr&lt;/code&gt; variable be global, but this was causing seg faults in the &lt;code&gt;CreateGlobalStringPtr&lt;/code&gt; method. It seems like the &lt;a href=&quot;https://llvm.org/docs/Passes.html#constmerge-merge-duplicate-global-constants&quot;&gt;constmerge&lt;/a&gt; transform pass handles this, but I have yet to implement any passes in my compiler beyond the one that emits object code.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Calculating System Velocities Using LAMMPS</title>
		<link href="https://luciano.laratel.li/blog/lammps-total-velocities/"/>
		<updated>2018-07-19T00:09:11Z</updated>
		<id>https://luciano.laratel.li/blog/lammps-total-velocities/</id>
		<content type="html">&lt;p&gt;For the water research I&#39;ve been doing, it is useful to get the velocity autocorrelation function, which gives the density of states of the system. Here is how I ended up doing it:&lt;/p&gt;
&lt;pre class=&quot;language-text hljs&quot;&gt;&lt;code class=&quot;language-text hljs&quot;&gt;compute 1 all property/atom vx vy vz&lt;br&gt;&lt;br&gt;compute s_v_x all reduce sum vx&lt;br&gt;variable vel_x equal c_s_v_x&lt;br&gt;fix print_vel_x all print 1 &quot;$(step) ${vel_x}&quot; file &quot;vel_x.txt&quot; screen no&lt;br&gt;&lt;br&gt;compute s_v_y all reduce sum vy&lt;br&gt;variable vel_y equal c_s_v_y&lt;br&gt;fix print_vel_y all print 1 &quot;$(step) ${vel_y}&quot; file &quot;vel_y.tyt&quot; screen no&lt;br&gt;&lt;br&gt;compute s_v_z all reduce sum vz&lt;br&gt;variable vel_z equal c_s_v_z&lt;br&gt;fix print_vel_z all print 1 &quot;$(step) ${vel_z}&quot; file &quot;vel_z.tzt&quot; screen no&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;One of the things that always trips me up in LAMMPS is the difference between using variables created by the user (e.g. &lt;code&gt;vel_x&lt;/code&gt; above) and using variables LAMMPS provides (e.g. &lt;code&gt;step&lt;/code&gt;.) When using them in, for example, a &lt;code&gt;fix print&lt;/code&gt;, user-created variables must be wrapped in curly brackets, while the LAMMPS-provided variables must be wrapped in parens.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Calculating System Dipoles Using LAMMPS</title>
		<link href="https://luciano.laratel.li/blog/lammps-system-dipole/"/>
		<updated>2018-07-10T15:23:05Z</updated>
		<id>https://luciano.laratel.li/blog/lammps-system-dipole/</id>
		<content type="html">&lt;p&gt;As part of my research in Philadelphia with Matt, we needed to calculate system dipoles using LAMMPS. We were having a lot of trouble using the provided &lt;code&gt;dipole/chunk&lt;/code&gt; compute so we went about figuring it out another way instead. This was a pain to do (could not find it anywhere on the internet, probably because everyone else is smart enough to figure out how to use &lt;code&gt;dipole/chunk&lt;/code&gt;) so here is how we ended up doing it:&lt;/p&gt;
&lt;pre class=&quot;language-text hljs&quot;&gt;&lt;code class=&quot;language-text hljs&quot;&gt;variable dipole_x atom x*q&lt;br&gt;variable dipole_y atom y*q&lt;br&gt;variable dipole_z atom z*q&lt;br&gt;#systemDipole_x&lt;br&gt;compute sD_x all reduce sum v_dipole_x&lt;br&gt;compute sD_y all reduce sum v_dipole_y&lt;br&gt;compute sD_z all reduce sum v_dipole_z&lt;br&gt;&lt;br&gt;#just in case you need only one dipole...&lt;br&gt;#variable system_dipole_x equal c_sD_x&lt;br&gt;variable total_system_dipole equal sqrt((c_sD_x*c_sD_x)+(c_sD_y*c_sD_y)+(c_sD_z*c_sD_z))&lt;br&gt;&lt;br&gt;fix get_total_system_dipole all print 1 &quot;$(step) ${total_system_dipole}&quot; file &quot;dipole.txt&quot;&lt;/code&gt;&lt;/pre&gt;
</content>
	</entry>
</feed>
