<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Siobhan Fitzpatrick</title>
    <link>https://shivfitzpatrick.com/</link>
    <description>Hi there! I am a Los Angeles based Senior Software Engineer.</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Tue, 18 Aug 2026 17:05:00 -0700</lastBuildDate>
    <atom:link href="https://shivfitzpatrick.com/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Visualizing the Lox Interpreter with D3</title>
      <link>https://shivfitzpatrick.com/posts/compilervis/</link>
      <pubDate>Tue, 18 Aug 2026 17:05:00 -0700</pubDate>
      <guid isPermaLink="true">https://shivfitzpatrick.com/posts/compilervis/</guid>
      <description>Intro As I was reading Crafting Interpreters, I had this idea pretty early on that I wanted to be able to understand what the interpreter was doing visually, step by step. There are lots of graphics in the book that demonstrate how each step connects to the next one, but you are left using your imagination if you want to see how any arbitrary piece of code is converted from the language you write to the one the computer actually knows how to execute.</description>
      <content:encoded><![CDATA[<h2 id="intro">Intro</h2>
<p>As I was reading Crafting Interpreters, I had this idea pretty early
on that I wanted to be able to understand what the interpreter was
doing visually, step by step. There are lots of graphics in the book
that demonstrate how each step connects to the next one, but you are
left using your imagination if you want to see how any arbitrary piece
of code is converted from the language you write to the one the
computer actually knows how to execute.</p>
<p>You can check it out <a href="https://shivfitzpatrick.com/visualizers/">here!</a></p>
<h2 id="how-it-works">How It Works</h2>
<p>On the Lox side I added json logs throughout each phase of the
interpretation process &ndash; logs when tokens get lexed, logs when tokens
get parsed, logs when bytecode gets generated, etc. These logs include
an index into the source code so we can trace the path each piece of
code takes as it&rsquo;s transformed all the way into bytecode instructions
to be executed. Then we build Lox to wasm and let the web app do the
rest of the work.</p>
<p>The web app uses CodeMirror to let you type in any Lox code you want,
runs it through the wasm build of the interpreter, and collects each
group of log messages to produce visualizations of each compiler phase
using D3. The lexer visualization is pretty simple; it&rsquo;s just syntax
highlighting! All we need is to produce a series of spans with the
right text and css classes attached.</p>
<p>The parser is the trickiest one. It&rsquo;s worth noting that the C version
of the Lox interpreter just generates bytecode as it parses, never
actually producing an AST data structure. Statements are parsed
recursively in a way that mirrors the AST. Each statement knows how
many children it has. We can process them linearly on the front end
and build a tree that we can then hand off to D3. This gets a little
trickier for expressions which are not parsed the same way. You can
learn more about the Pratt parsing algorithm in the book <a href="https://craftinginterpreters.com/compiling-expressions.html">here</a>, but the
takeaway for the AST visualizer is that all the nodes inside
expressions get logged backwards. We have to stop every time we see an
expression, gather up all its child nodes, and process them in a
batch. So the resulting AST visualization doesn&rsquo;t exactly mirror how
the parser works. It seemed like an acceptable simplification to me.</p>
<p>The bytecode visualizer that shows all the VM instructions generated
by each parsing step is mercifully straightforward. Since it&rsquo;s just a
list of instructions, we can just show them off in a list. It actually
looks pretty much the same as the output printed by the VM to the
console with the debug flags turned on. Likewise the stack is just a
list of items on the stack. When the VM runs the instructions, we log
the contents of the stack, so the playback visualizer can show you
what happens as the VM is instructed to jump around to different
instructions in the list.</p>
<h2 id="but-why">But Why</h2>
<p>At the beginning of <a href="https://craftinginterpreters.com/introduction.html#why-learn-this-stuff">Crafting Interpreters</a>, author Robert Nystrom muses
that compiler books often begin by pleading with readers to value
their existence. I spent a lot of time reflecting on that as I read
the book. I too felt uncertain how to justify the way I was spending
my time both reading the book and working on this project. I was
motivated only by the feeling that it&rsquo;s really cool that we can speak
to the computer in whatever way we want, that expresses our ideas the
best, because compilers exist. I was motivated to build the visualizer
like a hiker stops to take pictures along a trail, as much as to serve
any teaching purpose. Maybe AST nodes and bytecode instructions are
not as beautiful as waterfalls and vistas, but I enjoyed travelling
through them nonetheless.</p>
<p>Of course there are real world use cases for all things I learned
here. I have run into situations several times in my career where
being able to refactor code by manipulating code as data has proved
valuable. Nowadays you can delegate such tasks to an LLM, but it seems
to me that it would be better in many situations to produce a
deterministic refactoring tool with an LLM than to let the robot
refactor each line itself, leaving God knows what monstrosities hidden
throughout your codebase. Some phases of the visualizer are a lot like
debugging tools that people use every day. I also hope the visualizer
can help make compilers seem a little less scary to anyone else
interested in learning more about them.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Writing a Makefile for C Lox</title>
      <link>https://shivfitzpatrick.com/posts/clox_make/</link>
      <pubDate>Wed, 29 Oct 2025 00:00:00 -0700</pubDate>
      <guid isPermaLink="true">https://shivfitzpatrick.com/posts/clox_make/</guid>
      <description>Build systems for C Projects Coming from the ecosystems of popular interpreted platforms like Python and NodeJS, the tooling around C projects felt very unfamiliar to me. Just like with the jLox, my priority was just to pick something that works so I could move on to actually solving problems. It seemed to me based on some interneting that there are at least 3 reasonable options:&amp;#xA;make cmake meson Once again following the “I’ve used it before” principle, I decided once again to go with Make. Make is a very manual build tool that feels only slightly more sophisticated than writing a bunch of bash scripts. That said I was able to come up with a setup that addressed all of my needs and I think works pretty well for a project of this size. This post will cover some useful Makefile concepts and flags for the C compiler.</description>
      <content:encoded><![CDATA[<h2 id="build-systems-for-c-projects">Build systems for C Projects</h2>
<p>Coming from the ecosystems of popular interpreted platforms like
Python and NodeJS, the tooling around C projects felt very unfamiliar
to me. Just like with the jLox, my priority was just to pick something
that works so I could move on to actually solving problems. It seemed
to me based on some interneting that there are at least 3 reasonable
options:</p>
<ul>
<li>make</li>
<li>cmake</li>
<li>meson</li>
</ul>
<p>Once again following the &ldquo;I&rsquo;ve used it before&rdquo; principle, I decided
once again to go with Make. Make is a very manual build tool that
feels only slightly more sophisticated than writing a bunch of bash
scripts. That said I was able to come up with a setup that addressed
all of my needs and I think works pretty well for a project of this
size. This post will cover some useful Makefile concepts and flags for
the C compiler.</p>
<h2 id="choosing-a-c-compiler">Choosing a C compiler</h2>
<p>Once again, we have a couple of choices. Working on a Linux system I
narrowed it down to two choices:</p>
<ul>
<li>gcc</li>
<li>clang</li>
</ul>
<p>While gcc seems to be the default on Linux I used clang because the
error messages seemed slightly better. I can only guarantee that I
tested all the command line flags described in this post with clang
but this information should apply to gcc as well.</p>
<h2 id="project-organization">Project Organization</h2>
<p>Before I go into detail about the build process I landed on, let&rsquo;s
talk about the goals. Here&rsquo;s the way I wanted the project laid out:</p>
<p>Goals:</p>
<ul>
<li>compile binaries to bin</li>
<li>support building additional binaries from additional entry points in
case you want to build toy programs that play around with pieces of
the library</li>
<li>separate src/lib directory to keep entry points and lib files apart</li>
<li>compile debug binary with debug flags turned on</li>
<li>build and run lox with a single command</li>
<li>pass command line args to lox when running it through the build tool</li>
</ul>
<p>The rest of this post explains how to set this up.</p>
<h2 id="compiling-c-programs-with-clang">Compiling C programs with clang</h2>
<p>Installing clang should be pretty straightforward if it&rsquo;s not
installed already.</p>
<p>From there all you need to do is point it at a src
file like so:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>clang src/main.c
</span></span></code></pre></div><p>This is going to output your binary to a file called&hellip; a.out. So
obviously we&rsquo;re gonna want to do something about that.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>clang -o bin/lox src/main.c
</span></span></code></pre></div><p>That&rsquo;s great until you need to start breaking up main.c into multiple
files. Clang will not automatically compile anything just because you
<code>#include</code> it. Now you&rsquo;ve got something like:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>clang -o bin/lox src/main.c src/vm.c src/compiler.c
</span></span></code></pre></div><p>This is the point where I no longer want to function without a task runner</p>
<h2 id="makefile-tasks">Makefile tasks</h2>
<p>You&rsquo;ve probaby called <code>make install</code> to build and install an open
source package before. It&rsquo;s pretty ubiquitous. That said you don&rsquo;t
really need any prior experience to get started.</p>
<p>Writing your first task is as simple as this:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-make" data-lang="make"><span style="display:flex;"><span><span style="color:#a6e22e">clox</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>        clang -o bin/lox src/main.c src/vm.c src/compiler.c
</span></span></code></pre></div><p>Important note here: oftentimes when you are programming it does not
matter whether you use tabs or spaces to indent. This is not the case
for Makefiles. Make will blow up if you use spaces, you have to use tabs.</p>
<p>So now we&rsquo;ve got a task that builds the program and you can just keep
adding your modules one by one to this list if you want.</p>
<h2 id="task-dependencies">Task dependencies</h2>
<p>Just like with gradle we can use task dependencies to ensure that
prerequisite tasks run first. We&rsquo;ll take advantage of that to add a
<code>run</code> task that will make sure your build is up to date before runing lox.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>clox:
</span></span><span style="display:flex;"><span>        clang -o bin/lox src/main.c src/vm.c src/compiler.c
</span></span><span style="display:flex;"><span>run: clox
</span></span><span style="display:flex;"><span>        bin/lox
</span></span></code></pre></div><h2 id="clang-include-flags">Clang include flags</h2>
<p>At the point I want to move all of the additional lib files into a
src/lib directory. From my perspective it makes sense to just pile
everything at the top level of the project. Instructing the compiler
to grab things from src/lib is not an issue. This will work just fine.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>clox:
</span></span><span style="display:flex;"><span>        clang -o bin/lox src/main.c src/lib/vm.c src/lib/compiler.c
</span></span><span style="display:flex;"><span>run: clox
</span></span><span style="display:flex;"><span>        bin/lox
</span></span></code></pre></div><p>The problem is that now you need to update all your includes.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-C" data-lang="C"><span style="display:flex;"><span><span style="color:#75715e">/* #include &#34;vm.h&#34; */</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&#34;lib/vm.h&#34;</span><span style="color:#75715e">
</span></span></span></code></pre></div><p>Under normal circumstances this would also be fine. However this
project has a weird constraint: you may want to copy code directly
from the book unedited. Even if you are typing everything by hand for
better memory retention, it&rsquo;s a pretty useful troubleshooting tool to
be able to keep copypasting to verify that you mistyped
something. Fortunately clang supports a command line flag that adds
directories to the include path so we can both put the files where we
want and include them how we want. It could be argued this is a little
hacky but this solution made the codebase the most comfortable for me
to work in. Just place add an argument prefix the directory you want
to add with <code>-I</code> and you can keep the includes in your C code exactly
they way they&rsquo;re written in the book.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-make" data-lang="make"><span style="display:flex;"><span><span style="color:#a6e22e">clox</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>        clang -Isrc/lib -o bin/lox src/main.c src/lib/vm.c src/lib/compiler.c
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">run</span><span style="color:#f92672">:</span> clox
</span></span><span style="display:flex;"><span>        bin/lox
</span></span></code></pre></div><h2 id="clang-macro-flags">Clang Macro flags</h2>
<p>A couple chapters in the author defines a macro that toggles logging
of vm instructions as they get processed.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-C" data-lang="C"><span style="display:flex;"><span><span style="color:#75715e">#define DEBUG_TRACE_EXECUTION
</span></span></span></code></pre></div><p>As the author states, this is only for debugging purposes, end users
wouldn&rsquo;t want all of this dumped into the console while they work. If
you want you can just comment and uncomment this as necessary. A
better solution is to use make tasks to create a different
build. Clang makes this easy with define flags that let you define or
undefine macros. Comment out the debug flags in your code, and pass
the name of your macro prefixed with <code>-D</code> to clang when you invoke it
in your make task.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-make" data-lang="make"><span style="display:flex;"><span><span style="color:#a6e22e">clox</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>        clang -Isrc/lib -o bin/lox src/main.c src/lib/vm.c src/lib/compiler.c
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">run</span><span style="color:#f92672">:</span> clox
</span></span><span style="display:flex;"><span>        bin/lox
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">clox-debug</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>        clang -DDEBUG_TRACE_EXECUTION -Isrc/lib -o bin/lox-debug src/main.c src/lib/vm.c src/lib/compiler.c
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">run-debug</span><span style="color:#f92672">:</span> clox-debug
</span></span><span style="display:flex;"><span>        bin/lox-debug
</span></span></code></pre></div><h2 id="variables-and-wildcards-in-makefiles">Variables and wildcards in Makefiles</h2>
<p>Listing out the library files is already pretty inconvenient, but now
the list has been duplicated. Ideally we could automatically grab
every file in src/lib and pass it to the compiler for every entry
point. First let&rsquo;s solve the duplication problem by adding a variable
to the Makefile.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-make" data-lang="make"><span style="display:flex;"><span>LIB<span style="color:#f92672">=</span>src/lib/vm.c src/lib/compiler.c
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">clox</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>        clang -Isrc/lib -o bin/lox src/main.c <span style="color:#66d9ef">$(</span>LIB<span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">run</span><span style="color:#f92672">:</span> clox
</span></span><span style="display:flex;"><span>        bin/lox
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">clox-debug</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>        clang -DDEBUG_TRACE_EXECUTION -Isrc/lib -o bin/lox-debug src/main.c <span style="color:#66d9ef">$(</span>LIB<span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">run-debug</span><span style="color:#f92672">:</span> clox-debug
</span></span><span style="display:flex;"><span>        bin/lox-debug
</span></span></code></pre></div><p>This is already a pretty big improvement. Let&rsquo;s move some more of the
arguments to clang into variables.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-make" data-lang="make"><span style="display:flex;"><span>APP<span style="color:#f92672">=</span>src/main.c
</span></span><span style="display:flex;"><span>LIB<span style="color:#f92672">=</span>src/lib/vm.c src/lib/compiler.c
</span></span><span style="display:flex;"><span>FLAGS<span style="color:#f92672">=</span>-Isrc/lib
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>DEBUG_FLAGS<span style="color:#f92672">=</span>-DDEBUG_TRACE_EXECUTION
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>OUTPUT<span style="color:#f92672">=</span>bin/lox
</span></span><span style="display:flex;"><span>OUTPUT_DEBUG<span style="color:#f92672">=</span>bin/lox
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">clox</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>        clang -o <span style="color:#66d9ef">$(</span>OUTPUT<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>FLAGS<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>LIB<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>APP<span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">run</span><span style="color:#f92672">:</span> clox
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">$(</span>OUTPUT<span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">clox-debug</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>        clang -o <span style="color:#66d9ef">$(</span>OUTPUT_DEBUG<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>DEBUG_FLAGS<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>FLAGS<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>LIB<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>APP<span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">run-debug</span><span style="color:#f92672">:</span> clox-debug
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">$(</span>OUTPUT_DEBUG<span style="color:#66d9ef">)</span>
</span></span></code></pre></div><p>This is in my opinion much cleaner and easier to configure. Now use a
wildcard so we can finally avoid listing out all the library files.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-make" data-lang="make"><span style="display:flex;"><span>APP<span style="color:#f92672">=</span>src/main.c
</span></span><span style="display:flex;"><span>LIB<span style="color:#f92672">=</span><span style="color:#66d9ef">$(</span>wildcard src/lib/*.c<span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span>FLAGS<span style="color:#f92672">=</span>-Isrc/lib
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>DEBUG_FLAGS<span style="color:#f92672">=</span>-DDEBUG_TRACE_EXECUTION
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>OUTPUT<span style="color:#f92672">=</span>bin/lox
</span></span><span style="display:flex;"><span>OUTPUT_DEBUG<span style="color:#f92672">=</span>bin/lox
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">clox</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>        clang -o <span style="color:#66d9ef">$(</span>OUTPUT<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>FLAGS<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>LIB<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>APP<span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">run</span><span style="color:#f92672">:</span> clox
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">$(</span>OUTPUT<span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">clox-debug</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>        clang -o <span style="color:#66d9ef">$(</span>OUTPUT_DEBUG<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>DEBUG_FLAGS<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>FLAGS<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>LIB<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>APP<span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">run-debug</span><span style="color:#f92672">:</span> clox-debug
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">$(</span>OUTPUT_DEBUG<span style="color:#66d9ef">)</span>
</span></span></code></pre></div><h2 id="passing-through-command-line-arguments">Passing through command line arguments</h2>
<p>The lox binary can take a filename as a command line argument. We&rsquo;ll
need to update the Makefile a bit so that we can pass arguments to lox
when we invoke it with make. We can define define a new variable at
the top of the file called ARGS.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-make" data-lang="make"><span style="display:flex;"><span>ARGS <span style="color:#f92672">?=</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>APP<span style="color:#f92672">=</span>src/main.c
</span></span><span style="display:flex;"><span>LIB<span style="color:#f92672">=</span><span style="color:#66d9ef">$(</span>wildcard src/lib/*.c<span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span>FLAGS<span style="color:#f92672">=</span>-Isrc/lib
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>DEBUG_FLAGS<span style="color:#f92672">=</span>-DDEBUG_TRACE_EXECUTION
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>OUTPUT<span style="color:#f92672">=</span>bin/lox
</span></span><span style="display:flex;"><span>OUTPUT_DEBUG<span style="color:#f92672">=</span>bin/lox
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">clox</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>        clang -o <span style="color:#66d9ef">$(</span>OUTPUT<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>FLAGS<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>LIB<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>APP<span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">run</span><span style="color:#f92672">:</span> clox
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">$(</span>OUTPUT<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>ARGS<span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">clox-debug</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>        clang -o <span style="color:#66d9ef">$(</span>OUTPUT_DEBUG<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>DEBUG_FLAGS<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>FLAGS<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>LIB<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>APP<span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">run-debug</span><span style="color:#f92672">:</span> clox-debug
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">$(</span>OUTPUT_DEBUG<span style="color:#66d9ef">)</span> <span style="color:#66d9ef">$(</span>ARGS<span style="color:#66d9ef">)</span>
</span></span></code></pre></div><p>The ?= in <code>ARGS ?=</code> allows conditional assignment, so it will default
to vars passed on the command line if they are available. Leaving the
right side blank assigns an empty string. Now you can invoke the run
task with an argument like this:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>make run ARGS<span style="color:#f92672">=</span>demo_program.lox
</span></span></code></pre></div><h2 id="conclusion">Conclusion</h2>
<p>Now we&rsquo;ve got a pretty functional setup. From here adding new tasks
for tests etc. is pretty straightforward, and so is adding new flags.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Crafting an Interpreter in C</title>
      <link>https://shivfitzpatrick.com/posts/c_language/</link>
      <pubDate>Sun, 26 Oct 2025 00:00:00 -0700</pubDate>
      <guid isPermaLink="true">https://shivfitzpatrick.com/posts/c_language/</guid>
      <description>Crafting an Interpreter in C The second half of Crafting Interpreters implements a new interpreter in C. As a high school student I was gifted the canonical text on C, “The C Programming Language”, (nicknamed K&amp;amp;R after the authors Brian Kernighan and Dennis Ritchie). I bounced off of it pretty hard. It’s been a gratifying experience to take another shot at learning the language.&amp;#xA;Resources for Learning C Coming from Javascript or Python, Java is, in my opinion, pretty easy to understand. It’s a little verbose but the semantics were ultimately familiar1. However with C there were a few fundamental language features used frequently in the book that required me to dedicate some attention to learning them before I could be productive writing C myself vs just copying code out of the book. I resorted to using good old fashioned books to brush up on those features and that’s what I would recommend if you’re in the same boat.</description>
      <content:encoded><![CDATA[<h2 id="crafting-an-interpreter-in-c">Crafting an Interpreter in C</h2>
<p>The second half of Crafting Interpreters implements a new interpreter
in C. As a high school student I was gifted the canonical text on C,
&ldquo;The C Programming Language&rdquo;, (nicknamed K&amp;R after the authors Brian
Kernighan and Dennis Ritchie). I bounced off of it pretty hard. It&rsquo;s
been a gratifying experience to take another shot at learning the
language.</p>
<h2 id="resources-for-learning-c">Resources for Learning C</h2>
<p>Coming from Javascript or Python, Java is, in my opinion, pretty easy
to understand. It&rsquo;s a little verbose but the semantics were ultimately
familiar<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>. However with C there were a few
fundamental language features used frequently in the book that
required me to dedicate some attention to learning them before I could
be productive writing C myself vs just copying code out of the book. I
resorted to using good old fashioned books to brush up on those
features and that&rsquo;s what I would recommend if you&rsquo;re in the same boat.</p>
<p>My primary recommendation is &ldquo;Modern C&rdquo; by Jens Gustedt. Best
practices for C and indeed the language itself have evolved over the
decades since K&amp;R was written. &ldquo;Modern C&rdquo; is also organized into
sections for people with different experience levels sometimes
covering the same language concept more than once in more depth each
time. I think it&rsquo;s very well organized for someone who wants to try
and grab the language features she needs as quickly as possible at
exactly the level of depth she needs at the moment.</p>
<p>The most famous book about C is the aforementioned K&amp;R. I do think
that this book is a really fascinating document. You can learn a lot
about the mindset the authors of C had when the wrote it. While it&rsquo;s
definitely worth reading, I don&rsquo;t think this is the best book for
learning C today. It&rsquo;s a great supplement to &ldquo;Modern C&rdquo; and I&rsquo;ve known
a few people who love the teaching style in this book.</p>
<h2 id="a-few-features-and-concepts">A Few Features and Concepts</h2>
<p>Here&rsquo;s a quick survey of some of the things I needed to look up to get
productive working through the exercises and extending the codebase.</p>
<h3 id="pointers-and-memory-allocation">Pointers and Memory Allocation</h3>
<p>This is where C deviates the most heavily from other languages. C
gives you basically one type of usable collection: fixed
sized arrays<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>. Other types of
collections like growable array lists and stacks are built on top of
pointers and memory allocation. If you&rsquo;re not familiar with these
features you will probably want to dedicate some time to brushing up
on this. &ldquo;Modern C&rdquo; and K&amp;R both cover this in a lot of detail and I
used both to improve my understanding.</p>
<h3 id="the-stack-and-the-heap">The Stack and the Heap<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup></h3>
<p>Learning C it can be helpful to understand a little terminology about
two different ways C programs store their variables in memory: stack
memory and heap memory. You don&rsquo;t necessarily need to understand how
they work in depth to use the language, but stack memory and heap
memory are referenced frequently in teaching materials about C. When
you implement C Lox you&rsquo;ll actually see analogous concepts used to
manage the data in Lox programs too.</p>
<h4 id="stack-memory">Stack Memory</h4>
<p>Variables that you declare in your functions have a fixed size and
they go on the stack. Integers, fixed length strings and array,
pointers to addresses. The compiler knows at compile time how much
space each function call will need from the stack (except for
variable-length arrays, which are outside the scope of this article).</p>
<h4 id="heap-memory">Heap Memory</h4>
<p>When you allocate memory with <code>malloc</code> or <code>realloc</code> that goes on the
heap. The heap can grow as you ask for more and more memory. This is the
memory you&rsquo;re worried about when you&rsquo;re learning about memory
management in C and the memory that would most likely be responsible
for memory leaks.</p>
<h3 id="function-pointers">Function Pointers</h3>
<p>In Javascript and Python you can store functions in variables and pass
them around. The analogous feature in C is the function pointer. These
are used pretty heavily in the parser code in cLox to delegate to
different functions when different operators show up in expressions. I
found the syntax a little odd so it&rsquo;s worth reading more about them
for that reason, but I think they&rsquo;re otherwise pretty intuitive.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Maybe the comparison is unfair as I did have a little
experience using Java on the job&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>There is a such a thing as variable length arrays but
they are actually not growable like you may expect and they are an
optional feature for C compilers in the current standards. Crafting
Interpreters does not use them and neither do I.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p>I found the explanation from the <a href="https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html#the-stack-and-the-heap">Rust Book</a> about Stack and Heap memory to be really helpful even though it&rsquo;s not technically talking about C.&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Testing Java Lox with jUnit</title>
      <link>https://shivfitzpatrick.com/posts/junit/</link>
      <pubDate>Thu, 15 May 2025 19:39:00 -0700</pubDate>
      <guid isPermaLink="true">https://shivfitzpatrick.com/posts/junit/</guid>
      <description>This is the 3rd and final post about getting set up to use Java for the book Crafting Interpreters. If you are going through a book like Crafting Interpreters and just input the code from the book and run it, maybe you don’t need tests. I would argue you are probably not going to learn the material very well. Writing tests on its own will help build your understanding of the code the book is explaining to you, but the real point of adding unit tests is to support doing the exercises. I am not going to bother explaining the value of unit tests or test driven development in general, but I think it’s worth highlighting that the value of unit tests is particularly clear when you are refactoring and extending an existing codebase (which is basically what you are doing when you implement the features from the exercises).</description>
      <content:encoded><![CDATA[<p>This is the 3rd and final post about getting set up to use Java for
the book Crafting Interpreters. If you are going through a book like
Crafting Interpreters and just input the code from the book and run
it, maybe you don&rsquo;t need tests. I would argue you are probably not
going to learn the material very well. Writing tests on its own will
help build your understanding of the code the book is explaining to
you, but the real point of adding unit tests is to support doing the
exercises. I am not going to bother explaining the value of unit tests
or test driven development in general, but I think it&rsquo;s worth
highlighting that the value of unit tests is particularly clear when
you are refactoring and extending an existing codebase (which is
basically what you are doing when you implement the features from the
exercises).</p>
<p>This is a quick guide to the features from jUnit I used to test
jLox. I used the bare minimum number of concepts I felt that I needed
to write tests effectively, so this is not a comprehensive guide to
jUnit, and not necessarily following best practices. I wrote most of
my tests as integration tests once the full interpreter stack was
available: feeding Lox code to the interpreter and using print
statements to test the output. If I was implementing a real
interpreter I would do a much more careful job testing the individual
components with unit tests, but those integration tests were good
enough to help debug issues that I inevitably introduced.</p>
<h2 id="test-cases">Test Cases</h2>
<p>Test cases are placed in a test directory that sits next to
main. Inside it has a directory structure that mirrors main. Tests
should be placed in directories mirroring the files they test.</p>
<p>e.g. <code>app/src/test/java/com/craftinginterpreters/lox/InterpreterTest.java</code></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> com.craftinginterpreters.lox;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.junit.Test;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">InterpreterTest</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">@Test</span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">testStuff</span>() {}
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h2 id="assertions">Assertions</h2>
<p>jUnit comes with a bunch of different types of assertions. I only used
a few. They are all pretty self explanatory. Check out the docs for a
list of assertion methods available to you:
<a href="https://junit.org/junit4/javadoc/4.8/org/junit/Assert.html">https://junit.org/junit4/javadoc/4.8/org/junit/Assert.html</a></p>
<p><code>app/src/test/java/com/craftinginterpreters/lox/InterpreterTest.java</code></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> com.craftinginterpreters.lox;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.junit.Test;
</span></span><span style="display:flex;"><span><span style="color:#f92672">import static</span> org.junit.Assert.*;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">InterpreterTest</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">@Test</span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">testAsserts</span>() {
</span></span><span style="display:flex;"><span>        assertEquals(<span style="color:#e6db74">&#34;true equals true&#34;</span>, <span style="color:#66d9ef">true</span>, <span style="color:#66d9ef">true</span>);
</span></span><span style="display:flex;"><span>        assertTrue(<span style="color:#e6db74">&#34;true is true&#34;</span>, <span style="color:#66d9ef">true</span>);
</span></span><span style="display:flex;"><span>        assertNotNull(<span style="color:#e6db74">&#34;true is not null&#34;</span>, <span style="color:#66d9ef">true</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h2 id="testing-exceptions">Testing Exceptions</h2>
<p>I used one more type of assertion that I thought deserves a little
attention. <code>assertThrows</code> allows you to test methods that throw
exceptions by passing it a lambda.</p>
<p><code>app/src/test/java/com/craftinginterpreters/lox/InterpreterTest.java</code></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> com.craftinginterpreters.lox;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.junit.Test;
</span></span><span style="display:flex;"><span><span style="color:#f92672">import static</span> org.junit.Assert.*;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> java.lang.UnsupportedOperationException;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">InterpreterTest</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">@Test</span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">testException</span>() {
</span></span><span style="display:flex;"><span>        UnsupportedOperationException exception <span style="color:#f92672">=</span>
</span></span><span style="display:flex;"><span>            assertThrows(UnsupportedOperationException.<span style="color:#a6e22e">class</span>, () <span style="color:#f92672">-&gt;</span> {
</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">throw</span> <span style="color:#66d9ef">new</span> UnsupportedOperationException(<span style="color:#e6db74">&#34;Not implemented&#34;</span>);
</span></span><span style="display:flex;"><span>            });
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        assertEquals(<span style="color:#e6db74">&#34;Not implemented&#34;</span>, exception.<span style="color:#a6e22e">getMessage</span>());
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h2 id="print-output">Print output</h2>
<p>Once you have the interpreter set up, I found that the easiest way to
test output from the system was to call the built-in Lox function
print, and then check that the correct strings were sent to standard
output. It turns out it&rsquo;s pretty easy to capture the standard output
and test it with jUnit.</p>
<p><code>app/src/test/java/com/craftinginterpreters/lox/InterpreterTest.java</code></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">import</span> java.io.ByteArrayOutputStream;
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> java.io.PrintStream;
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> java.util.List;
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.junit.Test;
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.junit.Before;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">InterpreterTest</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">final</span> PrintStream standardOut <span style="color:#f92672">=</span> System.<span style="color:#a6e22e">out</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">final</span> ByteArrayOutputStream outputStreamCaptor <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> ByteArrayOutputStream();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">@Before</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">setUp</span>() {
</span></span><span style="display:flex;"><span>        System.<span style="color:#a6e22e">setOut</span>(<span style="color:#66d9ef">new</span> PrintStream(outputStreamCaptor));
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">@Test</span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">testPrint</span>() {
</span></span><span style="display:flex;"><span>        System.<span style="color:#a6e22e">out</span>.<span style="color:#a6e22e">println</span>(<span style="color:#e6db74">&#34;lol&#34;</span>);
</span></span><span style="display:flex;"><span>        assertEquals(<span style="color:#e6db74">&#34;lol&#34;</span>, outputStreamCaptor.<span style="color:#a6e22e">toString</span>().<span style="color:#a6e22e">trim</span>());
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>I got most of this information from here if you are curious:
<a href="https://www.baeldung.com/java-testing-system-out-println">https://www.baeldung.com/java-testing-system-out-println</a></p>
<h2 id="focusing-a-test-case">Focusing a Test case</h2>
<p>If you only want to run a single test case (especially useful if you
are doing print debugging and drowning in output!), you can easily do
that by passing a command line argument. If you are not using gradle,
I assume it&rsquo;s pretty similar:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>./gradlew test --tests InterpreterTest.testPrint
</span></span></code></pre></div><h2 id="setting-up-a-mock-clock">Setting up a Mock Clock</h2>
<p>At some point Crafting Interpreters will have you implement a clock
function that grabs the system time and converts it to seconds. As I
struggled to find a way to override and mock out
<code>System.currentTimeMillis()</code>, I realized that instead I could just set
up the interpreter to accept a clock object as a constructor argument
(defaulting to the system clock if none is provided), so I could use a
mock clock in the tests. This is kinda overkill, but if you wanted to
have this in your life here are the clock classes I used to set that
up. Just create an instance of whichever clock and call
<code>clock.getCurrentTimeSeconds()</code> instead of calling
<code>System.currentTimeMillis()</code> directly inside the interpreter
code. Inside your tests pass a <code>TestClock</code> to your interpreter, and
then you can control the time with <code>tick()</code>.</p>
<p><code>app/src/main/java/com/craftinginterpreters/lox/LoxClock.java</code></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> com.craftinginterpreters.lox;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> java.util.List;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">LoxClock</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">double</span> <span style="color:#a6e22e">getCurrentTimeSeconds</span>();
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><code>app/src/main/java/com/craftinginterpreters/lox/SystemClock.java</code></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> com.craftinginterpreters.lox;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> java.util.List;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">SystemClock</span> <span style="color:#66d9ef">implements</span> LoxClock {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">double</span> <span style="color:#a6e22e">getCurrentTimeSeconds</span>() {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> (<span style="color:#66d9ef">double</span>) System.<span style="color:#a6e22e">currentTimeMillis</span>() <span style="color:#f92672">/</span> 1000.<span style="color:#a6e22e">0</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><code>app/src/main/java/com/craftinginterpreters/lox/TestClock.java</code></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> com.craftinginterpreters.lox;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> java.util.List;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">TestClock</span> <span style="color:#66d9ef">implements</span> LoxClock {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> currentTime <span style="color:#f92672">=</span> 0;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">double</span> <span style="color:#a6e22e">getCurrentTimeSeconds</span>() {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> (<span style="color:#66d9ef">double</span>)currentTime;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">tick</span>() {
</span></span><span style="display:flex;"><span>        tick(1);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">tick</span>(<span style="color:#66d9ef">int</span> seconds) {
</span></span><span style="display:flex;"><span>        currentTime <span style="color:#f92672">+=</span> seconds;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div>]]></content:encoded>
      <category>crafting-interpreters</category>
    </item>
    <item>
      <title>Building the Java Lox Interpreter with Gradle</title>
      <link>https://shivfitzpatrick.com/posts/gradle/</link>
      <pubDate>Mon, 07 Apr 2025 18:03:00 -0700</pubDate>
      <guid isPermaLink="true">https://shivfitzpatrick.com/posts/gradle/</guid>
      <description>“Everything starts with a class in Java. Stick that in a text file, and go get your IDE or Makefile or whatever set up. I’ll be right here when you’re ready. Good? OK!” - Crafting Interpreters, 4.1 - The Interpreter Framework&amp;#xA;“Or Whatever Setup” This is the second of 3 posts on getting set up to work with Java as I go through the book Crafting Interpreters. In this Post we’re covering build tools. There are a lot of ways you could go about building and executing a Java project. I preferred to avoid using an IDE to set up my project, so I needed to choose that setup for myself.</description>
      <content:encoded><![CDATA[<p>&ldquo;Everything starts with a class in Java. Stick that in a text file,
and go get your IDE or Makefile or whatever set up. I’ll be right here
when you’re ready. Good? OK!&rdquo; - Crafting Interpreters, 4.1 - The
Interpreter Framework</p>
<h2 id="or-whatever-setup">&ldquo;Or Whatever Setup&rdquo;</h2>
<p>This is the second of 3 posts on getting set up to work with Java as I
go through the book Crafting Interpreters. In this Post we&rsquo;re covering
build tools. There are a lot of ways you could go about building and
executing a Java project. I preferred to avoid using an IDE to set up
my project, so I needed to choose that setup for myself.</p>
<p>One <strong>could</strong>, like the cavemen of olden days, just use <code>javac</code> to build
her code, and <code>java</code> to run it. Besides the fact that simply building
and executing your programs with the java executables is less
straightforward than one might prefer, there are some additional
benefits to using a build tool. I personally do not want to work on a
project of any size without the ability to write tests, and writing
tests usually entails dependencies. A few chapters in, the book has
you write a code generation tool to get around Java&rsquo;s tragic
verbosity, and its nice to have a task runner and a separate build
pipeline to deal with this tool. I&rsquo;ll explain how I used Gradle to do
each of these things.</p>
<h2 id="gradle-vs-maven-vs-ant">Gradle vs Maven vs Ant</h2>
<p>There are a few different popular build tools to consider when
starting a new Java project, and I spent almost zero time evaluating
them. I decided to use Gradle because:</p>
<ol>
<li>Gradle is the standard tool for building Android projects</li>
<li>Gradle uses Kotlin (or Groovy) instead of XML as the configuration language</li>
<li>I have used Gradle before</li>
</ol>
<p>Are there good reasons to choose one of the others? Maybe!</p>
<h2 id="getting-started">Getting Started</h2>
<h3 id="install-java-install-gradle">Install java, install gradle</h3>
<p>I won&rsquo;t go into detail here because this is system dependent. I used
my system package manager to install java 21 and the global gradle
that you&rsquo;ll use to initialize your project. If you need more assitance
getting gradle installed, check this out: <a href="https://gradle.org/install/">https://gradle.org/install/</a>.</p>
<h3 id="create-a-new-gradle-project">Create a new gradle project</h3>
<p>Once you have gradle installed, you can get your project set up pretty
easily with this command:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>gradle init --package com.craftinginterpreters.lox
</span></span><span style="display:flex;"><span>            --project-name lox
</span></span><span style="display:flex;"><span>            --java-version <span style="color:#ae81ff">21</span>
</span></span><span style="display:flex;"><span>            --test-framework junit
</span></span><span style="display:flex;"><span>            --dsl kotlin
</span></span><span style="display:flex;"><span>            --type java-application
</span></span><span style="display:flex;"><span>            --no-incubating
</span></span><span style="display:flex;"><span>            --no-split-project
</span></span></code></pre></div><p>More about gradle init: <a href="https://docs.gradle.org/current/userguide/build_init_plugin.html">https://docs.gradle.org/current/userguide/build_init_plugin.html</a></p>
<p>If you leave out all the options to gradle init, it will prompt you to
make a selection for each of these.</p>
<ul>
<li>package: Creates directory structure that matches the package name</li>
<li>project-name: Self explanatory. Not sure if this has any effect on
anything other than just being the nanme of the project</li>
<li>java-version: The version of Java you want to use.</li>
<li>test-framework: By default it prompts you to choose &ldquo;junit&rdquo; which
really means junit 4. That&rsquo;s what I chose, but I was unaware that
there is a junit 5, and you can select it here by choosing
&ldquo;jupiter-junit&rdquo; instead. Since I did not find this out until later,
I&rsquo;ll use junit 4 for my examples in the next post, but it should be
easy enough to translate to junit 5 if you prefer to use that
instead.</li>
<li>dsl: You can choose to configure the project with Kotlin or
Groovy. Since its plausible I may want to learn Kotlin in the
future, I preferred to choose that. The downside is that it&rsquo;s often
easier to find examples online written in Groovy.</li>
<li>type: This allows you to pick a project template. <code>java-appliation</code>
is &ldquo;a command line application written in java&rdquo; which is exactly
what we want. More about the application plugin:
<a href="https://docs.gradle.org/current/userguide/application_plugin.html">https://docs.gradle.org/current/userguide/application_plugin.html</a></li>
<li>no-incubating: You can choose between the bleeding edge and stable
versions of Gradle. I decided to go with the stable version since it
was pretty likely that I would be going through this book on and off
over a long period of time. I want the build to &ldquo;just work&rdquo; even if
I haven&rsquo;t touched it in 6 months.</li>
<li>no-split-project: This allows you to have multiple projects with
separate build files. We don&rsquo;t really need that for a project this
small.</li>
</ul>
<p>Once you&rsquo;ve run gradle init configured to your liking, you should have
java files named App.java and AppTest.java created inside this
directory structure. I would change them both to Lox.java and
LoxTest.java and rename the classes within. You&rsquo;ll also want to
checkout app/build.gradle.kts and change the main class to match. This
will make it a little easier to follow along with the book which names
its entrypoint Lox instead of App.</p>
<p>Check this out for more info about initializing Gradle:
<a href="https://docs.gradle.org/current/userguide/build_init_plugin.html">https://docs.gradle.org/current/userguide/build_init_plugin.html</a></p>
<h2 id="dependencies">Dependencies</h2>
<p>You probably won&rsquo;t need to add any more dependencies, since gradle
init will install the test framework for you. If you updated the main
class to Lox, your app/build.gradle.kts should look like this:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#75715e">/*
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * This file was generated by the Gradle &#39;init&#39; task.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> *
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * This generated file contains a sample Java application project to get you started.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * For more details on building Java &amp; JVM projects, please refer to https://docs.gradle.org/8.12/userguide/building_java_projects.html in the Gradle documentation.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> */</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>plugins {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Apply the application plugin to add support for building a CLI application in Java.</span>
</span></span><span style="display:flex;"><span>    application
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>repositories {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Use Maven Central for resolving dependencies.</span>
</span></span><span style="display:flex;"><span>    mavenCentral()
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>dependencies {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Use JUnit test framework.</span>
</span></span><span style="display:flex;"><span>    testImplementation(libs.<span style="color:#a6e22e">junit</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// This dependency is used by the application.</span>
</span></span><span style="display:flex;"><span>    implementation(libs.<span style="color:#a6e22e">guava</span>)
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// Apply a specific Java toolchain to ease working on different environments.</span>
</span></span><span style="display:flex;"><span>java {
</span></span><span style="display:flex;"><span>    toolchain {
</span></span><span style="display:flex;"><span>        languageVersion <span style="color:#f92672">=</span> JavaLanguageVersion.<span style="color:#a6e22e">of</span>(21)
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>application {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Define the main class for the application.</span>
</span></span><span style="display:flex;"><span>    mainClass <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;com.craftinginterpreters.lox.Lox&#34;</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>You&rsquo;ll notice that gradle added an additional dependency called
guava. Guava is a kind of supplemental standard library, with lots of
neat doodads and utilities. Code from the book won&rsquo;t take advantage of
that library, so you can go ahead and deleted the depenedency. You can
read more about guava here if you are curious:
<a href="https://github.com/google/guava">https://github.com/google/guava</a></p>
<h2 id="the-gradle-wrapper">The Gradle Wrapper</h2>
<p><code>gradle init</code> creates a script called <code>gradlew</code> in the root of your
project. This is the primary way you&rsquo;ll interact with gradle. It will
install the correct version of gradle that your project requires if
its missing, and use that gradle to run your tasks. This makes it
really easy to get set up on another machine.</p>
<h2 id="unit-tests">Unit Tests</h2>
<p>You can run your tests with <code>./gradlew test</code>. I often run them with
the <code>--info</code> flag which will allow exceptions thrown and
System.out.println to get printed out in the console for you. I&rsquo;ll
discuss writing test cases in a future post.</p>
<h2 id="configuring-tasks">Configuring tasks</h2>
<p>You&rsquo;ll primarily interact with gradle by running tasks. So far we&rsquo;ve
used tasks that come with gradle like <code>init</code>, and tasks that gradle
defines for your project like <code>run</code> and <code>test</code>. The behavior of
existing tasks can be configured to our liking. In addition we can
create our own tasks.</p>
<h3 id="configuring-run">Configuring <code>run</code></h3>
<p><code>java-application</code> comes with a <code>run</code> task that executes our
application. jLox will accept input in two different forms:</p>
<ul>
<li>From a .lox sources files</li>
<li>As a REPL accepting strings of lox code from standard input</li>
</ul>
<p>By default gradle will not wire up standard input to your tasks, so
we&rsquo;ll need to enable that explicitly for the REPL to work
properly. To test this out you can setup your Lox.java file to look like this:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#75715e">/*
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * This source file was generated by the Gradle &#39;init&#39; task
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> */</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">package</span> com.craftinginterpreters.lox;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> java.io.BufferedReader;
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> java.io.IOException;
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> java.io.InputStreamReader;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Lox</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">main</span>(String<span style="color:#f92672">[]</span> args) <span style="color:#66d9ef">throws</span> IOException {
</span></span><span style="display:flex;"><span>        System.<span style="color:#a6e22e">out</span>.<span style="color:#a6e22e">println</span>(<span style="color:#e6db74">&#34;Input string:&#34;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>              InputStreamReader input <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> InputStreamReader(System.<span style="color:#a6e22e">in</span>);
</span></span><span style="display:flex;"><span>              BufferedReader reader <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> BufferedReader(input);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>              String line <span style="color:#f92672">=</span> reader.<span style="color:#a6e22e">readLine</span>();
</span></span><span style="display:flex;"><span>              System.<span style="color:#a6e22e">out</span>.<span style="color:#a6e22e">println</span>(<span style="color:#e6db74">&#34;Line:&#34;</span>);
</span></span><span style="display:flex;"><span>              System.<span style="color:#a6e22e">out</span>.<span style="color:#a6e22e">println</span>(line);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>If you try <code>./gradlew run</code> without modifying the run task it should
print <code>null</code> without waiting for your input.</p>
<p>Add this to your build.gradle.kts to configure the <code>run</code>
task:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-kotlin" data-lang="kotlin"><span style="display:flex;"><span>tasks.named&lt;JavaExec&gt;(<span style="color:#e6db74">&#34;run&#34;</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Needed for the repl
</span></span></span><span style="display:flex;"><span>    standardInput = <span style="color:#a6e22e">System</span>.`in`
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Now try running that again. It should wait for your input now, but
you&rsquo;ll also see a bunch of &ldquo;gradle stuff&rdquo; that interrupts the input
experience.</p>
<h3 id="cleaning-up-the-command-line-output">Cleaning up the command line output</h3>
<p>A few command line arguments can clean up the output from gradle to
give you a better experience interacting with the REPL:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>./gradlew run -q --console<span style="color:#f92672">=</span>plain
</span></span></code></pre></div><h3 id="custom-tasks">Custom tasks</h3>
<p>Later in the book we write a code generation tool. We can create
custom task to run this code. You can create a placeholder file to
test this out and put it in <code>app/src/main/java/com/craftinginterpreters/tool/GenerateAst.java</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> com.craftinginterpreters.tool;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">GenerateAst</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">main</span>(String<span style="color:#f92672">[]</span> args) {
</span></span><span style="display:flex;"><span>        System.<span style="color:#a6e22e">out</span>.<span style="color:#a6e22e">println</span>(<span style="color:#e6db74">&#34;Generate AST&#34;</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Then add this to your <code>build.gradle.kts</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-kotlin" data-lang="kotlin"><span style="display:flex;"><span>tasks.register&lt;JavaExec&gt;(<span style="color:#e6db74">&#34;generateAst&#34;</span>) {
</span></span><span style="display:flex;"><span>    classpath = sourceSets.named(<span style="color:#e6db74">&#34;tool&#34;</span>).<span style="color:#66d9ef">get</span>().runtimeClasspath
</span></span><span style="display:flex;"><span>    mainClass.<span style="color:#66d9ef">set</span>(<span style="color:#e6db74">&#34;com.craftinginterpreters.tool.GenerateAst&#34;</span>)
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>You now run this tasks like so:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>./gradlew app:generateAst
</span></span></code></pre></div><h3 id="passing-command-line-arguments-to-your-tasks">Passing command line arguments to your tasks</h3>
<p>Crafting Interperters will instruct you to accept a directory name as
a command line argument where you will output the generated
code. Let&rsquo;s go ahead and test that out too. Let&rsquo;s tweak the code for
<code>GenerateAst.java</code> a bit to print out the first command line arg you
pass:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> com.craftinginterpreters.tool;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">GenerateAst</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">main</span>(String<span style="color:#f92672">[]</span> args) {
</span></span><span style="display:flex;"><span>        System.<span style="color:#a6e22e">out</span>.<span style="color:#a6e22e">println</span>(<span style="color:#e6db74">&#34;Generate AST to file: &#34;</span> <span style="color:#f92672">+</span> args<span style="color:#f92672">[</span>0<span style="color:#f92672">]</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>And now you can pass an argument to your task like so:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>./gradlew app:generateAst --args<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span>$PWD<span style="color:#e6db74">/app/src/main/java/com/craftinginterpreters/lox&#34;</span>
</span></span></code></pre></div><h3 id="using-sourcesets-to-isolate-unrelated-code">Using sourceSets to isolate unrelated code</h3>
<p>Ultimately Crafting Interpreters will instruct you to fill this file
with code that outputs a new source file with interfaces you&rsquo;ll import
into the rest of your code. One problem you may run into is that if
you add new methods to these interfaces, it will immediately break the
rest of your code because you&rsquo;ve failed to implement them yet. But
what if you need to run <code>app:generateAst</code> again? <code>app:generateAst</code>
shouldn&rsquo;t really depend on the rest of the code, and indeed Gradle
does give us a tool to deal with this called sourceSets.</p>
<p>The first thing we&rsquo;re going to want to do is to move the tool
directory out of <code>app/src/main</code> into its own top level directory
<code>app/src/tool</code>. I tried as much as possible to avoid modifying the
code in the book, but I think we&rsquo;re fighting against the tides if we
try to keep source code that should be isolated inside of main. Let&rsquo;s
move
<code>app/src/main/java/com/craftinginterpreters/tool/GenerateAst.java</code> to
<code>app/src/tool/java/com/craftinginterpreters/tool/GenerateAst.java</code>.</p>
<p>Add this <code>sourceSets</code> section and update your <code>generateAst</code> task in
your <code>build.gradle.kts</code> file:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-kotlin" data-lang="kotlin"><span style="display:flex;"><span>sourceSets {
</span></span><span style="display:flex;"><span>    create(<span style="color:#e6db74">&#34;tool&#34;</span>) {
</span></span><span style="display:flex;"><span>        java {
</span></span><span style="display:flex;"><span>            srcDir(<span style="color:#e6db74">&#34;src/tool&#34;</span>)
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>tasks.register&lt;JavaExec&gt;(<span style="color:#e6db74">&#34;generateAst&#34;</span>) {
</span></span><span style="display:flex;"><span>    classpath = sourceSets.named(<span style="color:#e6db74">&#34;tool&#34;</span>).<span style="color:#66d9ef">get</span>().runtimeClasspath
</span></span><span style="display:flex;"><span>    mainClass.<span style="color:#66d9ef">set</span>(<span style="color:#e6db74">&#34;com.craftinginterpreters.tool.GenerateAst&#34;</span>)
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Now you can break whatever you want in the primary codebase without
affecting the tool.</p>
<h3 id="pass-command-line-arguments-from-the-task-configuration">Pass command line arguments from the task configuration</h3>
<p>A quick quality of life improvement is to configure the default
command line arguments for generateAst right in the task
configuration.</p>
<p>Update your task configuration like so:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-kotlin" data-lang="kotlin"><span style="display:flex;"><span>tasks.register&lt;JavaExec&gt;(<span style="color:#e6db74">&#34;generateAst&#34;</span>) {
</span></span><span style="display:flex;"><span>    classpath = sourceSets.named(<span style="color:#e6db74">&#34;tool&#34;</span>).<span style="color:#66d9ef">get</span>().runtimeClasspath
</span></span><span style="display:flex;"><span>    mainClass.<span style="color:#66d9ef">set</span>(<span style="color:#e6db74">&#34;com.craftinginterpreters.tool.GenerateAst&#34;</span>)
</span></span><span style="display:flex;"><span>    args = listOf(project.<span style="color:#66d9ef">file</span>(<span style="color:#e6db74">&#34;app/src/main/java/com/craftinginterpreters/lox&#34;</span>).getAbsolutePath())
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Now you can just run:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>./gradlew app:generateAst
</span></span></code></pre></div><p>And you retain the ability to pass the args explicitly if you want.</p>
<h3 id="task-dependencies">Task dependencies</h3>
<p>Ok was that really necessary? You&rsquo;ve got ctrl-r after all. We can
build on this by making <code>generateAst</code> a task dependency for <code>run</code> and <code>test</code>. Now
you don&rsquo;t have to worry about forgetting to run <code>generateAst</code> at all. You can just run
<code>run</code> and <code>test</code> and be confident that all of the generated code is in place.</p>
<h4 id="using-dependson-for-task-dependencies">Using <code>dependsOn</code> for task dependencies</h4>
<p>The first thing I tried was to have <code>run</code> and <code>test</code> depend on
<code>generateAst</code> directly. Unfortunately this approach has a
problem. What we want is to run <code>generateAst</code> not just before <code>run</code> or
<code>test</code> execute their code. We actually need it to run before <code>run</code> and
<code>test</code> <strong>compile</strong> their code.</p>
<h4 id="gradle-s-compilation-tasks">Gradle&rsquo;s compilation tasks</h4>
<p>It turns out, each SourceSet comes with its own set of compilation
tasks. For the &ldquo;main&rdquo; SourceSet, that task is called
&ldquo;compileJava&rdquo;. (For the tool SourceSet, the task gets a suffix:
&ldquo;compileJavaTool&rdquo;. This is a common convention in gradle, where
suffixes are omitted when things refer to the &ldquo;main&rdquo; SourceSet.) To
make sure that the compilation of the &ldquo;main&rdquo; SourceSet is dependent on
<code>generateAst</code>, let&rsquo;s fix our build file like so:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-kotlin" data-lang="kotlin"><span style="display:flex;"><span><span style="color:#66d9ef">val</span> generateAst <span style="color:#66d9ef">by</span> tasks.register&lt;JavaExec&gt;(<span style="color:#e6db74">&#34;generateAst&#34;</span>) {
</span></span><span style="display:flex;"><span>    group = <span style="color:#e6db74">&#34;build&#34;</span>
</span></span><span style="display:flex;"><span>    description = <span style="color:#e6db74">&#34;Generates source code using the AST tool&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    classpath = sourceSets.named(<span style="color:#e6db74">&#34;tool&#34;</span>).<span style="color:#66d9ef">get</span>().runtimeClasspath
</span></span><span style="display:flex;"><span>    mainClass.<span style="color:#66d9ef">set</span>(<span style="color:#e6db74">&#34;com.craftinginterpreters.tool.GenerateAst&#34;</span>)
</span></span><span style="display:flex;"><span>    args = listOf(project.<span style="color:#66d9ef">file</span>(<span style="color:#e6db74">&#34;src/main/java/com/craftinginterpreters/lox&#34;</span>).getAbsolutePath())
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>tasks.named(<span style="color:#e6db74">&#34;compileJava&#34;</span>) {
</span></span><span style="display:flex;"><span>    dependsOn(generateAst)
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Conceptually, this is a better approach anyway. The code we generate
with <code>generateAst</code> should always be generated before will compile
&ldquo;main&rdquo;, and any future tasks that depend on &ldquo;main&rdquo; will get to take
advantage of our tool.</p>
<h3 id="fin-dot">fin.</h3>
<p>Here&rsquo;s the finished <code>build.gradle.kts</code> file:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-kotlin" data-lang="kotlin"><span style="display:flex;"><span><span style="color:#75715e">/*
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * This file was generated by the Gradle &#39;init&#39; task.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> *
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * This generated file contains a sample Java application project to get you started.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * For more details on building Java &amp; JVM projects, please refer to https://docs.gradle.org/8.12/userguide/building_java_projects.html in the Gradle documentation.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> */</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>plugins {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Apply the application plugin to add support for building a CLI application in Java.
</span></span></span><span style="display:flex;"><span>    application
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>repositories {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Use Maven Central for resolving dependencies.
</span></span></span><span style="display:flex;"><span>    mavenCentral()
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>dependencies {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Use JUnit test framework.
</span></span></span><span style="display:flex;"><span>    testImplementation(libs.junit)
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// Apply a specific Java toolchain to ease working on different environments.
</span></span></span><span style="display:flex;"><span>java {
</span></span><span style="display:flex;"><span>    toolchain {
</span></span><span style="display:flex;"><span>        languageVersion = <span style="color:#a6e22e">JavaLanguageVersion</span>.of(<span style="color:#ae81ff">21</span>)
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>tasks.named&lt;JavaExec&gt;(<span style="color:#e6db74">&#34;run&#34;</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Needed for the repl
</span></span></span><span style="display:flex;"><span>    standardInput = <span style="color:#a6e22e">System</span>.`in`
</span></span><span style="display:flex;"><span>    dependsOn(<span style="color:#e6db74">&#34;generateAst&#34;</span>)
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>tasks.named(<span style="color:#e6db74">&#34;test&#34;</span>) {
</span></span><span style="display:flex;"><span>    dependsOn(<span style="color:#e6db74">&#34;generateAst&#34;</span>)
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>tasks.register&lt;JavaExec&gt;(<span style="color:#e6db74">&#34;generateAst&#34;</span>) {
</span></span><span style="display:flex;"><span>    classpath = sourceSets.named(<span style="color:#e6db74">&#34;tool&#34;</span>).<span style="color:#66d9ef">get</span>().runtimeClasspath
</span></span><span style="display:flex;"><span>    mainClass.<span style="color:#66d9ef">set</span>(<span style="color:#e6db74">&#34;com.craftinginterpreters.tool.GenerateAst&#34;</span>)
</span></span><span style="display:flex;"><span>    args = listOf(project.<span style="color:#66d9ef">file</span>(<span style="color:#e6db74">&#34;app/src/main/java/com/craftinginterpreters/lox&#34;</span>).getAbsolutePath())
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>sourceSets {
</span></span><span style="display:flex;"><span>    create(<span style="color:#e6db74">&#34;tool&#34;</span>) {
</span></span><span style="display:flex;"><span>        java {
</span></span><span style="display:flex;"><span>            srcDir(<span style="color:#e6db74">&#34;src/tool&#34;</span>)
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>application {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Define the main class for the application.
</span></span></span><span style="display:flex;"><span>    mainClass = <span style="color:#e6db74">&#34;com.craftinginterpreters.lox.Lox&#34;</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>At this point I&rsquo;m pretty satisfied with the project set up. Now we&rsquo;ve got:</p>
<ul>
<li>Unit tests</li>
<li>Easy to build and run the project</li>
<li>Control the amount of log output</li>
<li>Code generation that runs automatically whenever we build</li>
</ul>
<p>These quality of life improvements improved my experience working
through the Java section of the book quite a bit. We love Gradle,
we&rsquo;re all gradle-pilled now.</p>
]]></content:encoded>
      <category>crafting-interpreters</category>
    </item>
    <item>
      <title>Crafting an Interpreter in Java</title>
      <link>https://shivfitzpatrick.com/posts/thoughts_on_java/</link>
      <pubDate>Sun, 06 Apr 2025 18:03:00 -0700</pubDate>
      <guid isPermaLink="true">https://shivfitzpatrick.com/posts/thoughts_on_java/</guid>
      <description>Crafting an Interpreter in Java Crafting Interpreters is divided into two parts: the first half uses Java to build an interpreter, while the second uses to C for a bytecode compiler. One of the things that drew me to the book was that, in addition to learning how to implement programming languages, you also pick up two different programming languages along the way. This post documents some observations about the language itself that stuck out to me when I learned it.</description>
      <content:encoded><![CDATA[<h2 id="crafting-an-interpreter-in-java">Crafting an Interpreter in Java</h2>
<p>Crafting Interpreters is divided into two parts: the first half uses
Java to build an interpreter, while the second uses to C for a
bytecode compiler. One of the things that drew me to the book was
that, in addition to learning how to implement programming languages,
you also pick up two different programming languages along the
way. This post documents some observations about the language itself
that stuck out to me when I learned it.</p>
<h2 id="a-note-on-ides">A Note on IDEs</h2>
<p>Most people I&rsquo;ve known in a professional context would use a Java
specific IDE to work with the language. I&rsquo;ve used IntelliJ and its
cousin Android Studio in the past. If you have no editor preference at
all I think IntelliJ will make your life the easiest. That said, I am
not using an IDE to go through this book, and I think it&rsquo;s totally
feasible to use any editor you want to work on a Java project this
size.</p>
<h2 id="package-names-and-directory-structure">Package names and Directory Structure</h2>
<p>Introductory documentation and tutorials for language beginners often
focus on the syntax of the language in question. In my experience,
that is rarely where I get stuck. Almost always I run into problems
when I try to make the transition beyond a toy project consisting of a
single file. With Java one of the first sticking points I ran into was
the directory structure. The directory structure of even small java
projects always seemed intimidating to me. Actually the way Java
projects are usually organized makes a lot of sense if you know what&rsquo;s
going on.</p>
<h3 id="designed-for-scale">Designed for scale</h3>
<p>Java is a language that&rsquo;s popular at huge companies with huge
codebases. New programmers may assume that these companies stick with
Java simply out of habit. In fact some of the things that seem
unnecessary, like Java&rsquo;s clunky directory naming, are &ldquo;features&rdquo; not
&ldquo;bugs&rdquo; when you are working at a larger scale.</p>
<h3 id="maven-standard-directory-layout"><a href="https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html">Maven Standard Directory Layout</a></h3>
<p>Maven is a one of a few competing build tools for working on Java
projects. As well as providing the tools to build Java projects, the
Maven project also publishes standard conventions for organizing Java
projects, and a directory of published Java projects you can use as
dependencies. For my project I chose to use Gradle to build my
project, which also follows the Maven Standard Directory Layout. It&rsquo;s
worth checking out the documentation yourself, but this layout
describes the very top level of the directory structure. We&rsquo;ll cover
the most relevant one real quick:</p>
<table>
  <thead>
      <tr>
          <th>Directory</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>./</td>
          <td>READEME, build files, License, etc.</td>
      </tr>
      <tr>
          <td>src/main</td>
          <td>Your source files</td>
      </tr>
      <tr>
          <td>src/test</td>
          <td>Your test files</td>
      </tr>
  </tbody>
</table>
<p>Not so bad right? Gradle projects further nest this inside an &ldquo;app&rdquo;
directory, setting you up for success if you need to add any
subprojects to your repository.</p>
<table>
  <thead>
      <tr>
          <th>Directory</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>./</td>
          <td>READEME, License, gradle settings, subprojects, etc.</td>
      </tr>
      <tr>
          <td>app/</td>
          <td>build file for the app project</td>
      </tr>
      <tr>
          <td>app/src/main</td>
          <td>Your source files</td>
      </tr>
      <tr>
          <td>app/src/test</td>
          <td>Your test files</td>
      </tr>
  </tbody>
</table>
<h3 id="what-s-the-deal-with-com">What&rsquo;s the deal with &ldquo;com&rdquo;</h3>
<p>Ok that&rsquo;s all good and well, but you may remain perplexed when you
open up src/main and are greeted with &ldquo;com&rdquo;, followed by a seemingly
interminable number of useless directories before you find any actual
code. There are three principles at work here.</p>
<ol>
<li>Inside src/main the directories should may directly to package names</li>
<li>Package names should ideally be unique across all your dependencies</li>
<li>If you always name your packages after a website name that you own,
you are unlikely to conflict with other package names.</li>
</ol>
<p>This might seem extreme to you, but consider how awful working with
dependencies in environments like nodejs and python can be. This is
just one way that the Java ecosystem seeks to make sure things &ldquo;just
work&rdquo; even on enormous projects. I&rsquo;ve come to appreciate the reasoning
here, even though I do find all the empty directories pretty
irritating. Now you&rsquo;ve got something like this:</p>
<table>
  <thead>
      <tr>
          <th>Directory</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>./</td>
          <td>READEME, License, gradle settings, subprojects, etc.</td>
      </tr>
      <tr>
          <td>app/</td>
          <td>build file for the app project</td>
      </tr>
      <tr>
          <td>app/src/main/com/goodskynet/coolproject</td>
          <td>Your source files</td>
      </tr>
      <tr>
          <td>app/src/test/com/goodskynet/coolproject</td>
          <td>Your test files</td>
      </tr>
  </tbody>
</table>
<h2 id="collections">Collections</h2>
<p>Modern languages usually provide convenient syntax for working with
lists and dictionaries. Java instead provides libraries with lots of
different collection implementations, optimized for various use
cases. I won&rsquo;t go through all the usefull ones here, but you should
expect when the book decides to create a list of object instances,
you&rsquo;re going to be importing something like java.util.List (to type
your variables) and java.util.ArrayList (the actual class you
instantiate), instead of using []. Actual quote from the book: <a href="https://craftinginterpreters.com/statements-and-state.html#parsing-statements">&ldquo;We
must also chant a minor prayer to the Java verbosity gods since we are
using ArrayList now.&rdquo;</a></p>
<h2 id="running-the-code">Running the code</h2>
<p>The java executable has a ton of options for configuring its
behavior. If you plan to use the executable directly, you&rsquo;re going to
have to learn about some of them. I preferred to allow my build tools
to handle this for me. Build tools like Gradle and Maven provide a lot
of additional benefits anyway, which I will cover in the next post.</p>
<h2 id="unsupportedoperationexception">UnsupportedOperationException</h2>
<p>When a class implements an interface in Java, Java gets upset when any
of the methods from the interface are missing. While this is sort of
the entire point of interfaces, sometimes it is helpful to run your
code before you are done matching the interface. Of course you could
mock out the missing methods however you want, but after a little
Googling it seemed like the most canonical way to throw an exception
for this case is <code>UnsupportedOperationException</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> com.craftinginterpreters.lox;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> java.lang.UnsupportedOperationException;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Interpreter</span> <span style="color:#66d9ef">implements</span> Expr.<span style="color:#a6e22e">Visitor</span><span style="color:#f92672">&lt;</span>Object<span style="color:#f92672">&gt;</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">@Override</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> Void <span style="color:#a6e22e">visitFunctionStmt</span>(Stmt.<span style="color:#a6e22e">Function</span> stmt) {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">throw</span> <span style="color:#66d9ef">new</span> UnsupportedOperationException(<span style="color:#e6db74">&#34;Not implemented&#34;</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div>]]></content:encoded>
      <category>crafting-interpreters</category>
    </item>
  </channel>
</rss>
