<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"
    xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel>
        <title>Enter the void *</title>
        <link>http://blog.emillon.org</link>
        <description><![CDATA[Yet another random hacker]]></description>
        <atom:link href="http://blog.emillon.org/feeds/haskell.xml" rel="self"
                   type="application/rss+xml" />
        <lastBuildDate>Mon, 21 Nov 2011 00:00:00 UT</lastBuildDate>
        <item>
    <title>Hakyll 101</title>
    <link>http://blog.emillon.org/posts/2011-11-21-hakyll-101.html</link>
    <description><![CDATA[<p>So, the recent trend seems to be static blogging. Indeed, as a web application,
a blog is mostly read-only. By generating static <code>.html</code> files, one can
eliminate :</p>
<ul>
<li>CPU load : static content is what’s easiest to serve, especially with modern
servers using <a href="http://manpages.debian.org/cgi-bin/man.cgi?query=sendfile&amp;sektion=2&amp;apropos=0&amp;manpath=Debian%206.0%20squeeze">sendfile(2)</a>.</li>
<li>security issues : without dynamic page generation, the attack surface is
also vastly reduced. Authentication is moved from a PHP or Python script to
the Unix way.</li>
<li>deployment problems : I don’t know a free host that won’t serve static
files. I use <a href="http://aws.amazon.com/s3/">S3</a> (and the free tier will often be enough !) but if I am not
satisfied, it’s dead simple to migrate.</li>
</ul>
<p>Basically, it’s like moving from a dynamic language to a static one ☺. The only
problem is if you want to add comments. The popular solution is <a href="https://disqus.com">Disqus</a> but it
is unfortunately a non-free application. I’ll probably stick to it but I fear
data lock-in.</p>
<p>As it is fashionable, a <em>lot</em> of tools have appeared : <a href="https://github.com/ametaireau/pelican/">pelican</a>, <a href="http://blogofile.com/">blogofile</a>,
<a href="http://ikiwiki.info/">ikiwiki</a>, <a href="http://jekyllrb.com/">jekyll</a>… Being a haskeller, I decided to give <a href="http://jaspervdj.be/hakyll/">hakyll</a> a try.</p>
<p>Hakyll is a haskell library for writing and deploying static websites ; that’s about
it. As in a dynamic application, you define routes and how to serve them :</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">makeCss ::</span> <span class="dt">Rules</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>makeCss <span class="ot">=</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  void <span class="op">$</span> match <span class="st">&quot;css/*&quot;</span> <span class="op">$</span> <span class="kw">do</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>      route   idRoute</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>      compile compressCssCompiler</span></code></pre></div>
<p>Most rules consist of compiling <a href="http://daringfireball.net/projects/markdown/">markdown</a> to HTML (with the fantastic <a href="http://johnmacfarlane.net/pandoc/">pandoc</a>
library) and copying stuff around.</p>
<p>The resulting binary, when compiled, can be run to see previews, build files or
even deploy the site.</p>
<pre><code> ~/www/blog [master] % ./blog
ABOUT

This is a Hakyll site generator program. You should always
run it from the project root directory.

USAGE

blog build           Generate the site
blog clean           Clean up and remove cache
blog help            Show this message
blog preview [port]  Run a server and autocompile
blog rebuild         Clean up and build again
blog server [port]   Run a local test server
blog deploy          Upload/deploy your site</code></pre>
<p>So far I’ve found it very easy to use. That’s it for this first mini-tour. Stay
tuned !</p>]]></description>
    <pubDate>Mon, 21 Nov 2011 00:00:00 UT</pubDate>
    <guid>http://blog.emillon.org/posts/2011-11-21-hakyll-101.html</guid>
    <dc:creator>Etienne Millon</dc:creator>
</item>
<item>
    <title>What's in an ADT ?</title>
    <link>http://blog.emillon.org/posts/2011-12-14-what-s-in-an-adt.html</link>
    <description><![CDATA[<h2 id="introduction">Introduction</h2>
<p>Algebraic Data Types, or ADTs for short, are a core feature of functional
languages such as OCaml or Haskell. They are a handy model of closed disjoint
unions and unfortunately, outside of the functional realm, they are only seldom
used.</p>
<p>In this article, I will explain what ADTs are, how they are used in OCaml and
what trimmed-down versions of them exist in other languages. I will use OCaml,
but the big picture is about the same in Haskell.</p>
<h2 id="principles">Principles</h2>
<p>Functional languages offer a myriad of types for the programmer.</p>
<ul>
<li>some <em>base</em> types, such as <code>int</code>, <code>char</code> or <code>bool</code>.</li>
<li>functions, ie <em>arrow</em> types. A function with domain <code>a</code> and codomain <code>b</code> has
type <code>a -&gt; b</code>.</li>
<li>tuples, ie <em>product</em> types. A tuple is an heterogeneous, fixed-width
container type (its set-theoretic counterpart is the cartesian product) For
example, <code>(2, true, 'x')</code> has type <code>int * bool * char</code>. <em>record</em> types are a
(mostly) syntactic extension to give name to their fields.</li>
<li>some <em>parametric</em> types. For example, if <code>t</code> is a type, <code>t list</code> is the type
of homogeneous linked list of elements having type <code>t</code>.</li>
<li>what we are talking about today, <em>algebraic</em> types (or <em>sum</em> types, or
<em>variant</em> types).</li>
</ul>
<p>If product types represent the cartesian product, algebraic types represent the
disjoint union. In another words, they are very adapted for a case
analysis.</p>
<p>We will take the example of integer ranges. One can say that an integer range is
either :</p>
<ul>
<li>the empty range</li>
<li>of the form <code>]-∞;a]</code></li>
<li>of the form <code>[a;+∞[</code></li>
<li>an interval of the form <code>[a;b]</code> (where a ≤ b)</li>
<li>the whole range (ie, ℤ)</li>
</ul>
<p>With the following properties :</p>
<ul>
<li>Disjunction : no range can be of two forms at a time.</li>
<li>Injectivity : if <code>[a;b]</code> = <code>[c;d]</code>, then <code>a</code> = <code>c</code> and <code>b</code> = <code>d</code> (and
similarly for other forms).</li>
<li>Exhaustiveness : it cannot be of another form.</li>
</ul>
<h2 id="syntax-semantics">Syntax &amp; semantics</h2>
<p>This can be encoded as an ADT :</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> range =</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  | Empty</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  | HalfLeft <span class="kw">of</span> <span class="dt">int</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>  | HalfRight <span class="kw">of</span> <span class="dt">int</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>  | Range <span class="kw">of</span> <span class="dt">int</span> * <span class="dt">int</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>  | FullRange</span></code></pre></div>
<p><code>Empty</code>, <code>HalfLeft</code>, <code>HalfRight</code>, <code>Range</code> and <code>FullRange</code> are <code>t</code>’s
<em>constructors</em>. They are the only way to build a value of type <code>t</code>. For example,
<code>Empty</code>, <code>HalfLeft 3</code> and <code>Range (2, 5)</code> are all values of type <code>t</code><a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a>. They
each have a specific <em>arity</em> (the number of arguments they take).</p>
<p>To <em>deconstruct</em> a value of type <code>t</code>, we have to use a powerful construct,
<em>pattern matching</em>, which is about matching a value against a sequence of
patterns (yes, that’s about it).</p>
<p>To illustrate this, we will write a function that computes the minimum value of
such a range. Of course, this can be ±∞ too, so we have to define a type to
represent the return value.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> ext_int =</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  | MinusInfinity</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  | Finite <span class="kw">of</span> <span class="dt">int</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>  | PlusInfinity</span></code></pre></div>
<p>In a math textbook, we would write the case analysis as :</p>
<ul>
<li>min ∅ = +∞</li>
<li>min ]-∞;a] = -∞</li>
<li>min [a;+∞[ = a</li>
<li>min [a;b] = a</li>
<li>min ℤ = -∞</li>
</ul>
<p>That translates to the following (executable !) OCaml code :</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> range_min x =</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">match</span> x <span class="kw">with</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>  | Empty -&gt; PlusInfinity</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>  | HalfLeft a -&gt; MinusInfinity</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>  | HalfRight a -&gt; Finite a</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>  | Range (a, b) -&gt; Finite a</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>  | FullRange -&gt; MinusInfinity</span></code></pre></div>
<p>In the pattern <code>HalfLeft a</code>, <code>a</code> is a variable name, so it get bounds to the
argument’s value. In other words, <code>match (HalfLeft 2) with HalfLeft x -&gt; e</code>
bounds <code>x</code> to 2 in <code>e</code>.</p>
<h2 id="its-functions-all-the-way-down">It’s functions all the way down</h2>
<p>Pattern matching seems magical at first, but it is only a syntactic trick.
Indeed, the definition of the above type is equivalent to the following
definition :</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> range</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="co">(* The following is not syntactically correct *)</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="kw">val</span> Empty : range</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="kw">val</span> HalfLeft : <span class="dt">int</span> -&gt; range</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a><span class="kw">val</span> HalfRight : <span class="dt">int</span> -&gt; range</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a><span class="kw">val</span> Range : <span class="dt">int</span> * <span class="dt">int</span> -&gt; range</span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a><span class="kw">val</span> FullRange : range</span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a><span class="co">(* Moreover, we know that they are injective and mutually disjoint *)</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a><span class="kw">val</span> deconstruct_range :</span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a>  (<span class="dt">unit</span> -&gt; &#39;a) -&gt;</span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a>  (<span class="dt">int</span> -&gt; &#39;a) -&gt;</span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a>  (<span class="dt">int</span> -&gt; &#39;a) -&gt;</span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a>  (<span class="dt">int</span> * <span class="dt">int</span> -&gt; &#39;a) -&gt;</span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a>  (<span class="dt">unit</span> -&gt; &#39;a) -&gt;</span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a>  range -&gt;</span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true" tabindex="-1"></a>  &#39;a</span></code></pre></div>
<p><code>deconstruct_range</code> is what replaces pattern matching. It also embodies the notion of
exhaustiveness, because given any value of type <code>range</code>, we can build a
deconstructed value out of it.</p>
<p>Its type looks scary at first, but if we look closer, its arguments are a
sequence of case-specific deconstructors<a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a> and the value to get “matched”
against.</p>
<p>To show the equivalence, we can implement <code>deconstruct_range</code> using pattern
patching and <code>range_min</code> using <code>deconstruct_range</code><a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a> :</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> deconstruct_range</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>      f_empty</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>      f_halfleft</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>      f_halfright</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>      f_range</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>      f_fullrange</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>      x</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>    =</span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">match</span> x <span class="kw">with</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>  | Empty -&gt; f_empty ()</span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>  | HalfLeft a -&gt; f_halfleft a</span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>  | HalfRight a -&gt; f_halfright a</span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>  | Range (a, b) -&gt; f_range (a, b)</span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a>  | FullRange -&gt; f_fullrange ()</span></code></pre></div>
<div class="sourceCode" id="cb6"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> range_min&#39; x =</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  deconstruct_range</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>    (<span class="kw">fun</span> () -&gt; PlusInfinity)</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>    (<span class="kw">fun</span> a -&gt; MinusInfinity)</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>    (<span class="kw">fun</span> a -&gt; Finite a)</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>    (<span class="kw">fun</span> (a, b) -&gt; Finite a)</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>    (<span class="kw">fun</span> () -&gt; MinusInfinity)</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>    x</span></code></pre></div>
<h2 id="implementation">Implementation</h2>
<p>After this trip in denotational-land, let’s get back to operational-land : how
is this implemented ?</p>
<p>In OCaml, no type information exists at runtime. Everything exists with a
uniform representation and is either an integer or a pointer to a block. Each
block starts with a tag, a size and a number of fields.</p>
<p>With the <code>Obj</code> module (kids, don’t try this at home), it is possible to inspect
blocks at runtime. Let’s write a dumper for <code>range</code> value and watch outputs :</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="co">(* Range of integers between a and b *)</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> rng a b =</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">if</span> a &gt; b <span class="kw">then</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>    []</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">else</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>    a :: rng (a+<span class="dv">1</span>) b</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> view_block o =</span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">if</span> (<span class="dt">Obj</span>.is_block o) <span class="kw">then</span></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">begin</span></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a>      <span class="kw">let</span> tag = <span class="dt">Obj</span>.tag o <span class="kw">in</span></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a>      <span class="kw">let</span> sz = <span class="dt">Obj</span>.size o <span class="kw">in</span></span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a>      <span class="kw">let</span> f n =</span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span> f = <span class="dt">Obj</span>.field o n <span class="kw">in</span></span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true" tabindex="-1"></a>        <span class="kw">assert</span> (<span class="dt">Obj</span>.is_int f);</span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Obj</span>.obj f</span>
<span id="cb7-17"><a href="#cb7-17" aria-hidden="true" tabindex="-1"></a>      <span class="kw">in</span></span>
<span id="cb7-18"><a href="#cb7-18" aria-hidden="true" tabindex="-1"></a>      tag :: <span class="dt">List</span>.map f (rng <span class="dv">0</span> (sz<span class="dv">-1</span>))</span>
<span id="cb7-19"><a href="#cb7-19" aria-hidden="true" tabindex="-1"></a>    <span class="kw">end</span></span>
<span id="cb7-20"><a href="#cb7-20" aria-hidden="true" tabindex="-1"></a>  <span class="kw">else</span> <span class="kw">if</span> <span class="dt">Obj</span>.is_int o <span class="kw">then</span></span>
<span id="cb7-21"><a href="#cb7-21" aria-hidden="true" tabindex="-1"></a>    [<span class="dt">Obj</span>.obj o]</span>
<span id="cb7-22"><a href="#cb7-22" aria-hidden="true" tabindex="-1"></a>  <span class="kw">else</span></span>
<span id="cb7-23"><a href="#cb7-23" aria-hidden="true" tabindex="-1"></a>    <span class="kw">assert</span> <span class="kw">false</span></span>
<span id="cb7-24"><a href="#cb7-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-25"><a href="#cb7-25" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> examples () =</span>
<span id="cb7-26"><a href="#cb7-26" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> p_list l =</span>
<span id="cb7-27"><a href="#cb7-27" aria-hidden="true" tabindex="-1"></a>    <span class="dt">String</span>.concat <span class="st">&quot;;&quot;</span> (<span class="dt">List</span>.map <span class="dt">string_of_int</span> l)</span>
<span id="cb7-28"><a href="#cb7-28" aria-hidden="true" tabindex="-1"></a>  <span class="kw">in</span></span>
<span id="cb7-29"><a href="#cb7-29" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> explore_range r =</span>
<span id="cb7-30"><a href="#cb7-30" aria-hidden="true" tabindex="-1"></a>    <span class="dt">print_endline</span> (p_list (view_block (<span class="dt">Obj</span>.repr r)))</span>
<span id="cb7-31"><a href="#cb7-31" aria-hidden="true" tabindex="-1"></a>  <span class="kw">in</span></span>
<span id="cb7-32"><a href="#cb7-32" aria-hidden="true" tabindex="-1"></a>  <span class="dt">List</span>.iter explore_range</span>
<span id="cb7-33"><a href="#cb7-33" aria-hidden="true" tabindex="-1"></a>    [ Empty</span>
<span id="cb7-34"><a href="#cb7-34" aria-hidden="true" tabindex="-1"></a>    ; HalfLeft <span class="dv">8</span></span>
<span id="cb7-35"><a href="#cb7-35" aria-hidden="true" tabindex="-1"></a>    ; HalfRight <span class="dv">13</span></span>
<span id="cb7-36"><a href="#cb7-36" aria-hidden="true" tabindex="-1"></a>    ; Range (<span class="dv">2</span>, <span class="dv">5</span>)</span>
<span id="cb7-37"><a href="#cb7-37" aria-hidden="true" tabindex="-1"></a>    ; FullRange</span>
<span id="cb7-38"><a href="#cb7-38" aria-hidden="true" tabindex="-1"></a>    ]</span></code></pre></div>
<p>When we run <code>examples ()</code>, it outputs :</p>
<pre><code>0
0;8
1;13
2;2;5
1</code></pre>
<p>We can see the following distinction :</p>
<ul>
<li>0-ary constructors (<code>Empty</code> and <code>FullRange</code>) are encoded are simple
integers.</li>
<li>other ones are encoded blocks with a constructor number as tag (0 for
<code>HalfLeft</code>, 1 for <code>HalfRight</code> and 2 for <code>Range</code>) and their argument list
afterwards.</li>
</ul>
<p>Thanks to this uniform representation, pattern-matching is straightforward : the
runtime system will only look at the tag number to decide which constructor has
been used, and if there are arguments to be bound, they are just after in the
same block.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Algebraic Data Types are a simple model of disjoint unions, for which
case analyses are the most natural. In more mainstream languages, some
alternatives exist but they are more limited to model the same problem.</p>
<p>For example, in object-oriented languages, the Visitor pattern is the natural
way to do it. But class trees are inherently “open”, thus breaking the
exhaustivity property.</p>
<p>The closest implementation is tagged unions in C, but they require to roll your
own solution using <code>enum</code>s, <code>struct</code>s and <code>union</code>s. This also means that all
your hand-allocated blocks will have the same size.</p>
<p>Oh, and I would love to know how this problem is solved with other paradigms !</p>
<section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>Unfortunately, so is <code>Range (10, 2)</code>. The invariant that a ≤ b has to be
enforced by the programmer when using this constructor.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2"><p>For 0-ary constructors, the type has to be <code>unit -&gt; 'a</code> instead of <code>'a</code> to
allow side effects to happen during pattern matching.<a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn3"><p>More precisely, we would have to show that any function written with
pattern matching can be adapted to use the deconstructor instead. I hope
that this example is general enough to get the idea.<a href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>]]></description>
    <pubDate>Wed, 14 Dec 2011 00:00:00 UT</pubDate>
    <guid>http://blog.emillon.org/posts/2011-12-14-what-s-in-an-adt.html</guid>
    <dc:creator>Etienne Millon</dc:creator>
</item>
<item>
    <title>Comonadic Life</title>
    <link>http://blog.emillon.org/posts/2012-10-18-comonadic-life.html</link>
    <description><![CDATA[<h2 id="of-monads-and-comonads">Of monads and comonads</h2>
<p>This post is written in <a href="http://www.haskell.org/haskellwiki/Literate_programming">Literate Haskell</a>. This means that you can copy it into
a <code>.lhs</code> file<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a> and run it through a Haskell compiler or interpreter.</p>
<p>Today we’ll talk about…</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Control.Comonad</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Control.Monad</span></span></code></pre></div>
<p>Comonads ! They are the categoric dual of monads, which means that the type
signatures of comonadic functions look like monadic functions, but with the
arrow reversed. I am not an expert in category theory, so I won’t go further.</p>
<p>I will use the following typeclass for comonads : it’s from <a href="http://comonad.com">Edward Kmett</a>’s
<a href="http://hackage.haskell.org/package/comonad-3.0.0.2/docs/Control-Comonad.html">comonad package</a> (split from the infamous <a href="http://hackage.haskell.org/package/category-extras-1.0.2">category-extras package</a>).</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Functor</span> w <span class="ot">=&gt;</span> <span class="dt">Comonad</span> w <span class="kw">where</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  extract ::</span> w a <span class="ot">-&gt;</span> a</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  extend ::</span> (w a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> w a <span class="ot">-&gt;</span> w b</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="ot">  duplicate ::</span> w a <span class="ot">-&gt;</span> w (w a)</span></code></pre></div>
<p><code>extend</code> or <code>duplicate</code> are optional, as one can be written in terms of the
other one. The Monad typeclass, for reference, can be described as<a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a> :</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Functor</span> m <span class="ot">=&gt;</span> <span class="dt">Monad</span> m <span class="kw">where</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  return ::</span> a <span class="ot">-&gt;</span> m a</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  (=&lt;&lt;) ::</span> (a <span class="ot">-&gt;</span> m b) <span class="ot">-&gt;</span> m a <span class="ot">-&gt;</span> m b</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="ot">  join ::</span> m (m a) <span class="ot">-&gt;</span> m a</span></code></pre></div>
<p>The duality is quite easy to see : <code>extract</code> is the dual of <code>return</code>, <code>extend</code>
the one of <code>(=&lt;&lt;)</code> and <code>duplicate</code> the one of <code>join</code>.</p>
<p>So what are comonads good for ?</p>
<p>I stumbled upon <a href="http://blog.sigfpe.com/2006/12/evaluating-cellular-automata-is.html">an article</a> which explains that they can be
used for computations which depend on some local environment, like <a href="http://en.wikipedia.org/wiki/Cellular_automaton">cellular
automata</a>. Comments ask whether it’s possible to generalize to higher
dimensions, which I will do by implementing <a href="http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life">Conway’s Game of Life</a> in a
comonadic way.</p>
<h2 id="list-zippers">List Zippers</h2>
<p>List zippers are a fantastic data structure, allowing O(1) edits at a “cursor”.
Moving the cursor element to element is O(1) too. This makes it a very nice data
structure when your edits are local (say, in a text editor). You can learn more
about zippers in general in this <a href="http://blog.ezyang.com/2010/04/you-could-have-invented-zippers/">post from Edward Z Yang</a>. The seminal paper is
of course <a href="http://www.st.cs.uni-saarland.de/edu/seminare/2005/advanced-fp/docs/huet-zipper.pdf">Huet’s article</a>.</p>
<p>A list zipper is composed of a cursor and two lists.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">ListZipper</span> a <span class="ot">=</span> <span class="dt">LZ</span> [a] a [a]</span></code></pre></div>
<p>To go in a direction, you pick the head of a list, set it as your cursor, and
push the cursor on top of the other list. We assume that we will only infinte
lists, so this operation can not fail. This assumption is reasonnable especially
in the context of cellular automata<a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a>.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ot">listLeft ::</span> <span class="dt">ListZipper</span> a <span class="ot">-&gt;</span> <span class="dt">ListZipper</span> a</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>listLeft (<span class="dt">LZ</span> (l<span class="op">:</span>ls) x rs) <span class="ot">=</span> <span class="dt">LZ</span> ls l (x<span class="op">:</span>rs)</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>listLeft _ <span class="ot">=</span> <span class="fu">error</span> <span class="st">&quot;listLeft&quot;</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="ot">listRight ::</span> <span class="dt">ListZipper</span> a <span class="ot">-&gt;</span> <span class="dt">ListZipper</span> a</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>listRight (<span class="dt">LZ</span> ls x (r<span class="op">:</span>rs)) <span class="ot">=</span> <span class="dt">LZ</span> (x<span class="op">:</span>ls) r rs</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>listRight _ <span class="ot">=</span> <span class="fu">error</span> <span class="st">&quot;listRight&quot;</span></span></code></pre></div>
<p>Reading and writing on a list zipper at the cursor is straightforward :</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">listRead ::</span> <span class="dt">ListZipper</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>listRead (<span class="dt">LZ</span> _ x _) <span class="ot">=</span> x</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="ot">listWrite ::</span> a <span class="ot">-&gt;</span> <span class="dt">ListZipper</span> a <span class="ot">-&gt;</span> <span class="dt">ListZipper</span> a</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>listWrite x (<span class="dt">LZ</span> ls _ rs) <span class="ot">=</span> <span class="dt">LZ</span> ls x rs</span></code></pre></div>
<p>We can also define a function to convert a list zipper to a list, for example
for printing. As it’s infinite on both sizes, it’s not possible to convert it to
the whole list, so we have to pass a size parameter.</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">toList ::</span> <span class="dt">ListZipper</span> a <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> [a]</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>toList (<span class="dt">LZ</span> ls x rs) n <span class="ot">=</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">reverse</span> (<span class="fu">take</span> n ls) <span class="op">++</span> [x] <span class="op">++</span> <span class="fu">take</span> n rs</span></code></pre></div>
<p>We can easily define a <code>Functor</code> instance for <code>ListZipper</code>. To apply a function
on whole zipper, we apply it to the cursor and map it on the two lists :</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> <span class="dt">ListZipper</span> <span class="kw">where</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fmap</span> f (<span class="dt">LZ</span> ls x rs) <span class="ot">=</span> <span class="dt">LZ</span> (<span class="fu">map</span> f ls) (f x) (<span class="fu">map</span> f rs)</span></code></pre></div>
<p>Time for the <code>Comonad</code> instance. The <code>extract</code> method returns an element from
the structure : we can pick the one at the cursor.</p>
<p><code>duplicate</code> is a bit harder to grasp. From a list zipper, we have to build a
list zipper of list zippers. The signification behind this (confirmed by the
comonad laws that every instance has to fulfill) is that moving inside the
duplicated structure returns the original structure, altered by the same
move : for example, <code>listRead (listLeft (duplicate z)) == listLeft z</code>.</p>
<p>This means that at the cursor of the duplicated structure, there is the original
structure <code>z</code>. And the left list is composed of <code>listLeft z</code>, <code>listLeft (listLeft z)</code>, <code>listLeft (listLeft (listLeft z))</code>, etc (same goes for the right
list).</p>
<p>The following function applies repeatedly two movement functions on each side of
the zipper (its type is more generic than needed for this specific case but
we’ll instanciate <code>z</code> with something other than <code>ListZipper</code> in the next
section).</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ot">genericMove ::</span> (z a <span class="ot">-&gt;</span> z a)</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>            <span class="ot">-&gt;</span> (z a <span class="ot">-&gt;</span> z a)</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>            <span class="ot">-&gt;</span> z a</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>            <span class="ot">-&gt;</span> <span class="dt">ListZipper</span> (z a)</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>genericMove a b z <span class="ot">=</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">LZ</span> (iterate&#39; a z) z (iterate&#39; b z)</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a><span class="ot">iterate&#39; ::</span> (a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>iterate&#39; f <span class="ot">=</span> <span class="fu">tail</span> <span class="op">.</span> <span class="fu">iterate</span> f</span></code></pre></div>
<p>And finally we can implement the instance.</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Comonad</span> <span class="dt">ListZipper</span> <span class="kw">where</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  extract <span class="ot">=</span> listRead</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>  duplicate <span class="ot">=</span> genericMove listLeft listRight</span></code></pre></div>
<p>Using this comonad instance we can already implement 1D cellular automata, as
explained in the <a href="http://blog.sigfpe.com/2006/12/evaluating-cellular-automata-is.html">sigfpe article</a>. Let’s see how they can be extended to 2D
automata.</p>
<h2 id="plane-zippers">Plane zippers</h2>
<p>Let’s generalize list zippers to plane zippers, which are cursors on a plane
of cells. We will implement them using a list zipper of list zippers.</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Z</span> a <span class="ot">=</span> <span class="dt">Z</span> (<span class="dt">ListZipper</span> (<span class="dt">ListZipper</span> a))</span></code></pre></div>
<p>We start by defining move functions. As a convention, the external list will
hold lines : to move up and down, we will really move left and right at the root
level.</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ot">up ::</span> <span class="dt">Z</span> a <span class="ot">-&gt;</span> <span class="dt">Z</span> a</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>up (<span class="dt">Z</span> z) <span class="ot">=</span> <span class="dt">Z</span> (listLeft z)</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a><span class="ot">down ::</span> <span class="dt">Z</span> a <span class="ot">-&gt;</span> <span class="dt">Z</span> a</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>down (<span class="dt">Z</span> z) <span class="ot">=</span> <span class="dt">Z</span> (listRight z)</span></code></pre></div>
<p>For left and right, it is necessary to alter every line, using the <code>Functor</code>
instance.</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ot">left ::</span> <span class="dt">Z</span> a <span class="ot">-&gt;</span> <span class="dt">Z</span> a</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>left (<span class="dt">Z</span> z) <span class="ot">=</span> <span class="dt">Z</span> (<span class="fu">fmap</span> listLeft z)</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a><span class="ot">right ::</span> <span class="dt">Z</span> a <span class="ot">-&gt;</span> <span class="dt">Z</span> a</span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>right (<span class="dt">Z</span> z) <span class="ot">=</span> <span class="dt">Z</span> (<span class="fu">fmap</span> listRight z)</span></code></pre></div>
<p>Finally, editing is quite straightforward : reading is direct (first read the line,
then the cursor) ; and in order to write, it is necessary to fetch the current
line, write to it and write the new line.</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ot">zRead ::</span> <span class="dt">Z</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>zRead (<span class="dt">Z</span> z) <span class="ot">=</span> listRead <span class="op">$</span> listRead z</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a><span class="ot">zWrite ::</span> a <span class="ot">-&gt;</span> <span class="dt">Z</span> a <span class="ot">-&gt;</span> <span class="dt">Z</span> a</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>zWrite x (<span class="dt">Z</span> z) <span class="ot">=</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Z</span> <span class="op">$</span> listWrite newLine z</span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>      newLine <span class="ot">=</span> listWrite x oldLine</span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a>      oldLine <span class="ot">=</span> listRead z</span></code></pre></div>
<p>Time for algebra. Let’s define a <code>Functor</code> instance : applying a function
everywhere can be achieved by applying it on every line.</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> <span class="dt">Z</span> <span class="kw">where</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fmap</span> f (<span class="dt">Z</span> z) <span class="ot">=</span> <span class="dt">Z</span> (<span class="fu">fmap</span> (<span class="fu">fmap</span> f) z)</span></code></pre></div>
<p>The idea behind the <code>Comonad</code> instance for <code>Z</code> is the same that the <code>ListZipper</code>
one : moving “up” in the structure (really, “left” at the root level) returns
the original structure moved in this direction.</p>
<p>We will reuse the <code>genericMove</code> defined earlier in order to build list zippers
that describe movements in the two axes<a href="#fn4" class="footnote-ref" id="fnref4" role="doc-noteref"><sup>4</sup></a>.</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ot">horizontal ::</span> <span class="dt">Z</span> a <span class="ot">-&gt;</span> <span class="dt">ListZipper</span> (<span class="dt">Z</span> a)</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>horizontal <span class="ot">=</span> genericMove left right</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a><span class="ot">vertical ::</span> <span class="dt">Z</span> a <span class="ot">-&gt;</span> <span class="dt">ListZipper</span> (<span class="dt">Z</span> a)</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>vertical <span class="ot">=</span> genericMove up down</span></code></pre></div>
<p>This is enough to define the instance.</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Comonad</span> <span class="dt">Z</span> <span class="kw">where</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>  extract <span class="ot">=</span> zRead</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>  duplicate z <span class="ot">=</span></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Z</span> <span class="op">$</span> <span class="fu">fmap</span> horizontal <span class="op">$</span> vertical z</span></code></pre></div>
<h2 id="conways-comonadic-game-of-life">Conway’s (comonadic) Game of Life</h2>
<p>Let’s define a neighbourhood function. Here, directions are moves on a plane
zipper. Neighbours are : horizontal moves, vertical moves and their
compositions (<code>liftM2 (.)</code>)<a href="#fn5" class="footnote-ref" id="fnref5" role="doc-noteref"><sup>5</sup></a>.</p>
<div class="sourceCode" id="cb18"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="ot">neighbours ::</span> [<span class="dt">Z</span> a <span class="ot">-&gt;</span> <span class="dt">Z</span> a]</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>neighbours <span class="ot">=</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>  horiz <span class="op">++</span> vert <span class="op">++</span> liftM2 (<span class="op">.</span>) horiz vert</span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>      horiz <span class="ot">=</span> [left, right]</span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a>      vert  <span class="ot">=</span> [up, down]</span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a><span class="ot">aliveNeighbours ::</span> <span class="dt">Z</span> <span class="dt">Bool</span> <span class="ot">-&gt;</span> <span class="dt">Int</span></span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a>aliveNeighbours z <span class="ot">=</span></span>
<span id="cb18-10"><a href="#cb18-10" aria-hidden="true" tabindex="-1"></a>  card <span class="op">$</span> <span class="fu">map</span> (\ dir <span class="ot">-&gt;</span> extract <span class="op">$</span> dir z) neighbours</span>
<span id="cb18-11"><a href="#cb18-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-12"><a href="#cb18-12" aria-hidden="true" tabindex="-1"></a><span class="ot">card ::</span> [<span class="dt">Bool</span>] <span class="ot">-&gt;</span> <span class="dt">Int</span></span>
<span id="cb18-13"><a href="#cb18-13" aria-hidden="true" tabindex="-1"></a>card <span class="ot">=</span> <span class="fu">length</span> <span class="op">.</span> <span class="fu">filter</span> (<span class="op">==</span><span class="dt">True</span>)</span></code></pre></div>
<p>The core rule of the game fits in the following function : if two neighbours are
alive, return the previous state ; if three neighbours are alive, a new cell is
born, and any other count causes the cell to die (of under-population or
overcrowding).</p>
<p>It is remarkable that its type is the dual of that of a Kleisli arrow (<code>a -&gt; m b</code>).</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="ot">rule ::</span> <span class="dt">Z</span> <span class="dt">Bool</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>rule z <span class="ot">=</span></span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">case</span> aliveNeighbours z <span class="kw">of</span></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>    <span class="dv">2</span> <span class="ot">-&gt;</span> extract z</span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>    <span class="dv">3</span> <span class="ot">-&gt;</span> <span class="dt">True</span></span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a>    _ <span class="ot">-&gt;</span> <span class="dt">False</span></span></code></pre></div>
<p>And then the comonadic magic happens with the use of <code>extend</code> :</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="ot">evolve ::</span> <span class="dt">Z</span> <span class="dt">Bool</span> <span class="ot">-&gt;</span> <span class="dt">Z</span> <span class="dt">Bool</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>evolve <span class="ot">=</span> extend rule</span></code></pre></div>
<p><code>evolve</code> is our main transition function between world states, and yet it’s only
defined in terms of the local transition function !</p>
<p>Let’s define a small printer to see what’s going on.</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="ot">dispLine ::</span> <span class="dt">ListZipper</span> <span class="dt">Bool</span> <span class="ot">-&gt;</span> <span class="dt">String</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>dispLine z <span class="ot">=</span></span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">map</span> dispC <span class="op">$</span> toList z <span class="dv">6</span></span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a>      dispC <span class="dt">True</span>  <span class="ot">=</span> <span class="ch">&#39;*&#39;</span></span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a>      dispC <span class="dt">False</span> <span class="ot">=</span> <span class="ch">&#39; &#39;</span></span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a><span class="ot">disp ::</span> <span class="dt">Z</span> <span class="dt">Bool</span> <span class="ot">-&gt;</span> <span class="dt">String</span></span>
<span id="cb21-9"><a href="#cb21-9" aria-hidden="true" tabindex="-1"></a>disp (<span class="dt">Z</span> z) <span class="ot">=</span></span>
<span id="cb21-10"><a href="#cb21-10" aria-hidden="true" tabindex="-1"></a>  <span class="fu">unlines</span> <span class="op">$</span> <span class="fu">map</span> dispLine <span class="op">$</span> toList z <span class="dv">6</span></span></code></pre></div>
<p>Here is the classic glider pattern to test. The definition has a lot of
boilerplate because we did not bother to create a <code>fromList</code> function.</p>
<div class="sourceCode" id="cb22"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="ot">glider ::</span> <span class="dt">Z</span> <span class="dt">Bool</span></span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a>glider <span class="ot">=</span></span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Z</span> <span class="op">$</span> <span class="dt">LZ</span> (<span class="fu">repeat</span> fz) fz rs</span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a>      rs <span class="ot">=</span> [ line [f, t, f]</span>
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a>           , line [f, f, t]</span>
<span id="cb22-7"><a href="#cb22-7" aria-hidden="true" tabindex="-1"></a>           , line [t, t, t]</span>
<span id="cb22-8"><a href="#cb22-8" aria-hidden="true" tabindex="-1"></a>           ] <span class="op">++</span> <span class="fu">repeat</span> fz</span>
<span id="cb22-9"><a href="#cb22-9" aria-hidden="true" tabindex="-1"></a>      t <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb22-10"><a href="#cb22-10" aria-hidden="true" tabindex="-1"></a>      f <span class="ot">=</span> <span class="dt">False</span></span>
<span id="cb22-11"><a href="#cb22-11" aria-hidden="true" tabindex="-1"></a>      fl <span class="ot">=</span> <span class="fu">repeat</span> f</span>
<span id="cb22-12"><a href="#cb22-12" aria-hidden="true" tabindex="-1"></a>      fz <span class="ot">=</span> <span class="dt">LZ</span> fl f fl</span>
<span id="cb22-13"><a href="#cb22-13" aria-hidden="true" tabindex="-1"></a>      line l <span class="ot">=</span></span>
<span id="cb22-14"><a href="#cb22-14" aria-hidden="true" tabindex="-1"></a>        <span class="dt">LZ</span> fl f (l <span class="op">++</span> fl)</span></code></pre></div>
<pre><code>*Main&gt; putStr $ disp glider
             
             
             
             
             
             
             
        *    
         *   
       ***   
             
             
             
*Main&gt; putStr $ disp $ evolve glider
             
             
             
             
             
             
             
             
       * *   
        **   
        *    
             
             </code></pre>
<p>We did it ! Implementing Conway’s Game of Life is usually full of ad-hoc
boilerplate code : iterating loops, managing copies of cells, etc. Using the
comonadic structure of cellular automata, the code can be a lot simpler.</p>
<p>In this example, <code>ListZipper</code> and <code>Z</code> should be library functions, so the actual
implementation is only a dozen lines long!</p>
<p>The real benefit is that it has really helped be grasp the concept of comonads.
I hope that I did not just fall into the comonad tutorial fallacy :)</p>
<p><strong>Update (March 10th):</strong> Brian Cohen contributed <a href="http://lpaste.net/83811">a simple extension to simulate
a closed topology</a>. Thanks !</p>
<section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>Or download the <a href="https://github.com/emillon/blog.emillon.org">source on github</a>.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2"><p>In the real Haskell typeclass, there are the following differences: Monad
and Functor are not related, <code>join</code> is a library function (you can’t use
it to define an instance), <code>(&gt;&gt;=)</code> is used instead of its flipped
counterpart <code>(=&lt;&lt;)</code> and there two more methods <code>(&gt;&gt;)</code> and <code>fail</code>.<a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn3"><p>Simulating a closed topology such as a torus may even be possible using
cyclic lists instead of lazy infinite lists.
<strong>Update:</strong> see Brian Cohen’s response at the end of this post.<a href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn4"><p>At first I thought that it was possible to only use the <code>Comonad</code> instance
of <code>ListZipper</code> to define <code>horizontal</code> and <code>vertical</code>, but I couldn’t come
up with a solution. But in that case, the <code>z</code> generic parameter is
instanciated to <code>Z</code>, not <code>ListZipper</code>. For that reason I believe that my
initial thought can’t be implemented. Maybe it’s possible with a comonad
transformer or something like that.<a href="#fnref4" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn5"><p>This could have been written in extension as there are only 8 cases, but
it’s funnier and arguably less error prone this way :-)<a href="#fnref5" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>]]></description>
    <pubDate>Thu, 18 Oct 2012 00:00:00 UT</pubDate>
    <guid>http://blog.emillon.org/posts/2012-10-18-comonadic-life.html</guid>
    <dc:creator>Etienne Millon</dc:creator>
</item>
<item>
    <title>A lens-based ST20 emulator</title>
    <link>http://blog.emillon.org/posts/2015-08-20-a-lens-based-st20-emulator.html</link>
    <description><![CDATA[<p>Every year, as part of the <a href="https://www.sstic.org/">SSTIC conference</a>, there is
a forensics/reverse engineering challenge. I participated in the 2015 edition.
Though I did not manage to complete it, I made an emulator for the exotic ST20
architecture, which is probably worth describing here.</p>
<figure>
<img src="/img/st20/t00f.png" alt="Some programs will loop. It’s OK." />
<figcaption aria-hidden="true">Some programs will loop. It’s OK.</figcaption>
</figure>
<p>Note that this emulator is not really optimized for pure speed. In the actual
challenge I actually had to rewrite it as pure Haskell (i.e., removing the
emulation part) so that it was faster. Instead, the goal of this article is to
show a few techniques to write powerful emulators in Haskell.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE GeneralizedNewtypeDeriving #-}</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE Rank2Types #-}</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE TemplateHaskell #-}</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Control.Applicative</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Control.Concurrent</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Control.Monad.RWS</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Control.Lens</span> <span class="kw">hiding</span> (imap, op)</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Bits</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Int</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Maybe</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Word</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Numeric</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">System.Exit</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">System.IO</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Text.Printf</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Data.ByteString</span> <span class="kw">as</span> <span class="dt">BS</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Data.Map</span> <span class="kw">as</span> <span class="dt">M</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Data.Set</span> <span class="kw">as</span> <span class="dt">S</span></span></code></pre></div>
<h2 id="the-evaluation-monad">The evaluation monad</h2>
<p>This program uses Template Haskell to define lenses, so unfortunately we need to
start with a few type definitions.</p>
<p>The ST20’s memory goes from <code>0x80000000</code> to <code>0x7fffffff</code>:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Address</span> <span class="ot">=</span> <span class="dt">Int32</span></span></code></pre></div>
<p>We’ll represent the memory using a map. The performance is surprisingly close to
that of an array. It is possible to get significantly speeds up memory access by
using an <code>IOUArray</code> but it turns loads and stores become monadic operations and
makes it impossible to use lenses.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Mem</span> <span class="ot">=</span> <span class="dt">M.Map</span> <span class="dt">Address</span> <span class="dt">Word8</span></span></code></pre></div>
<p>As we’ll see, <em>transputers</em> (hardware threads) can communicate together. We’ll
be able to connect it either between them, or to a tty.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">IChannel</span> <span class="ot">=</span> <span class="dt">InChan</span> (<span class="dt">Chan</span> <span class="dt">Word8</span>)</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>              <span class="op">|</span> <span class="dt">InHandle</span> <span class="dt">Handle</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">OChannel</span> <span class="ot">=</span> <span class="dt">OutChan</span> (<span class="dt">Chan</span> <span class="dt">Word8</span>)</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>              <span class="op">|</span> <span class="dt">OutHandle</span> <span class="dt">Handle</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">IChannelMap</span> <span class="ot">=</span> [(<span class="dt">Int32</span>, <span class="dt">IChannel</span>)]</span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">OChannelMap</span> <span class="ot">=</span> [(<span class="dt">Int32</span>, <span class="dt">OChannel</span>)]</span></code></pre></div>
<p>All evaluations take place in a <code>Eval</code> Monad which is a monad transformer stack
with the following capabilities:</p>
<ul>
<li>read and write an <code>EvalState</code> value;</li>
<li>read an <code>EvalEnv</code> value</li>
<li>do some I/O.</li>
</ul>
<div class="sourceCode" id="cb5"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Eval</span> a <span class="ot">=</span> <span class="dt">Eval</span> (<span class="dt">RWST</span> <span class="dt">EvalEnv</span> () <span class="dt">EvalState</span> <span class="dt">IO</span> a)</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">deriving</span> ( <span class="dt">Functor</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>             , <span class="dt">Monad</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>             , <span class="dt">MonadIO</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>             , <span class="dt">MonadReader</span> <span class="dt">EvalEnv</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>             , <span class="dt">MonadState</span> <span class="dt">EvalState</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>             )</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">EvalEnv</span> <span class="ot">=</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>    <span class="dt">EvalEnv</span></span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>        {<span class="ot"> envInChans ::</span> <span class="dt">IChannelMap</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>        ,<span class="ot"> envOutChans ::</span> <span class="dt">OChannelMap</span></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>        }</span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">EvalState</span> <span class="ot">=</span></span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true" tabindex="-1"></a>    <span class="dt">EvalState</span></span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true" tabindex="-1"></a>        {<span class="ot"> _iptr ::</span> <span class="op">!</span><span class="dt">Address</span></span>
<span id="cb5-18"><a href="#cb5-18" aria-hidden="true" tabindex="-1"></a>        ,<span class="ot"> _intStack ::</span> [<span class="dt">Int32</span>]</span>
<span id="cb5-19"><a href="#cb5-19" aria-hidden="true" tabindex="-1"></a>        ,<span class="ot"> _wptr ::</span> <span class="op">!</span><span class="dt">Int32</span></span>
<span id="cb5-20"><a href="#cb5-20" aria-hidden="true" tabindex="-1"></a>        ,<span class="ot"> _mem ::</span> <span class="op">!</span><span class="dt">Mem</span></span>
<span id="cb5-21"><a href="#cb5-21" aria-hidden="true" tabindex="-1"></a>        }</span>
<span id="cb5-22"><a href="#cb5-22" aria-hidden="true" tabindex="-1"></a><span class="op">$</span>(makeLenses &#39;<span class="dt">&#39;EvalState</span>)</span>
<span id="cb5-23"><a href="#cb5-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-24"><a href="#cb5-24" aria-hidden="true" tabindex="-1"></a><span class="ot">runEval ::</span> <span class="dt">Mem</span> <span class="ot">-&gt;</span> <span class="dt">IChannelMap</span> <span class="ot">-&gt;</span> <span class="dt">OChannelMap</span> <span class="ot">-&gt;</span> <span class="dt">Eval</span> a <span class="ot">-&gt;</span> <span class="dt">IO</span> a</span>
<span id="cb5-25"><a href="#cb5-25" aria-hidden="true" tabindex="-1"></a>runEval memory imap omap (<span class="dt">Eval</span> m) <span class="ot">=</span></span>
<span id="cb5-26"><a href="#cb5-26" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fst</span> <span class="op">&lt;$&gt;</span> evalRWST m env st</span>
<span id="cb5-27"><a href="#cb5-27" aria-hidden="true" tabindex="-1"></a>        <span class="kw">where</span></span>
<span id="cb5-28"><a href="#cb5-28" aria-hidden="true" tabindex="-1"></a>            env <span class="ot">=</span> <span class="dt">EvalEnv</span> imap omap</span>
<span id="cb5-29"><a href="#cb5-29" aria-hidden="true" tabindex="-1"></a>            st <span class="ot">=</span></span>
<span id="cb5-30"><a href="#cb5-30" aria-hidden="true" tabindex="-1"></a>                 <span class="dt">EvalState</span></span>
<span id="cb5-31"><a href="#cb5-31" aria-hidden="true" tabindex="-1"></a>                     { _iptr <span class="ot">=</span> memStart</span>
<span id="cb5-32"><a href="#cb5-32" aria-hidden="true" tabindex="-1"></a>                     , _intStack <span class="ot">=</span> []</span>
<span id="cb5-33"><a href="#cb5-33" aria-hidden="true" tabindex="-1"></a>                     , _wptr <span class="ot">=</span> <span class="bn">0xaaaaaaaa</span></span>
<span id="cb5-34"><a href="#cb5-34" aria-hidden="true" tabindex="-1"></a>                     , _mem <span class="ot">=</span> memory</span>
<span id="cb5-35"><a href="#cb5-35" aria-hidden="true" tabindex="-1"></a>                     }</span></code></pre></div>
<p>The above <code>$(...)</code> is a Template Haskell splice. It creates <em>lenses</em> based on
the record declaration of <code>EvalState</code>. Lenses are a very powerful tool that
makes it possible to compose record reads and updates in a functional way. Here,
it defines a lens for each record field; for example, the splice expands to a
top-level declaration <code>iptr :: Lens' EvalState Address</code>. But we will define our
own lenses too, and everything will remain composable.</p>
<h2 id="memory">Memory</h2>
<p>This is naturally adapted to byte access:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">memByteOpt ::</span> <span class="dt">Address</span> <span class="ot">-&gt;</span> <span class="dt">Lens&#39;</span> <span class="dt">EvalState</span> (<span class="dt">Maybe</span> <span class="dt">Word8</span>)</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>memByteOpt addr <span class="ot">=</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>  mem <span class="op">.</span> at addr</span></code></pre></div>
<p>See? We composed the <code>mem</code> lens (between an evaluation state and a memory state) with <code>at addr</code>, which is a lens between a memory state and the value at address <code>addr</code>.
Well, not exactly: <code>at</code> actually returns a <code>Maybe Word8</code>. We will assume that
all memory accesses will succeed, so we want a lens that returns a plain
<code>Word8</code>. To achieve this, we can compose with a lens that treats <code>Maybe a</code> as a
container of <code>a</code>:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeLens ::</span> <span class="dt">Lens&#39;</span> (<span class="dt">Maybe</span> a) a</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>maybeLens <span class="ot">=</span> lens fromJust (<span class="fu">const</span> <span class="dt">Just</span>)</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a><span class="ot">memByte ::</span> <span class="dt">Address</span> <span class="ot">-&gt;</span> <span class="dt">Lens&#39;</span> <span class="dt">EvalState</span> <span class="dt">Word8</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>memByte addr <span class="ot">=</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>  memByteOpt addr <span class="op">.</span> maybeLens</span></code></pre></div>
<p>Sometimes we will also need to access memory word by word. To achieve that, we
first define conversion functions.</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bytesToWord ::</span> (<span class="dt">Word8</span>, <span class="dt">Word8</span>, <span class="dt">Word8</span>, <span class="dt">Word8</span>) <span class="ot">-&gt;</span> <span class="dt">Int32</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>bytesToWord (b0, b1, b2, b3) <span class="ot">=</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">sum</span> [ <span class="fu">fromIntegral</span> b0</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>        , <span class="fu">fromIntegral</span> b1 <span class="ot">`shiftL`</span> <span class="dv">8</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>        , <span class="fu">fromIntegral</span> b2 <span class="ot">`shiftL`</span> <span class="dv">16</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>        , <span class="fu">fromIntegral</span> b3 <span class="ot">`shiftL`</span> <span class="dv">24</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>        ]</span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a><span class="ot">wordToBytes ::</span> <span class="dt">Int32</span> <span class="ot">-&gt;</span> (<span class="dt">Word8</span>, <span class="dt">Word8</span>, <span class="dt">Word8</span>, <span class="dt">Word8</span>)</span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>wordToBytes w <span class="ot">=</span></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>    (b0, b1, b2, b3)</span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>        <span class="kw">where</span></span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>            b0 <span class="ot">=</span> <span class="fu">fromIntegral</span> <span class="op">$</span> w <span class="op">.&amp;.</span> <span class="bn">0x000000ff</span></span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a>            b1 <span class="ot">=</span> <span class="fu">fromIntegral</span> <span class="op">$</span> (w <span class="op">.&amp;.</span> <span class="bn">0x0000ff00</span>) <span class="ot">`shiftR`</span> <span class="dv">8</span></span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>            b2 <span class="ot">=</span> <span class="fu">fromIntegral</span> <span class="op">$</span> (w <span class="op">.&amp;.</span> <span class="bn">0x00ff0000</span>) <span class="ot">`shiftR`</span> <span class="dv">16</span></span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a>            b3 <span class="ot">=</span> <span class="fu">fromIntegral</span> <span class="op">$</span> (w <span class="op">.&amp;.</span> <span class="bn">0xff000000</span>) <span class="ot">`shiftR`</span> <span class="dv">24</span></span></code></pre></div>
<p>Then, we can define a lens focusing on a 32-bit value.</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ot">compose ::</span> [a <span class="ot">-&gt;</span> a] <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>compose <span class="ot">=</span> <span class="fu">foldr</span> (<span class="op">.</span>) <span class="fu">id</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a><span class="ot">get32 ::</span> <span class="dt">Address</span> <span class="ot">-&gt;</span> <span class="dt">EvalState</span> <span class="ot">-&gt;</span> <span class="dt">Int32</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>get32 base s <span class="ot">=</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>    bytesToWord (b0, b1, b2, b3)</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>        <span class="kw">where</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>            b0 <span class="ot">=</span> s <span class="op">^.</span> memByte base</span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>            b1 <span class="ot">=</span> s <span class="op">^.</span> memByte (base <span class="op">+</span> <span class="dv">1</span>)</span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a>            b2 <span class="ot">=</span> s <span class="op">^.</span> memByte (base <span class="op">+</span> <span class="dv">2</span>)</span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a>            b3 <span class="ot">=</span> s <span class="op">^.</span> memByte (base <span class="op">+</span> <span class="dv">3</span>)</span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a><span class="ot">set32 ::</span> <span class="dt">Address</span> <span class="ot">-&gt;</span> <span class="dt">EvalState</span> <span class="ot">-&gt;</span> <span class="dt">Int32</span> <span class="ot">-&gt;</span> <span class="dt">EvalState</span></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a>set32 base s v <span class="ot">=</span></span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true" tabindex="-1"></a>   compose</span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a>       [ set (memByte base) b0</span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true" tabindex="-1"></a>       , set (memByte (base <span class="op">+</span> <span class="dv">1</span>)) b1</span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true" tabindex="-1"></a>       , set (memByte (base <span class="op">+</span> <span class="dv">2</span>)) b2</span>
<span id="cb9-19"><a href="#cb9-19" aria-hidden="true" tabindex="-1"></a>       , set (memByte (base <span class="op">+</span> <span class="dv">3</span>)) b3</span>
<span id="cb9-20"><a href="#cb9-20" aria-hidden="true" tabindex="-1"></a>       ] s</span>
<span id="cb9-21"><a href="#cb9-21" aria-hidden="true" tabindex="-1"></a>        <span class="kw">where</span></span>
<span id="cb9-22"><a href="#cb9-22" aria-hidden="true" tabindex="-1"></a>            (b0, b1, b2, b3) <span class="ot">=</span> wordToBytes v</span>
<span id="cb9-23"><a href="#cb9-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-24"><a href="#cb9-24" aria-hidden="true" tabindex="-1"></a><span class="ot">memWord ::</span> <span class="dt">Address</span> <span class="ot">-&gt;</span> <span class="dt">Lens&#39;</span> <span class="dt">EvalState</span> <span class="dt">Int32</span></span>
<span id="cb9-25"><a href="#cb9-25" aria-hidden="true" tabindex="-1"></a>memWord addr <span class="ot">=</span> lens (get32 addr) (set32 addr)</span></code></pre></div>
<p>The instruction set reference defines a handy operator to shift an address by a
word offset:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ot">(@@) ::</span> <span class="dt">Address</span> <span class="ot">-&gt;</span> <span class="dt">Int32</span> <span class="ot">-&gt;</span> <span class="dt">Address</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>a <span class="op">@@</span> n <span class="ot">=</span> a <span class="op">+</span> <span class="dv">4</span> <span class="op">*</span> n</span></code></pre></div>
<p>It will be also handy to access the memory in list chunks:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ot">mem8s ::</span> <span class="dt">Address</span> <span class="ot">-&gt;</span> <span class="dt">Int32</span> <span class="ot">-&gt;</span> <span class="dt">Lens&#39;</span> <span class="dt">EvalState</span> [<span class="dt">Word8</span>]</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>mem8s base len <span class="ot">=</span> lens getList setList</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>        getList s <span class="ot">=</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>            <span class="fu">map</span> (\ off <span class="ot">-&gt;</span> s <span class="op">^.</span> memByte (base <span class="op">+</span> off)) [<span class="dv">0</span> <span class="op">..</span> len <span class="op">-</span> <span class="dv">1</span>]</span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>        setList s0 ws <span class="ot">=</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a>            compose (<span class="fu">zipWith</span> (\ off w <span class="ot">-&gt;</span> set (memByte (base <span class="op">+</span> off)) w) [<span class="dv">0</span><span class="op">..</span>] ws) s0</span></code></pre></div>
<h2 id="instruction-decoding">Instruction decoding</h2>
<p>Instructions are usually encoded on a single byte: the opcode is in the first
nibble, and a parameter is in the second one. For example this is how a LDC
(load constant) is encoded:</p>
<pre><code>   .--- 0x40 LDC
  |.---          0x5
  ||
0x45         LDC 0x5</code></pre>
<p>This only works for 4-bytes constants. To load bigger constants, there is a
“prefix” operation that will shift the current operand:</p>
<pre><code>   .-------- 0x20 PFX
  |.--------          0x2
  ||
  ||    .--- 0x40 LDC
  ||   |.---          0x5
  ||   ||
0x22 0x45    LDC 0x25</code></pre>
<p>Those are chainable; for example <code>0x21 0x22 0x45</code> encodes <code>LDC 0x125</code>.</p>
<p>Another prefix shifts and complements the current operand value:</p>
<pre><code>   .-------- 0x60 NFX
  |.--------          0x2
  ||
  ||    .--- 0x40 LDC
  ||   |.---          0x5
  ||   ||
0x62 0x45    LDC (~0x25)</code></pre>
<p>The ST20 architecture actually provides two type of instructions:</p>
<ul>
<li>“primary” instructions such as <code>LDC</code>. Their operand is directly encoded.</li>
<li>“secondary” instructions such as <code>MINT</code> (equivalent to <code>LDC 0x80000000</code>).
They do not have operands. On the contrary, they are actually a special case
of the first type, using a special <code>OPR n</code> opcode. For example, <code>MINT</code> is
<code>OPR 0x42</code>, which is encoded using <code>0x24 0xF2</code>.</li>
</ul>
<p>We know enough to draft an instruction decoder.</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">PInstr</span> <span class="ot">=</span> <span class="dt">AJW</span>   <span class="op">|</span> <span class="dt">ADC</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>            <span class="op">|</span> <span class="dt">LDC</span>   <span class="op">|</span> <span class="dt">STL</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>            <span class="op">|</span> <span class="dt">LDL</span>   <span class="op">|</span> <span class="dt">LDNL</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>            <span class="op">|</span> <span class="dt">LDLP</span>  <span class="op">|</span> <span class="dt">LDNLP</span></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>            <span class="op">|</span> <span class="dt">CJ</span>    <span class="op">|</span> <span class="dt">J</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>            <span class="op">|</span> <span class="dt">EQC</span>   <span class="op">|</span> <span class="dt">CALL</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>            <span class="op">|</span> <span class="dt">STNL</span></span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">deriving</span> (<span class="dt">Eq</span>, <span class="dt">Ord</span>, <span class="dt">Show</span>)</span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">SInstr</span> <span class="ot">=</span> <span class="dt">PROD</span>  <span class="op">|</span> <span class="dt">MINT</span>   <span class="op">|</span> <span class="dt">GAJW</span></span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a>            <span class="op">|</span> <span class="dt">LDPI</span>  <span class="op">|</span> <span class="dt">OUT</span>    <span class="op">|</span> <span class="dt">IN</span></span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a>            <span class="op">|</span> <span class="dt">LB</span>    <span class="op">|</span> <span class="dt">XOR</span>    <span class="op">|</span> <span class="dt">SB</span></span>
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a>            <span class="op">|</span> <span class="dt">BSUB</span>  <span class="op">|</span> <span class="dt">SSUB</span>   <span class="op">|</span> <span class="dt">DUP</span></span>
<span id="cb15-14"><a href="#cb15-14" aria-hidden="true" tabindex="-1"></a>            <span class="op">|</span> <span class="dt">GTx</span>   <span class="op">|</span> <span class="dt">WSUB</span>   <span class="op">|</span> <span class="dt">AND</span></span>
<span id="cb15-15"><a href="#cb15-15" aria-hidden="true" tabindex="-1"></a>            <span class="op">|</span> <span class="dt">RET</span>   <span class="op">|</span> <span class="dt">GCALL</span>  <span class="op">|</span> <span class="dt">SHR</span></span>
<span id="cb15-16"><a href="#cb15-16" aria-hidden="true" tabindex="-1"></a>            <span class="op">|</span> <span class="dt">SHL</span>   <span class="op">|</span> <span class="dt">REM</span></span>
<span id="cb15-17"><a href="#cb15-17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">deriving</span> (<span class="dt">Eq</span>, <span class="dt">Ord</span>, <span class="dt">Show</span>)</span>
<span id="cb15-18"><a href="#cb15-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-19"><a href="#cb15-19" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Instr</span> <span class="ot">=</span> <span class="dt">Pri</span> <span class="dt">PInstr</span> <span class="dt">Int32</span></span>
<span id="cb15-20"><a href="#cb15-20" aria-hidden="true" tabindex="-1"></a>           <span class="op">|</span> <span class="dt">Sec</span> <span class="dt">SInstr</span></span>
<span id="cb15-21"><a href="#cb15-21" aria-hidden="true" tabindex="-1"></a>    <span class="kw">deriving</span> (<span class="dt">Eq</span>, <span class="dt">Ord</span>)</span>
<span id="cb15-22"><a href="#cb15-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-23"><a href="#cb15-23" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Show</span> <span class="dt">Instr</span> <span class="kw">where</span></span>
<span id="cb15-24"><a href="#cb15-24" aria-hidden="true" tabindex="-1"></a>    <span class="fu">show</span> (<span class="dt">Pri</span> p n) <span class="ot">=</span> <span class="fu">show</span> p <span class="op">++</span> <span class="st">&quot; &quot;</span> <span class="op">++</span> <span class="fu">show</span> n</span>
<span id="cb15-25"><a href="#cb15-25" aria-hidden="true" tabindex="-1"></a>    <span class="fu">show</span> (<span class="dt">Sec</span> s) <span class="ot">=</span> <span class="fu">show</span> s</span></code></pre></div>
<p>Instruction decoding will need to move within the instruction stream, so it is
part of the evaluation monad.</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ot">decodeInstr ::</span> <span class="dt">Eval</span> <span class="dt">Instr</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>decodeInstr <span class="ot">=</span> decodeInstr_ <span class="dv">0</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a><span class="ot">decodeInstr_ ::</span> <span class="dt">Int32</span> <span class="ot">-&gt;</span> <span class="dt">Eval</span> <span class="dt">Instr</span></span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>decodeInstr_ acc <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>    b <span class="ot">&lt;-</span> peekAndIncr</span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> acc&#39; <span class="ot">=</span> acc <span class="op">+</span> <span class="fu">fromIntegral</span> (b <span class="op">.&amp;.</span> <span class="bn">0xf</span>)</span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">case</span> () <span class="kw">of</span></span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a>        _ <span class="op">|</span> b <span class="op">&lt;=</span> <span class="bn">0x0f</span> <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="op">$</span> <span class="dt">Pri</span> <span class="dt">J</span> acc&#39;</span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a>        _ <span class="op">|</span> b <span class="op">&lt;=</span> <span class="bn">0x1f</span> <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="op">$</span> <span class="dt">Pri</span> <span class="dt">LDLP</span> acc&#39;</span>
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a>        _ <span class="op">|</span> b <span class="op">&lt;=</span> <span class="bn">0x2f</span> <span class="ot">-&gt;</span> decodeInstr_ <span class="op">$</span> acc&#39; <span class="ot">`shiftL`</span> <span class="dv">4</span></span>
<span id="cb16-12"><a href="#cb16-12" aria-hidden="true" tabindex="-1"></a>        _ <span class="op">|</span> b <span class="op">&lt;=</span> <span class="bn">0x3f</span> <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="op">$</span> <span class="dt">Pri</span> <span class="dt">LDNL</span> acc&#39;</span>
<span id="cb16-13"><a href="#cb16-13" aria-hidden="true" tabindex="-1"></a>        _ <span class="op">|</span> b <span class="op">&lt;=</span> <span class="bn">0x4f</span> <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="op">$</span> <span class="dt">Pri</span> <span class="dt">LDC</span> acc&#39;</span>
<span id="cb16-14"><a href="#cb16-14" aria-hidden="true" tabindex="-1"></a>        _ <span class="op">|</span> b <span class="op">&lt;=</span> <span class="bn">0x5f</span> <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="op">$</span> <span class="dt">Pri</span> <span class="dt">LDNLP</span> acc&#39;</span>
<span id="cb16-15"><a href="#cb16-15" aria-hidden="true" tabindex="-1"></a>        _ <span class="op">|</span> b <span class="op">&lt;=</span> <span class="bn">0x6f</span> <span class="ot">-&gt;</span> decodeInstr_ <span class="op">$</span> complement acc&#39; <span class="ot">`shiftL`</span> <span class="dv">4</span></span>
<span id="cb16-16"><a href="#cb16-16" aria-hidden="true" tabindex="-1"></a>        _ <span class="op">|</span> b <span class="op">&lt;=</span> <span class="bn">0x7f</span> <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="op">$</span> <span class="dt">Pri</span> <span class="dt">LDL</span> acc&#39;</span>
<span id="cb16-17"><a href="#cb16-17" aria-hidden="true" tabindex="-1"></a>        _ <span class="op">|</span> b <span class="op">&lt;=</span> <span class="bn">0x8f</span> <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="op">$</span> <span class="dt">Pri</span> <span class="dt">ADC</span> acc&#39;</span>
<span id="cb16-18"><a href="#cb16-18" aria-hidden="true" tabindex="-1"></a>        _ <span class="op">|</span> b <span class="op">&lt;=</span> <span class="bn">0x9f</span> <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="op">$</span> <span class="dt">Pri</span> <span class="dt">CALL</span> acc&#39;</span>
<span id="cb16-19"><a href="#cb16-19" aria-hidden="true" tabindex="-1"></a>        _ <span class="op">|</span> b <span class="op">&lt;=</span> <span class="bn">0xaf</span> <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="op">$</span> <span class="dt">Pri</span> <span class="dt">CJ</span> acc&#39;</span>
<span id="cb16-20"><a href="#cb16-20" aria-hidden="true" tabindex="-1"></a>        _ <span class="op">|</span> b <span class="op">&lt;=</span> <span class="bn">0xbf</span> <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="op">$</span> <span class="dt">Pri</span> <span class="dt">AJW</span> acc&#39;</span>
<span id="cb16-21"><a href="#cb16-21" aria-hidden="true" tabindex="-1"></a>        _ <span class="op">|</span> b <span class="op">&lt;=</span> <span class="bn">0xcf</span> <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="op">$</span> <span class="dt">Pri</span> <span class="dt">EQC</span> acc&#39;</span>
<span id="cb16-22"><a href="#cb16-22" aria-hidden="true" tabindex="-1"></a>        _ <span class="op">|</span> b <span class="op">&lt;=</span> <span class="bn">0xdf</span> <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="op">$</span> <span class="dt">Pri</span> <span class="dt">STL</span> acc&#39;</span>
<span id="cb16-23"><a href="#cb16-23" aria-hidden="true" tabindex="-1"></a>        _ <span class="op">|</span> b <span class="op">&lt;=</span> <span class="bn">0xef</span> <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="op">$</span> <span class="dt">Pri</span> <span class="dt">STNL</span> acc&#39;</span>
<span id="cb16-24"><a href="#cb16-24" aria-hidden="true" tabindex="-1"></a>        _             <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="op">$</span> <span class="dt">Sec</span> <span class="op">$</span> parseSecondary acc&#39;</span>
<span id="cb16-25"><a href="#cb16-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-26"><a href="#cb16-26" aria-hidden="true" tabindex="-1"></a><span class="ot">peekAndIncr ::</span> <span class="dt">Eval</span> <span class="dt">Word8</span></span>
<span id="cb16-27"><a href="#cb16-27" aria-hidden="true" tabindex="-1"></a>peekAndIncr <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb16-28"><a href="#cb16-28" aria-hidden="true" tabindex="-1"></a>    addr <span class="ot">&lt;-</span> use iptr</span>
<span id="cb16-29"><a href="#cb16-29" aria-hidden="true" tabindex="-1"></a>    b <span class="ot">&lt;-</span> use (memByte addr)</span>
<span id="cb16-30"><a href="#cb16-30" aria-hidden="true" tabindex="-1"></a>    iptr <span class="op">+=</span> <span class="dv">1</span></span>
<span id="cb16-31"><a href="#cb16-31" aria-hidden="true" tabindex="-1"></a>    <span class="fu">return</span> b</span>
<span id="cb16-32"><a href="#cb16-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-33"><a href="#cb16-33" aria-hidden="true" tabindex="-1"></a><span class="ot">parseSecondary ::</span> <span class="dt">Int32</span> <span class="ot">-&gt;</span> <span class="dt">SInstr</span></span>
<span id="cb16-34"><a href="#cb16-34" aria-hidden="true" tabindex="-1"></a>parseSecondary <span class="bn">0x01</span> <span class="ot">=</span> <span class="dt">LB</span></span>
<span id="cb16-35"><a href="#cb16-35" aria-hidden="true" tabindex="-1"></a>parseSecondary <span class="bn">0x02</span> <span class="ot">=</span> <span class="dt">BSUB</span></span>
<span id="cb16-36"><a href="#cb16-36" aria-hidden="true" tabindex="-1"></a>parseSecondary <span class="bn">0x06</span> <span class="ot">=</span> <span class="dt">GCALL</span></span>
<span id="cb16-37"><a href="#cb16-37" aria-hidden="true" tabindex="-1"></a>parseSecondary <span class="bn">0x07</span> <span class="ot">=</span> <span class="dt">IN</span></span>
<span id="cb16-38"><a href="#cb16-38" aria-hidden="true" tabindex="-1"></a>parseSecondary <span class="bn">0x08</span> <span class="ot">=</span> <span class="dt">PROD</span></span>
<span id="cb16-39"><a href="#cb16-39" aria-hidden="true" tabindex="-1"></a>parseSecondary <span class="bn">0x09</span> <span class="ot">=</span> <span class="dt">GTx</span></span>
<span id="cb16-40"><a href="#cb16-40" aria-hidden="true" tabindex="-1"></a>parseSecondary <span class="bn">0x0a</span> <span class="ot">=</span> <span class="dt">WSUB</span></span>
<span id="cb16-41"><a href="#cb16-41" aria-hidden="true" tabindex="-1"></a>parseSecondary <span class="bn">0x0b</span> <span class="ot">=</span> <span class="dt">OUT</span></span>
<span id="cb16-42"><a href="#cb16-42" aria-hidden="true" tabindex="-1"></a>parseSecondary <span class="bn">0x1b</span> <span class="ot">=</span> <span class="dt">LDPI</span></span>
<span id="cb16-43"><a href="#cb16-43" aria-hidden="true" tabindex="-1"></a>parseSecondary <span class="bn">0x1f</span> <span class="ot">=</span> <span class="dt">REM</span></span>
<span id="cb16-44"><a href="#cb16-44" aria-hidden="true" tabindex="-1"></a>parseSecondary <span class="bn">0x20</span> <span class="ot">=</span> <span class="dt">RET</span></span>
<span id="cb16-45"><a href="#cb16-45" aria-hidden="true" tabindex="-1"></a>parseSecondary <span class="bn">0x33</span> <span class="ot">=</span> <span class="dt">XOR</span></span>
<span id="cb16-46"><a href="#cb16-46" aria-hidden="true" tabindex="-1"></a>parseSecondary <span class="bn">0x3b</span> <span class="ot">=</span> <span class="dt">SB</span></span>
<span id="cb16-47"><a href="#cb16-47" aria-hidden="true" tabindex="-1"></a>parseSecondary <span class="bn">0x3c</span> <span class="ot">=</span> <span class="dt">GAJW</span></span>
<span id="cb16-48"><a href="#cb16-48" aria-hidden="true" tabindex="-1"></a>parseSecondary <span class="bn">0x40</span> <span class="ot">=</span> <span class="dt">SHR</span></span>
<span id="cb16-49"><a href="#cb16-49" aria-hidden="true" tabindex="-1"></a>parseSecondary <span class="bn">0x41</span> <span class="ot">=</span> <span class="dt">SHL</span></span>
<span id="cb16-50"><a href="#cb16-50" aria-hidden="true" tabindex="-1"></a>parseSecondary <span class="bn">0x42</span> <span class="ot">=</span> <span class="dt">MINT</span></span>
<span id="cb16-51"><a href="#cb16-51" aria-hidden="true" tabindex="-1"></a>parseSecondary <span class="bn">0x46</span> <span class="ot">=</span> <span class="dt">AND</span></span>
<span id="cb16-52"><a href="#cb16-52" aria-hidden="true" tabindex="-1"></a>parseSecondary <span class="bn">0x5a</span> <span class="ot">=</span> <span class="dt">DUP</span></span>
<span id="cb16-53"><a href="#cb16-53" aria-hidden="true" tabindex="-1"></a>parseSecondary <span class="bn">0xc1</span> <span class="ot">=</span> <span class="dt">SSUB</span></span>
<span id="cb16-54"><a href="#cb16-54" aria-hidden="true" tabindex="-1"></a>parseSecondary b <span class="ot">=</span> <span class="fu">error</span> <span class="op">$</span> <span class="st">&quot;Unknown secondary 0x&quot;</span> <span class="op">++</span> showHex b <span class="st">&quot;&quot;</span></span></code></pre></div>
<h2 id="the-two-stacks">The two stacks</h2>
<p>Data is manipulated using two different mechanisms: the integer stack and the
workspace.</p>
<p>The integer stack is a set of three registers: <code>A</code>, <code>B</code>, and <code>C</code>, which can be
used as a stack using these operations. Actually, it can only be manipulated
through push and pop operations, so we represent this using a list.</p>
<p>The instruction set reference says that an undefined value will be popped if the
stack is empty; here we consider that this will not happen, and allow a partial
pattern matching.</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="ot">pushInt ::</span> <span class="dt">Int32</span> <span class="ot">-&gt;</span> <span class="dt">Eval</span> ()</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>pushInt n <span class="ot">=</span></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>    intStack <span class="op">%=</span> (n<span class="op">:</span>)</span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a><span class="ot">popInt ::</span> <span class="dt">Eval</span> <span class="dt">Int32</span></span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a>popInt <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb17-7"><a href="#cb17-7" aria-hidden="true" tabindex="-1"></a>    (h<span class="op">:</span>t) <span class="ot">&lt;-</span> use intStack</span>
<span id="cb17-8"><a href="#cb17-8" aria-hidden="true" tabindex="-1"></a>    intStack <span class="op">.=</span> t</span>
<span id="cb17-9"><a href="#cb17-9" aria-hidden="true" tabindex="-1"></a>    <span class="fu">return</span> h</span>
<span id="cb17-10"><a href="#cb17-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-11"><a href="#cb17-11" aria-hidden="true" tabindex="-1"></a><span class="ot">popAll ::</span> <span class="dt">Eval</span> (<span class="dt">Int32</span>, <span class="dt">Int32</span>, <span class="dt">Int32</span>)</span>
<span id="cb17-12"><a href="#cb17-12" aria-hidden="true" tabindex="-1"></a>popAll <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb17-13"><a href="#cb17-13" aria-hidden="true" tabindex="-1"></a>    a <span class="ot">&lt;-</span> popInt</span>
<span id="cb17-14"><a href="#cb17-14" aria-hidden="true" tabindex="-1"></a>    b <span class="ot">&lt;-</span> popInt</span>
<span id="cb17-15"><a href="#cb17-15" aria-hidden="true" tabindex="-1"></a>    c <span class="ot">&lt;-</span> popInt</span>
<span id="cb17-16"><a href="#cb17-16" aria-hidden="true" tabindex="-1"></a>    <span class="fu">return</span> (a, b, c)</span></code></pre></div>
<p>Only the head (<code>A</code>) can be directly accessed, so we first define a lens between
a list and its head, and compose it with <code>intStack</code>.</p>
<div class="sourceCode" id="cb18"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="ot">headLens ::</span> <span class="dt">Lens&#39;</span> [a] a</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>headLens <span class="ot">=</span> lens <span class="fu">head</span> <span class="op">$</span> \ l x <span class="ot">-&gt;</span> x<span class="op">:</span><span class="fu">tail</span> l</span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a><span class="ot">areg ::</span> <span class="dt">Lens&#39;</span> <span class="dt">EvalState</span> <span class="dt">Int32</span></span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>areg <span class="ot">=</span> intStack <span class="op">.</span> headLens</span></code></pre></div>
<p>The workspace is a place in memory (pointed to by a register <code>wptr</code>) where local
variables can be stored and loaded, a bit like a stack pointer. We first define
push and pop operations.</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="ot">pushWorkspace ::</span> <span class="dt">Int32</span> <span class="ot">-&gt;</span> <span class="dt">Eval</span> ()</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>pushWorkspace value <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>    wptr <span class="op">-=</span> <span class="dv">4</span></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>    var <span class="dv">0</span> <span class="op">.=</span> value</span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a><span class="ot">popWorkspace ::</span> <span class="dt">Eval</span> <span class="dt">Int32</span></span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a>popWorkspace <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a>    w <span class="ot">&lt;-</span> use <span class="op">$</span> var <span class="dv">0</span></span>
<span id="cb19-9"><a href="#cb19-9" aria-hidden="true" tabindex="-1"></a>    wptr <span class="op">+=</span> <span class="dv">4</span></span>
<span id="cb19-10"><a href="#cb19-10" aria-hidden="true" tabindex="-1"></a>    <span class="fu">return</span> w</span></code></pre></div>
<p>Then we define a lens to focus on a variable.</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="ot">var ::</span> <span class="dt">Int32</span> <span class="ot">-&gt;</span> <span class="dt">Lens&#39;</span> <span class="dt">EvalState</span> <span class="dt">Int32</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>var n <span class="ot">=</span></span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>    lens getVar setVar</span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a>        <span class="kw">where</span></span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a>            varLens s <span class="ot">=</span> memWord ((s <span class="op">^.</span> wptr) <span class="op">@@</span> n)</span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a>            getVar s <span class="ot">=</span> s <span class="op">^.</span> varLens s</span>
<span id="cb20-7"><a href="#cb20-7" aria-hidden="true" tabindex="-1"></a>            setVar s v <span class="ot">=</span> set (varLens s) v s</span></code></pre></div>
<h2 id="input-and-output">Input and output</h2>
<p>The main particularity of the ST20 architecture is that it has hardware support
of message channels. They map fairly naturally to <code>Control.Concurrent.Chan</code>
channels. Each ST20 thread will have a map from channel numbers to input or
output channels:</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="ot">getXChan ::</span> (<span class="dt">EvalEnv</span> <span class="ot">-&gt;</span> [(<span class="dt">Int32</span>, a)]) <span class="ot">-&gt;</span> <span class="dt">Int32</span> <span class="ot">-&gt;</span> <span class="dt">EvalEnv</span> <span class="ot">-&gt;</span> a</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>getXChan member w st <span class="ot">=</span></span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>    fromJust <span class="op">$</span> <span class="fu">lookup</span> w <span class="op">$</span> member st</span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a><span class="ot">getIChan ::</span> <span class="dt">Int32</span> <span class="ot">-&gt;</span> <span class="dt">EvalEnv</span> <span class="ot">-&gt;</span> <span class="dt">IChannel</span></span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a>getIChan <span class="ot">=</span> getXChan envInChans</span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a><span class="ot">getOChan ::</span> <span class="dt">Int32</span> <span class="ot">-&gt;</span> <span class="dt">EvalEnv</span> <span class="ot">-&gt;</span> <span class="dt">OChannel</span></span>
<span id="cb21-9"><a href="#cb21-9" aria-hidden="true" tabindex="-1"></a>getOChan <span class="ot">=</span> getXChan envOutChans</span></code></pre></div>
<p>And these channels can be either a <code>Chan Word8</code> or a plain <code>Handle</code>, to connect
a thread to the process’ standard input and output.</p>
<div class="sourceCode" id="cb22"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="ot">readFromIChan ::</span> <span class="dt">IChannel</span> <span class="ot">-&gt;</span> <span class="dt">Int32</span> <span class="ot">-&gt;</span> <span class="dt">Eval</span> [<span class="dt">Word8</span>]</span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a>readFromIChan (<span class="dt">InChan</span> chan) n <span class="ot">=</span></span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>    liftIO <span class="op">$</span> <span class="fu">mapM</span> (\ _ <span class="ot">-&gt;</span> readChan chan) [<span class="dv">1</span><span class="op">..</span>n]</span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a>readFromIChan (<span class="dt">InHandle</span> h) n <span class="ot">=</span></span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a>    liftIO <span class="op">$</span> <span class="kw">do</span></span>
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a>        bs <span class="ot">&lt;-</span> BS.hGet h <span class="op">$</span> <span class="fu">fromIntegral</span> n</span>
<span id="cb22-7"><a href="#cb22-7" aria-hidden="true" tabindex="-1"></a>        <span class="fu">return</span> <span class="op">$</span> BS.unpack bs</span>
<span id="cb22-8"><a href="#cb22-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-9"><a href="#cb22-9" aria-hidden="true" tabindex="-1"></a><span class="ot">writeToOChan ::</span> <span class="dt">OChannel</span> <span class="ot">-&gt;</span> [<span class="dt">Word8</span>] <span class="ot">-&gt;</span> <span class="dt">Eval</span> ()</span>
<span id="cb22-10"><a href="#cb22-10" aria-hidden="true" tabindex="-1"></a>writeToOChan (<span class="dt">OutChan</span> chan) ws <span class="ot">=</span></span>
<span id="cb22-11"><a href="#cb22-11" aria-hidden="true" tabindex="-1"></a>    liftIO <span class="op">$</span> writeList2Chan chan ws</span>
<span id="cb22-12"><a href="#cb22-12" aria-hidden="true" tabindex="-1"></a>writeToOChan (<span class="dt">OutHandle</span> h) ws <span class="ot">=</span></span>
<span id="cb22-13"><a href="#cb22-13" aria-hidden="true" tabindex="-1"></a>    liftIO <span class="op">$</span> <span class="kw">do</span></span>
<span id="cb22-14"><a href="#cb22-14" aria-hidden="true" tabindex="-1"></a>        BS.hPutStr h <span class="op">$</span> BS.pack ws</span>
<span id="cb22-15"><a href="#cb22-15" aria-hidden="true" tabindex="-1"></a>        hFlush h</span></code></pre></div>
<h2 id="a-few-combinators">A few combinators</h2>
<p>We first define a few combinators that will help us define the <code>interpret</code>
function.</p>
<p>Pop two operands, and push the result:</p>
<div class="sourceCode" id="cb23"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="ot">liftOp ::</span> (<span class="dt">Int32</span> <span class="ot">-&gt;</span> <span class="dt">Int32</span> <span class="ot">-&gt;</span> <span class="dt">Int32</span>) <span class="ot">-&gt;</span> <span class="dt">Eval</span> ()</span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>liftOp op <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a>    a <span class="ot">&lt;-</span> popInt</span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a>    b <span class="ot">&lt;-</span> popInt</span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a>    pushInt <span class="op">$</span> op a b</span></code></pre></div>
<p>Exchange two registers:</p>
<div class="sourceCode" id="cb24"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="ot">xchg ::</span> <span class="dt">Lens&#39;</span> <span class="dt">EvalState</span> <span class="dt">Int32</span> <span class="ot">-&gt;</span> <span class="dt">Lens&#39;</span> <span class="dt">EvalState</span> <span class="dt">Int32</span> <span class="ot">-&gt;</span> <span class="dt">Eval</span> ()</span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>xchg l1 l2 <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>  x1 <span class="ot">&lt;-</span> use l1</span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a>  x2 <span class="ot">&lt;-</span> use l2</span>
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a>  l1 <span class="op">.=</span> x2</span>
<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a>  l2 <span class="op">.=</span> x1</span></code></pre></div>
<p>Convert a boolean to an integer:</p>
<div class="sourceCode" id="cb25"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="ot">fromBool ::</span> <span class="dt">Bool</span> <span class="ot">-&gt;</span> <span class="dt">Int32</span></span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>fromBool <span class="dt">False</span> <span class="ot">=</span> <span class="dv">0</span></span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>fromBool <span class="dt">True</span> <span class="ot">=</span> <span class="dv">1</span></span></code></pre></div>
<h2 id="the-interpret-function">The <code>interpret</code> function</h2>
<p>The core of the interpreter is the following function. It takes an instruction
and transforms it into a monadic action in <code>Eval</code>.</p>
<div class="sourceCode" id="cb26"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="ot">interpret ::</span> <span class="dt">Instr</span> <span class="ot">-&gt;</span> <span class="dt">Eval</span> ()</span></code></pre></div>
<p>Some cases are very simple.</p>
<div class="sourceCode" id="cb27"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Pri</span> <span class="dt">AJW</span> n) <span class="ot">=</span> wptr <span class="op">+=</span> <span class="dv">4</span> <span class="op">*</span> n</span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Pri</span> <span class="dt">LDNLP</span> n) <span class="ot">=</span> areg <span class="op">+=</span> <span class="dv">4</span> <span class="op">*</span> n</span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Pri</span> <span class="dt">J</span> n) <span class="ot">=</span> iptr <span class="op">+=</span> n</span>
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Pri</span> <span class="dt">LDC</span> n) <span class="ot">=</span> pushInt n</span>
<span id="cb27-5"><a href="#cb27-5" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Sec</span> <span class="dt">MINT</span>) <span class="ot">=</span> pushInt <span class="bn">0x80000000</span></span>
<span id="cb27-6"><a href="#cb27-6" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Sec</span> <span class="dt">GAJW</span>) <span class="ot">=</span> xchg areg wptr</span>
<span id="cb27-7"><a href="#cb27-7" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Sec</span> <span class="dt">GCALL</span>) <span class="ot">=</span> xchg areg iptr</span>
<span id="cb27-8"><a href="#cb27-8" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Pri</span> <span class="dt">ADC</span> n) <span class="ot">=</span> areg <span class="op">+=</span> n</span>
<span id="cb27-9"><a href="#cb27-9" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Pri</span> <span class="dt">EQC</span> n) <span class="ot">=</span> areg <span class="op">%=</span> (\ a <span class="ot">-&gt;</span> fromBool <span class="op">$</span> a <span class="op">==</span> n)</span></code></pre></div>
<p>For some others, we can lift them into the host language and use Haskell
operations.</p>
<div class="sourceCode" id="cb28"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Sec</span> <span class="dt">PROD</span>) <span class="ot">=</span> liftOp (<span class="op">*</span>)</span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Sec</span> <span class="dt">XOR</span>) <span class="ot">=</span> liftOp xor</span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Sec</span> <span class="dt">AND</span>) <span class="ot">=</span> liftOp (<span class="op">.&amp;.</span>)</span>
<span id="cb28-4"><a href="#cb28-4" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Sec</span> <span class="dt">BSUB</span>) <span class="ot">=</span> liftOp (<span class="op">+</span>)</span>
<span id="cb28-5"><a href="#cb28-5" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Sec</span> <span class="dt">SSUB</span>) <span class="ot">=</span> liftOp <span class="op">$</span> \ a b <span class="ot">-&gt;</span> a <span class="op">+</span> <span class="dv">2</span> <span class="op">*</span> b</span>
<span id="cb28-6"><a href="#cb28-6" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Sec</span> <span class="dt">WSUB</span>) <span class="ot">=</span> liftOp (<span class="op">@@</span>)</span>
<span id="cb28-7"><a href="#cb28-7" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Sec</span> <span class="dt">GTx</span>) <span class="ot">=</span> liftOp <span class="op">$</span> \ a b <span class="ot">-&gt;</span> fromBool <span class="op">$</span> b <span class="op">&gt;</span> a</span>
<span id="cb28-8"><a href="#cb28-8" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Sec</span> <span class="dt">SHR</span>) <span class="ot">=</span> liftOp <span class="op">$</span> \ a b <span class="ot">-&gt;</span> b <span class="ot">`shiftR`</span> <span class="fu">fromIntegral</span> a</span>
<span id="cb28-9"><a href="#cb28-9" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Sec</span> <span class="dt">SHL</span>) <span class="ot">=</span> liftOp <span class="op">$</span> \ a b <span class="ot">-&gt;</span> b <span class="ot">`shiftL`</span> <span class="fu">fromIntegral</span> a</span>
<span id="cb28-10"><a href="#cb28-10" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Sec</span> <span class="dt">REM</span>) <span class="ot">=</span> liftOp <span class="op">$</span> \ a b <span class="ot">-&gt;</span> b <span class="ot">`mod`</span> a</span></code></pre></div>
<p>Others need a few operations to prepare the operands and access memory.</p>
<div class="sourceCode" id="cb29"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Sec</span> <span class="dt">SB</span>) <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a>    a <span class="ot">&lt;-</span> popInt</span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a>    b <span class="ot">&lt;-</span> popInt</span>
<span id="cb29-4"><a href="#cb29-4" aria-hidden="true" tabindex="-1"></a>    memByte a <span class="op">.=</span> <span class="fu">fromIntegral</span> b</span>
<span id="cb29-5"><a href="#cb29-5" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Sec</span> <span class="dt">DUP</span>) <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb29-6"><a href="#cb29-6" aria-hidden="true" tabindex="-1"></a>    a <span class="ot">&lt;-</span> popInt</span>
<span id="cb29-7"><a href="#cb29-7" aria-hidden="true" tabindex="-1"></a>    pushInt a</span>
<span id="cb29-8"><a href="#cb29-8" aria-hidden="true" tabindex="-1"></a>    pushInt a</span>
<span id="cb29-9"><a href="#cb29-9" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Pri</span> <span class="dt">STL</span> n) <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb29-10"><a href="#cb29-10" aria-hidden="true" tabindex="-1"></a>    v <span class="ot">&lt;-</span> popInt</span>
<span id="cb29-11"><a href="#cb29-11" aria-hidden="true" tabindex="-1"></a>    var n <span class="op">.=</span> v</span>
<span id="cb29-12"><a href="#cb29-12" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Pri</span> <span class="dt">LDLP</span> n) <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb29-13"><a href="#cb29-13" aria-hidden="true" tabindex="-1"></a>    v <span class="ot">&lt;-</span> use wptr</span>
<span id="cb29-14"><a href="#cb29-14" aria-hidden="true" tabindex="-1"></a>    pushInt <span class="op">$</span> v <span class="op">@@</span> n</span>
<span id="cb29-15"><a href="#cb29-15" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Pri</span> <span class="dt">LDL</span> n) <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb29-16"><a href="#cb29-16" aria-hidden="true" tabindex="-1"></a>    v <span class="ot">&lt;-</span> use <span class="op">$</span> var n</span>
<span id="cb29-17"><a href="#cb29-17" aria-hidden="true" tabindex="-1"></a>    pushInt v</span>
<span id="cb29-18"><a href="#cb29-18" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Sec</span> <span class="dt">LDPI</span>) <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb29-19"><a href="#cb29-19" aria-hidden="true" tabindex="-1"></a>    ip <span class="ot">&lt;-</span> use iptr</span>
<span id="cb29-20"><a href="#cb29-20" aria-hidden="true" tabindex="-1"></a>    areg <span class="op">+=</span> ip</span>
<span id="cb29-21"><a href="#cb29-21" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Pri</span> <span class="dt">CJ</span> n) <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb29-22"><a href="#cb29-22" aria-hidden="true" tabindex="-1"></a>    a <span class="ot">&lt;-</span> popInt</span>
<span id="cb29-23"><a href="#cb29-23" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> d <span class="ot">=</span> <span class="kw">if</span> a <span class="op">==</span> <span class="dv">0</span> <span class="kw">then</span> n <span class="kw">else</span> <span class="dv">0</span></span>
<span id="cb29-24"><a href="#cb29-24" aria-hidden="true" tabindex="-1"></a>    iptr <span class="op">+=</span> d</span>
<span id="cb29-25"><a href="#cb29-25" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Sec</span> <span class="dt">LB</span>) <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb29-26"><a href="#cb29-26" aria-hidden="true" tabindex="-1"></a>    a <span class="ot">&lt;-</span> use areg</span>
<span id="cb29-27"><a href="#cb29-27" aria-hidden="true" tabindex="-1"></a>    a&#39; <span class="ot">&lt;-</span> <span class="fu">fromIntegral</span> <span class="op">&lt;$&gt;</span> use (memByte a)</span>
<span id="cb29-28"><a href="#cb29-28" aria-hidden="true" tabindex="-1"></a>    areg <span class="op">.=</span> a&#39;</span>
<span id="cb29-29"><a href="#cb29-29" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Pri</span> <span class="dt">STNL</span> n) <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb29-30"><a href="#cb29-30" aria-hidden="true" tabindex="-1"></a>    a <span class="ot">&lt;-</span> popInt</span>
<span id="cb29-31"><a href="#cb29-31" aria-hidden="true" tabindex="-1"></a>    b <span class="ot">&lt;-</span> popInt</span>
<span id="cb29-32"><a href="#cb29-32" aria-hidden="true" tabindex="-1"></a>    memWord (a <span class="op">@@</span> n) <span class="op">.=</span> b</span>
<span id="cb29-33"><a href="#cb29-33" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Pri</span> <span class="dt">LDNL</span> n) <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb29-34"><a href="#cb29-34" aria-hidden="true" tabindex="-1"></a>    a <span class="ot">&lt;-</span> use areg</span>
<span id="cb29-35"><a href="#cb29-35" aria-hidden="true" tabindex="-1"></a>    a&#39; <span class="ot">&lt;-</span> use <span class="op">$</span> memWord <span class="op">$</span> a <span class="op">@@</span> n</span>
<span id="cb29-36"><a href="#cb29-36" aria-hidden="true" tabindex="-1"></a>    areg <span class="op">.=</span> a&#39;</span></code></pre></div>
<p>Call and return instructions use the workspace to pass arguments.</p>
<div class="sourceCode" id="cb30"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Pri</span> <span class="dt">CALL</span> n) <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a>    (a, b, c) <span class="ot">&lt;-</span> popAll</span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a>    pushWorkspace c</span>
<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a>    pushWorkspace b</span>
<span id="cb30-5"><a href="#cb30-5" aria-hidden="true" tabindex="-1"></a>    pushWorkspace a</span>
<span id="cb30-6"><a href="#cb30-6" aria-hidden="true" tabindex="-1"></a>    ip <span class="ot">&lt;-</span> use iptr</span>
<span id="cb30-7"><a href="#cb30-7" aria-hidden="true" tabindex="-1"></a>    pushWorkspace ip</span>
<span id="cb30-8"><a href="#cb30-8" aria-hidden="true" tabindex="-1"></a>    areg <span class="op">.=</span> ip</span>
<span id="cb30-9"><a href="#cb30-9" aria-hidden="true" tabindex="-1"></a>    iptr <span class="op">+=</span> n</span>
<span id="cb30-10"><a href="#cb30-10" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Sec</span> <span class="dt">RET</span>) <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb30-11"><a href="#cb30-11" aria-hidden="true" tabindex="-1"></a>    newIp <span class="ot">&lt;-</span> popWorkspace</span>
<span id="cb30-12"><a href="#cb30-12" aria-hidden="true" tabindex="-1"></a>    _ <span class="ot">&lt;-</span> popWorkspace</span>
<span id="cb30-13"><a href="#cb30-13" aria-hidden="true" tabindex="-1"></a>    _ <span class="ot">&lt;-</span> popWorkspace</span>
<span id="cb30-14"><a href="#cb30-14" aria-hidden="true" tabindex="-1"></a>    _ <span class="ot">&lt;-</span> popWorkspace</span>
<span id="cb30-15"><a href="#cb30-15" aria-hidden="true" tabindex="-1"></a>    iptr <span class="op">.=</span> newIp</span></code></pre></div>
<p>To perform I/O, the calling transputer needs to supply three things in the int
stack:</p>
<ul>
<li>the number of bytes to transfer;</li>
<li>a pointer to a channel;</li>
<li>where to read or write the message.</li>
</ul>
<p>The channel itself is abstracted in the transputer’s channel maps. Most reads
succeed; however the first transputer’s channel 0 will read directly from a
file, so it will reach end of file at some time. We can detect that when an
empty list is read, and exit the process.</p>
<div class="sourceCode" id="cb31"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Sec</span> <span class="dt">OUT</span>) <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a>    (len, pChan, pMsg) <span class="ot">&lt;-</span> popAll</span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a>    message <span class="ot">&lt;-</span> use <span class="op">$</span> mem8s pMsg len</span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a>    chan <span class="ot">&lt;-</span> asks <span class="op">$</span> getOChan pChan</span>
<span id="cb31-5"><a href="#cb31-5" aria-hidden="true" tabindex="-1"></a>    writeToOChan chan message</span>
<span id="cb31-6"><a href="#cb31-6" aria-hidden="true" tabindex="-1"></a>interpret (<span class="dt">Sec</span> <span class="dt">IN</span>) <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb31-7"><a href="#cb31-7" aria-hidden="true" tabindex="-1"></a>    (len, pChan, pMsg) <span class="ot">&lt;-</span> popAll</span>
<span id="cb31-8"><a href="#cb31-8" aria-hidden="true" tabindex="-1"></a>    chan <span class="ot">&lt;-</span> asks <span class="op">$</span> getIChan pChan</span>
<span id="cb31-9"><a href="#cb31-9" aria-hidden="true" tabindex="-1"></a>    input <span class="ot">&lt;-</span> readFromIChan chan len</span>
<span id="cb31-10"><a href="#cb31-10" aria-hidden="true" tabindex="-1"></a>    when (<span class="fu">null</span> input) <span class="op">$</span> liftIO exitSuccess</span>
<span id="cb31-11"><a href="#cb31-11" aria-hidden="true" tabindex="-1"></a>    mem8s pMsg (<span class="fu">fromIntegral</span> <span class="op">$</span> <span class="fu">length</span> input) <span class="op">.=</span> input</span></code></pre></div>
<p>The core of the interpreter is then very simple:</p>
<div class="sourceCode" id="cb32"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="ot">evalLoop ::</span> <span class="dt">Eval</span> ()</span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a>evalLoop <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a>    i <span class="ot">&lt;-</span> decodeInstr</span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a>    interpret i</span>
<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a>    evalLoop</span></code></pre></div>
<h2 id="boot-from-link">Boot from link</h2>
<p>Several things are missing: the memory map, and how the system boots.</p>
<p>It turns out that the ST20 has a very simple boot protocol:</p>
<ul>
<li>read 1 byte from port 0, call it <code>n</code></li>
<li>read <code>n</code> bytes from port 0</li>
<li>store those at <code>memStart</code></li>
<li>set the workspace just after this memory chunk</li>
<li>jump to <code>memStart</code></li>
</ul>
<div class="sourceCode" id="cb33"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bootSeq ::</span> <span class="dt">Eval</span> ()</span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a>bootSeq <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb33-3"><a href="#cb33-3" aria-hidden="true" tabindex="-1"></a>    chan <span class="ot">&lt;-</span> asks <span class="op">$</span> getIChan <span class="op">$</span> iPin <span class="dv">0</span></span>
<span id="cb33-4"><a href="#cb33-4" aria-hidden="true" tabindex="-1"></a>    len <span class="ot">&lt;-</span> <span class="fu">head</span> <span class="op">&lt;$&gt;</span> readFromIChan chan <span class="dv">1</span></span>
<span id="cb33-5"><a href="#cb33-5" aria-hidden="true" tabindex="-1"></a>    prog <span class="ot">&lt;-</span> readFromIChan chan <span class="op">$</span> <span class="fu">fromIntegral</span> len</span>
<span id="cb33-6"><a href="#cb33-6" aria-hidden="true" tabindex="-1"></a>    mem8s memStart (<span class="fu">fromIntegral</span> <span class="op">$</span> <span class="fu">length</span> prog) <span class="op">.=</span> prog</span>
<span id="cb33-7"><a href="#cb33-7" aria-hidden="true" tabindex="-1"></a>    wptr <span class="op">.=</span> memStart <span class="op">+</span> <span class="fu">fromIntegral</span> len</span></code></pre></div>
<p>There’s some flexibility on <code>memStart</code>, but this value works:</p>
<div class="sourceCode" id="cb34"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a><span class="ot">memStart ::</span> <span class="dt">Address</span></span>
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a>memStart <span class="ot">=</span> <span class="bn">0x80000100</span></span></code></pre></div>
<p>Pin numbers, however, are mapped to fixed address:</p>
<div class="sourceCode" id="cb35"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb35-1"><a href="#cb35-1" aria-hidden="true" tabindex="-1"></a><span class="ot">iPin ::</span> <span class="dt">Int32</span> <span class="ot">-&gt;</span> <span class="dt">Int32</span></span>
<span id="cb35-2"><a href="#cb35-2" aria-hidden="true" tabindex="-1"></a>iPin n <span class="ot">=</span> <span class="bn">0x80000010</span> <span class="op">@@</span> n</span>
<span id="cb35-3"><a href="#cb35-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-4"><a href="#cb35-4" aria-hidden="true" tabindex="-1"></a><span class="ot">oPin ::</span> <span class="dt">Int32</span> <span class="ot">-&gt;</span> <span class="dt">Int32</span></span>
<span id="cb35-5"><a href="#cb35-5" aria-hidden="true" tabindex="-1"></a>oPin n <span class="ot">=</span> <span class="bn">0x80000000</span> <span class="op">@@</span> n</span></code></pre></div>
<p>We decide to initialize the memory with zeroes:</p>
<div class="sourceCode" id="cb36"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb36-1"><a href="#cb36-1" aria-hidden="true" tabindex="-1"></a><span class="ot">initialMem ::</span> <span class="dt">Mem</span></span>
<span id="cb36-2"><a href="#cb36-2" aria-hidden="true" tabindex="-1"></a>initialMem <span class="ot">=</span></span>
<span id="cb36-3"><a href="#cb36-3" aria-hidden="true" tabindex="-1"></a>    M.fromList <span class="op">$</span> <span class="fu">zip</span> [<span class="bn">0x80000000</span> <span class="op">..</span> memEnd] <span class="op">$</span> <span class="fu">repeat</span> <span class="dv">0</span></span>
<span id="cb36-4"><a href="#cb36-4" aria-hidden="true" tabindex="-1"></a>        <span class="kw">where</span></span>
<span id="cb36-5"><a href="#cb36-5" aria-hidden="true" tabindex="-1"></a>            memSize <span class="ot">=</span> <span class="bn">0x4000</span></span>
<span id="cb36-6"><a href="#cb36-6" aria-hidden="true" tabindex="-1"></a>            memEnd <span class="ot">=</span> memStart <span class="op">+</span> memSize <span class="op">-</span> <span class="dv">1</span></span></code></pre></div>
<p>Booting a transputer is then just a matter of reading from the correct channel
and doing the rest of the evaluation loop.</p>
<div class="sourceCode" id="cb37"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb37-1"><a href="#cb37-1" aria-hidden="true" tabindex="-1"></a><span class="ot">transputer ::</span> <span class="dt">Maybe</span> <span class="dt">Analysis</span></span>
<span id="cb37-2"><a href="#cb37-2" aria-hidden="true" tabindex="-1"></a>           <span class="ot">-&gt;</span> [((<span class="dt">Int32</span>, <span class="dt">IChannel</span>), (<span class="dt">Int32</span>, <span class="dt">OChannel</span>))]</span>
<span id="cb37-3"><a href="#cb37-3" aria-hidden="true" tabindex="-1"></a>           <span class="ot">-&gt;</span> <span class="dt">IO</span> (<span class="dt">MVar</span> ())</span>
<span id="cb37-4"><a href="#cb37-4" aria-hidden="true" tabindex="-1"></a>transputer analysis cmap <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb37-5"><a href="#cb37-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> (imap, omap) <span class="ot">=</span> <span class="fu">unzip</span> cmap</span>
<span id="cb37-6"><a href="#cb37-6" aria-hidden="true" tabindex="-1"></a>    fork <span class="op">$</span> runEval initialMem imap omap <span class="op">$</span> <span class="kw">do</span></span>
<span id="cb37-7"><a href="#cb37-7" aria-hidden="true" tabindex="-1"></a>        bootSeq</span>
<span id="cb37-8"><a href="#cb37-8" aria-hidden="true" tabindex="-1"></a>        runAnalysis analysis</span>
<span id="cb37-9"><a href="#cb37-9" aria-hidden="true" tabindex="-1"></a>        evalLoop</span></code></pre></div>
<h2 id="multithreading-boilerplate">Multithreading boilerplate</h2>
<p>If you fork threads and don’t wait for them, nothing will happen since the main
thread will just exit. The solution is to create a “control” <code>MVar</code> that will be
signalled to by each thread:</p>
<div class="sourceCode" id="cb38"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb38-1"><a href="#cb38-1" aria-hidden="true" tabindex="-1"></a><span class="ot">fork ::</span> <span class="dt">IO</span> () <span class="ot">-&gt;</span> <span class="dt">IO</span> (<span class="dt">MVar</span> ())</span>
<span id="cb38-2"><a href="#cb38-2" aria-hidden="true" tabindex="-1"></a>fork io <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb38-3"><a href="#cb38-3" aria-hidden="true" tabindex="-1"></a>    mvar <span class="ot">&lt;-</span> newEmptyMVar</span>
<span id="cb38-4"><a href="#cb38-4" aria-hidden="true" tabindex="-1"></a>    _ <span class="ot">&lt;-</span> forkFinally io <span class="op">$</span> \ _ <span class="ot">-&gt;</span> putMVar mvar ()</span>
<span id="cb38-5"><a href="#cb38-5" aria-hidden="true" tabindex="-1"></a>    <span class="fu">return</span> mvar</span></code></pre></div>
<p>And to wait for all of them:</p>
<div class="sourceCode" id="cb39"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb39-1"><a href="#cb39-1" aria-hidden="true" tabindex="-1"></a><span class="ot">runAll ::</span> [<span class="dt">IO</span> (<span class="dt">MVar</span> ())] <span class="ot">-&gt;</span> <span class="dt">IO</span> ()</span>
<span id="cb39-2"><a href="#cb39-2" aria-hidden="true" tabindex="-1"></a>runAll ms <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb39-3"><a href="#cb39-3" aria-hidden="true" tabindex="-1"></a>    threads <span class="ot">&lt;-</span> <span class="fu">sequence</span> ms</span>
<span id="cb39-4"><a href="#cb39-4" aria-hidden="true" tabindex="-1"></a>    <span class="fu">mapM_</span> takeMVar threads</span></code></pre></div>
<h2 id="connecting-the-lines">Connecting the lines</h2>
<p>For this problem we have 13 transputers.</p>
<div class="sourceCode" id="cb40"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb40-1"><a href="#cb40-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">TransputerName</span> <span class="ot">=</span> <span class="dt">T00</span> <span class="op">|</span> <span class="dt">T01</span> <span class="op">|</span> <span class="dt">T02</span> <span class="op">|</span> <span class="dt">T03</span></span>
<span id="cb40-2"><a href="#cb40-2" aria-hidden="true" tabindex="-1"></a>                    <span class="op">|</span> <span class="dt">T04</span> <span class="op">|</span> <span class="dt">T05</span> <span class="op">|</span> <span class="dt">T06</span> <span class="op">|</span> <span class="dt">T07</span></span>
<span id="cb40-3"><a href="#cb40-3" aria-hidden="true" tabindex="-1"></a>                    <span class="op">|</span> <span class="dt">T08</span> <span class="op">|</span> <span class="dt">T09</span> <span class="op">|</span> <span class="dt">T10</span> <span class="op">|</span> <span class="dt">T11</span></span>
<span id="cb40-4"><a href="#cb40-4" aria-hidden="true" tabindex="-1"></a>                    <span class="op">|</span> <span class="dt">T12</span></span>
<span id="cb40-5"><a href="#cb40-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">deriving</span> (<span class="dt">Enum</span>, <span class="dt">Eq</span>)</span></code></pre></div>
<p>We devise a way to connect them together. The communication between two
transputers is bidirectional, so we need two channels. Each of them is converted
to an <code>OChannel</code> on one side and an <code>IChannel</code> on the other one.</p>
<div class="sourceCode" id="cb41"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb41-1"><a href="#cb41-1" aria-hidden="true" tabindex="-1"></a><span class="ot">connect ::</span> <span class="dt">TransputerName</span> <span class="ot">-&gt;</span> <span class="dt">Int32</span></span>
<span id="cb41-2"><a href="#cb41-2" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> <span class="dt">TransputerName</span> <span class="ot">-&gt;</span> <span class="dt">Int32</span></span>
<span id="cb41-3"><a href="#cb41-3" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> <span class="dt">IO</span> [(<span class="dt">TransputerName</span>, <span class="dt">Int32</span>, <span class="dt">OChannel</span>, <span class="dt">IChannel</span>)]</span>
<span id="cb41-4"><a href="#cb41-4" aria-hidden="true" tabindex="-1"></a>connect src srcPort dst dstPort <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb41-5"><a href="#cb41-5" aria-hidden="true" tabindex="-1"></a>  x <span class="ot">&lt;-</span> newChan</span>
<span id="cb41-6"><a href="#cb41-6" aria-hidden="true" tabindex="-1"></a>  y <span class="ot">&lt;-</span> newChan</span>
<span id="cb41-7"><a href="#cb41-7" aria-hidden="true" tabindex="-1"></a>  <span class="fu">return</span> [ (src, srcPort, <span class="dt">OutChan</span> x, <span class="dt">InChan</span> y)</span>
<span id="cb41-8"><a href="#cb41-8" aria-hidden="true" tabindex="-1"></a>         , (dst, dstPort, <span class="dt">OutChan</span> y, <span class="dt">InChan</span> x)</span>
<span id="cb41-9"><a href="#cb41-9" aria-hidden="true" tabindex="-1"></a>         ]</span></code></pre></div>
<p>Booting them is a matter of creating the correct communication channels (this
pinout list comes from a schematic that was present in the challenge files).</p>
<div class="sourceCode" id="cb42"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb42-1"><a href="#cb42-1" aria-hidden="true" tabindex="-1"></a><span class="ot">main ::</span> <span class="dt">IO</span> ()</span>
<span id="cb42-2"><a href="#cb42-2" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb42-3"><a href="#cb42-3" aria-hidden="true" tabindex="-1"></a>    pins <span class="ot">&lt;-</span> <span class="fu">concat</span> <span class="op">&lt;$&gt;</span> <span class="fu">sequence</span></span>
<span id="cb42-4"><a href="#cb42-4" aria-hidden="true" tabindex="-1"></a>        [ connect <span class="dt">T00</span> <span class="dv">1</span> <span class="dt">T01</span> <span class="dv">0</span></span>
<span id="cb42-5"><a href="#cb42-5" aria-hidden="true" tabindex="-1"></a>        , connect <span class="dt">T00</span> <span class="dv">2</span> <span class="dt">T02</span> <span class="dv">0</span></span>
<span id="cb42-6"><a href="#cb42-6" aria-hidden="true" tabindex="-1"></a>        , connect <span class="dt">T00</span> <span class="dv">3</span> <span class="dt">T03</span> <span class="dv">0</span></span>
<span id="cb42-7"><a href="#cb42-7" aria-hidden="true" tabindex="-1"></a>        , connect <span class="dt">T01</span> <span class="dv">1</span> <span class="dt">T04</span> <span class="dv">0</span></span>
<span id="cb42-8"><a href="#cb42-8" aria-hidden="true" tabindex="-1"></a>        , connect <span class="dt">T01</span> <span class="dv">2</span> <span class="dt">T05</span> <span class="dv">0</span></span>
<span id="cb42-9"><a href="#cb42-9" aria-hidden="true" tabindex="-1"></a>        , connect <span class="dt">T01</span> <span class="dv">3</span> <span class="dt">T06</span> <span class="dv">0</span></span>
<span id="cb42-10"><a href="#cb42-10" aria-hidden="true" tabindex="-1"></a>        , connect <span class="dt">T02</span> <span class="dv">1</span> <span class="dt">T07</span> <span class="dv">0</span></span>
<span id="cb42-11"><a href="#cb42-11" aria-hidden="true" tabindex="-1"></a>        , connect <span class="dt">T02</span> <span class="dv">2</span> <span class="dt">T08</span> <span class="dv">0</span></span>
<span id="cb42-12"><a href="#cb42-12" aria-hidden="true" tabindex="-1"></a>        , connect <span class="dt">T02</span> <span class="dv">3</span> <span class="dt">T09</span> <span class="dv">0</span></span>
<span id="cb42-13"><a href="#cb42-13" aria-hidden="true" tabindex="-1"></a>        , connect <span class="dt">T03</span> <span class="dv">1</span> <span class="dt">T10</span> <span class="dv">0</span></span>
<span id="cb42-14"><a href="#cb42-14" aria-hidden="true" tabindex="-1"></a>        , connect <span class="dt">T03</span> <span class="dv">2</span> <span class="dt">T11</span> <span class="dv">0</span></span>
<span id="cb42-15"><a href="#cb42-15" aria-hidden="true" tabindex="-1"></a>        , connect <span class="dt">T03</span> <span class="dv">3</span> <span class="dt">T12</span> <span class="dv">0</span></span>
<span id="cb42-16"><a href="#cb42-16" aria-hidden="true" tabindex="-1"></a>        , connect <span class="dt">T11</span> <span class="dv">1</span> <span class="dt">T12</span> <span class="dv">1</span></span>
<span id="cb42-17"><a href="#cb42-17" aria-hidden="true" tabindex="-1"></a>        ]</span>
<span id="cb42-18"><a href="#cb42-18" aria-hidden="true" tabindex="-1"></a>    runAll <span class="op">$</span> <span class="fu">map</span> (buildTransputer pins) [<span class="dt">T00</span> <span class="op">..</span>]</span>
<span id="cb42-19"><a href="#cb42-19" aria-hidden="true" tabindex="-1"></a>        <span class="kw">where</span></span>
<span id="cb42-20"><a href="#cb42-20" aria-hidden="true" tabindex="-1"></a>            buildTransputer pins t <span class="ot">=</span></span>
<span id="cb42-21"><a href="#cb42-21" aria-hidden="true" tabindex="-1"></a>                transputer (isDebug t) <span class="op">$</span> onlyFor t pins <span class="op">++</span> extraPins t</span>
<span id="cb42-22"><a href="#cb42-22" aria-hidden="true" tabindex="-1"></a>            pin n ochan ichan <span class="ot">=</span> ((iPin n, ichan), (oPin n, ochan))</span>
<span id="cb42-23"><a href="#cb42-23" aria-hidden="true" tabindex="-1"></a>            onlyFor src l <span class="ot">=</span> [pin p oc ic <span class="op">|</span> (name, p, oc, ic) <span class="ot">&lt;-</span> l, name <span class="op">==</span> src]</span>
<span id="cb42-24"><a href="#cb42-24" aria-hidden="true" tabindex="-1"></a>            extraPins <span class="dt">T00</span> <span class="ot">=</span> [((iPin <span class="dv">0</span>, <span class="dt">InHandle</span> stdin), (oPin <span class="dv">0</span>, <span class="dt">OutHandle</span> stdout))]</span>
<span id="cb42-25"><a href="#cb42-25" aria-hidden="true" tabindex="-1"></a>            extraPins _ <span class="ot">=</span> []</span></code></pre></div>
<h2 id="bonus-static-analysis-tools">Bonus: static analysis tools</h2>
<p>The above <code>transputer</code> function is controlled by the following configuration:</p>
<div class="sourceCode" id="cb43"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb43-1"><a href="#cb43-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Analysis</span> <span class="ot">=</span> <span class="dt">Graph</span> <span class="op">|</span> <span class="dt">Disasm</span></span>
<span id="cb43-2"><a href="#cb43-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb43-3"><a href="#cb43-3" aria-hidden="true" tabindex="-1"></a><span class="ot">isDebug ::</span> <span class="dt">TransputerName</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> <span class="dt">Analysis</span></span>
<span id="cb43-4"><a href="#cb43-4" aria-hidden="true" tabindex="-1"></a>isDebug _ <span class="ot">=</span> <span class="dt">Nothing</span></span></code></pre></div>
<p>It means that for each transputer, we can choose to print a graph or a
disassembly of the code that will be executed. To do that, we will first compute
the set of all edges in the control flow graph.</p>
<p>This analysis relies on a <code>nextInstr</code> function that statically computes the set
of next instructions. These can be reached either because it’s the next
one in the instruction flow (<code>DSeq</code>), because of jump (<code>DJmp</code>), or an unknown
destination, for example after a <code>RET</code> (<code>DDyn</code>).</p>
<div class="sourceCode" id="cb44"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb44-1"><a href="#cb44-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Dest</span> <span class="ot">=</span> <span class="dt">DSeq</span> <span class="dt">Address</span></span>
<span id="cb44-2"><a href="#cb44-2" aria-hidden="true" tabindex="-1"></a>          <span class="op">|</span> <span class="dt">DJmp</span> <span class="dt">Address</span></span>
<span id="cb44-3"><a href="#cb44-3" aria-hidden="true" tabindex="-1"></a>          <span class="op">|</span> <span class="dt">DDyn</span></span>
<span id="cb44-4"><a href="#cb44-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">deriving</span> (<span class="dt">Eq</span>, <span class="dt">Ord</span>)</span>
<span id="cb44-5"><a href="#cb44-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb44-6"><a href="#cb44-6" aria-hidden="true" tabindex="-1"></a><span class="ot">nextInstrs ::</span> <span class="dt">Instr</span> <span class="ot">-&gt;</span> [<span class="dt">Dest</span>]</span>
<span id="cb44-7"><a href="#cb44-7" aria-hidden="true" tabindex="-1"></a>nextInstrs (<span class="dt">Pri</span> <span class="dt">CJ</span> n) <span class="ot">=</span> [<span class="dt">DSeq</span> <span class="dv">0</span>, <span class="dt">DJmp</span> n]</span>
<span id="cb44-8"><a href="#cb44-8" aria-hidden="true" tabindex="-1"></a>nextInstrs (<span class="dt">Pri</span> <span class="dt">J</span> n) <span class="ot">=</span> [<span class="dt">DJmp</span> n]</span>
<span id="cb44-9"><a href="#cb44-9" aria-hidden="true" tabindex="-1"></a>nextInstrs (<span class="dt">Pri</span> <span class="dt">CALL</span> n) <span class="ot">=</span> [<span class="dt">DSeq</span> <span class="dv">0</span>, <span class="dt">DJmp</span> n]</span>
<span id="cb44-10"><a href="#cb44-10" aria-hidden="true" tabindex="-1"></a>nextInstrs (<span class="dt">Sec</span> <span class="dt">GCALL</span>) <span class="ot">=</span> [<span class="dt">DDyn</span>]</span>
<span id="cb44-11"><a href="#cb44-11" aria-hidden="true" tabindex="-1"></a>nextInstrs (<span class="dt">Sec</span> <span class="dt">RET</span>) <span class="ot">=</span> [<span class="dt">DDyn</span>]</span>
<span id="cb44-12"><a href="#cb44-12" aria-hidden="true" tabindex="-1"></a>nextInstrs _ <span class="ot">=</span> [<span class="dt">DSeq</span> <span class="dv">0</span>]</span></code></pre></div>
<p>We can wrap this function in a monadic one that can turn these relative
addresses into absolute ones (since it can know the addresses of functions).</p>
<div class="sourceCode" id="cb45"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb45-1"><a href="#cb45-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">EdgeSet</span> <span class="ot">=</span> <span class="dt">S.Set</span> (<span class="dt">Address</span>, <span class="dt">Instr</span>, <span class="dt">Dest</span>)</span>
<span id="cb45-2"><a href="#cb45-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb45-3"><a href="#cb45-3" aria-hidden="true" tabindex="-1"></a><span class="ot">instrDests ::</span> <span class="dt">Address</span> <span class="ot">-&gt;</span> <span class="dt">Eval</span> <span class="dt">EdgeSet</span></span>
<span id="cb45-4"><a href="#cb45-4" aria-hidden="true" tabindex="-1"></a>instrDests start <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb45-5"><a href="#cb45-5" aria-hidden="true" tabindex="-1"></a>    iptr <span class="op">.=</span> start</span>
<span id="cb45-6"><a href="#cb45-6" aria-hidden="true" tabindex="-1"></a>    i <span class="ot">&lt;-</span> decodeInstr</span>
<span id="cb45-7"><a href="#cb45-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> deltaips <span class="ot">=</span> nextInstrs i</span>
<span id="cb45-8"><a href="#cb45-8" aria-hidden="true" tabindex="-1"></a>    new <span class="ot">&lt;-</span> use iptr</span>
<span id="cb45-9"><a href="#cb45-9" aria-hidden="true" tabindex="-1"></a>    <span class="fu">return</span> <span class="op">$</span> S.fromList <span class="op">$</span> <span class="fu">map</span> (\ d <span class="ot">-&gt;</span> (start, i, adjust new d)) deltaips</span>
<span id="cb45-10"><a href="#cb45-10" aria-hidden="true" tabindex="-1"></a>        <span class="kw">where</span></span>
<span id="cb45-11"><a href="#cb45-11" aria-hidden="true" tabindex="-1"></a>            adjust n (<span class="dt">DSeq</span> d) <span class="ot">=</span> <span class="dt">DSeq</span> <span class="op">$</span> n <span class="op">+</span> d</span>
<span id="cb45-12"><a href="#cb45-12" aria-hidden="true" tabindex="-1"></a>            adjust n (<span class="dt">DJmp</span> d) <span class="ot">=</span> <span class="dt">DJmp</span> <span class="op">$</span> n <span class="op">+</span> d</span>
<span id="cb45-13"><a href="#cb45-13" aria-hidden="true" tabindex="-1"></a>            adjust _ <span class="dt">DDyn</span> <span class="ot">=</span> <span class="dt">DDyn</span></span></code></pre></div>
<p>Then, the algorithm consists in computing the fixpoint of the following
iterating function:</p>
<div class="sourceCode" id="cb46"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb46-1"><a href="#cb46-1" aria-hidden="true" tabindex="-1"></a><span class="ot">step ::</span> <span class="dt">EdgeSet</span> <span class="ot">-&gt;</span> <span class="dt">Eval</span> <span class="dt">EdgeSet</span></span>
<span id="cb46-2"><a href="#cb46-2" aria-hidden="true" tabindex="-1"></a>step s <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb46-3"><a href="#cb46-3" aria-hidden="true" tabindex="-1"></a>    xs <span class="ot">&lt;-</span> <span class="fu">mapM</span> (basicBlockM <span class="op">.</span> getDest) <span class="op">$</span> S.toList s</span>
<span id="cb46-4"><a href="#cb46-4" aria-hidden="true" tabindex="-1"></a>    <span class="fu">return</span> <span class="op">$</span> S.union s <span class="op">$</span> S.unions xs</span>
<span id="cb46-5"><a href="#cb46-5" aria-hidden="true" tabindex="-1"></a>        <span class="kw">where</span></span>
<span id="cb46-6"><a href="#cb46-6" aria-hidden="true" tabindex="-1"></a>            getDest (_, _, <span class="dt">DSeq</span> a) <span class="ot">=</span> <span class="dt">Just</span> a</span>
<span id="cb46-7"><a href="#cb46-7" aria-hidden="true" tabindex="-1"></a>            getDest (_, _, <span class="dt">DJmp</span> a) <span class="ot">=</span> <span class="dt">Just</span> a</span>
<span id="cb46-8"><a href="#cb46-8" aria-hidden="true" tabindex="-1"></a>            getDest (_, _, <span class="dt">DDyn</span>) <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb46-9"><a href="#cb46-9" aria-hidden="true" tabindex="-1"></a>            basicBlockM (<span class="dt">Just</span> a) <span class="ot">=</span> instrDests a</span>
<span id="cb46-10"><a href="#cb46-10" aria-hidden="true" tabindex="-1"></a>            basicBlockM <span class="dt">Nothing</span> <span class="ot">=</span> <span class="fu">return</span> S.empty</span></code></pre></div>
<p>The fixpoint itself is computed using the following function, which takes a
predicate on two <code>EdgeSet</code>s to stop the iteration.</p>
<div class="sourceCode" id="cb47"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb47-1"><a href="#cb47-1" aria-hidden="true" tabindex="-1"></a><span class="ot">stepUntil ::</span> ((<span class="dt">EdgeSet</span>, <span class="dt">EdgeSet</span>) <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> (<span class="dt">EdgeSet</span>, <span class="dt">EdgeSet</span>) <span class="ot">-&gt;</span> <span class="dt">Eval</span> <span class="dt">EdgeSet</span></span>
<span id="cb47-2"><a href="#cb47-2" aria-hidden="true" tabindex="-1"></a>stepUntil p (a, b) <span class="op">|</span> p (a, b) <span class="ot">=</span> <span class="fu">return</span> b</span>
<span id="cb47-3"><a href="#cb47-3" aria-hidden="true" tabindex="-1"></a>stepUntil p (_, b) <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb47-4"><a href="#cb47-4" aria-hidden="true" tabindex="-1"></a>    c <span class="ot">&lt;-</span> step b</span>
<span id="cb47-5"><a href="#cb47-5" aria-hidden="true" tabindex="-1"></a>    stepUntil p (b, c)</span></code></pre></div>
<p>We’ll stop when their size is equal.</p>
<div class="sourceCode" id="cb48"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb48-1"><a href="#cb48-1" aria-hidden="true" tabindex="-1"></a><span class="ot">runAnalysis ::</span> <span class="dt">Maybe</span> <span class="dt">Analysis</span> <span class="ot">-&gt;</span> <span class="dt">Eval</span> ()</span>
<span id="cb48-2"><a href="#cb48-2" aria-hidden="true" tabindex="-1"></a>runAnalysis <span class="dt">Nothing</span> <span class="ot">=</span> <span class="fu">return</span> ()</span>
<span id="cb48-3"><a href="#cb48-3" aria-hidden="true" tabindex="-1"></a>runAnalysis (<span class="dt">Just</span> analysis) <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb48-4"><a href="#cb48-4" aria-hidden="true" tabindex="-1"></a>    s0 <span class="ot">&lt;-</span> instrDests memStart</span>
<span id="cb48-5"><a href="#cb48-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> p (a, b) <span class="ot">=</span> S.size a <span class="op">==</span> S.size b</span>
<span id="cb48-6"><a href="#cb48-6" aria-hidden="true" tabindex="-1"></a>    r <span class="ot">&lt;-</span> stepUntil p (S.empty, s0)</span>
<span id="cb48-7"><a href="#cb48-7" aria-hidden="true" tabindex="-1"></a>    liftIO <span class="op">$</span> <span class="fu">putStrLn</span> <span class="op">$</span> convert analysis r</span>
<span id="cb48-8"><a href="#cb48-8" aria-hidden="true" tabindex="-1"></a>    iptr <span class="op">.=</span> memStart</span></code></pre></div>
<p>Finally, here is how to convert the <code>EdgeSet</code>s in a human-readable form.</p>
<div class="sourceCode" id="cb49"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb49-1"><a href="#cb49-1" aria-hidden="true" tabindex="-1"></a><span class="ot">convert ::</span> <span class="dt">Analysis</span> <span class="ot">-&gt;</span> <span class="dt">EdgeSet</span> <span class="ot">-&gt;</span> <span class="dt">String</span></span>
<span id="cb49-2"><a href="#cb49-2" aria-hidden="true" tabindex="-1"></a>convert <span class="dt">Graph</span> es <span class="ot">=</span></span>
<span id="cb49-3"><a href="#cb49-3" aria-hidden="true" tabindex="-1"></a>    <span class="st">&quot;digraph G{\n&quot;</span></span>
<span id="cb49-4"><a href="#cb49-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span> <span class="st">&quot;node[shape=point]\n&quot;</span></span>
<span id="cb49-5"><a href="#cb49-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span> <span class="fu">concatMap</span> edge (S.toList es)</span>
<span id="cb49-6"><a href="#cb49-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span> <span class="st">&quot;}&quot;</span></span>
<span id="cb49-7"><a href="#cb49-7" aria-hidden="true" tabindex="-1"></a>        <span class="kw">where</span></span>
<span id="cb49-8"><a href="#cb49-8" aria-hidden="true" tabindex="-1"></a>            edge (x, i, y) <span class="ot">=</span> <span class="fu">show</span> x <span class="op">++</span> <span class="st">&quot; -&gt; &quot;</span> <span class="op">++</span> toNode x y <span class="op">++</span> <span class="st">&quot;[label=\&quot;&quot;</span> <span class="op">++</span> <span class="fu">show</span> i <span class="op">++</span> <span class="st">&quot;\&quot;];\n&quot;</span></span>
<span id="cb49-9"><a href="#cb49-9" aria-hidden="true" tabindex="-1"></a>            toNode _ (<span class="dt">DSeq</span> a) <span class="ot">=</span> <span class="fu">show</span> a</span>
<span id="cb49-10"><a href="#cb49-10" aria-hidden="true" tabindex="-1"></a>            toNode _ (<span class="dt">DJmp</span> a) <span class="ot">=</span> <span class="fu">show</span> a</span>
<span id="cb49-11"><a href="#cb49-11" aria-hidden="true" tabindex="-1"></a>            toNode x <span class="dt">DDyn</span> <span class="ot">=</span> <span class="st">&quot;dyn&quot;</span> <span class="op">++</span> <span class="fu">show</span> x</span>
<span id="cb49-12"><a href="#cb49-12" aria-hidden="true" tabindex="-1"></a>convert <span class="dt">Disasm</span> es <span class="ot">=</span> <span class="fu">concatMap</span> go <span class="op">$</span> S.toList es</span>
<span id="cb49-13"><a href="#cb49-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb49-14"><a href="#cb49-14" aria-hidden="true" tabindex="-1"></a>        go (x, i, <span class="dt">DSeq</span> _) <span class="ot">=</span></span>
<span id="cb49-15"><a href="#cb49-15" aria-hidden="true" tabindex="-1"></a>            printf <span class="st">&quot;%04x %s\n&quot;</span> x (<span class="fu">show</span> i)</span>
<span id="cb49-16"><a href="#cb49-16" aria-hidden="true" tabindex="-1"></a>        go (x, i, <span class="dt">DJmp</span> y) <span class="ot">=</span></span>
<span id="cb49-17"><a href="#cb49-17" aria-hidden="true" tabindex="-1"></a>            printf <span class="st">&quot;%04x %s  [* %04x]\n&quot;</span> x (<span class="fu">show</span> i) y</span>
<span id="cb49-18"><a href="#cb49-18" aria-hidden="true" tabindex="-1"></a>        go (x, i, <span class="dt">DDyn</span>) <span class="ot">=</span></span>
<span id="cb49-19"><a href="#cb49-19" aria-hidden="true" tabindex="-1"></a>            printf <span class="st">&quot;%04x %s  [* dyn]\n&quot;</span> x (<span class="fu">show</span> i)</span></code></pre></div>
<p>For example here is an extract of the beginning of the first transputer. You can
notice instructions with several destinations (conditional jumps) are displayed
twice.</p>
<pre><code>80000100 AJW -76
80000102 LDC 0
80000103 STL 1
80000104 LDC 0
80000105 STL 3
80000106 MINT
80000108 LDNLP 1024
8000010b GAJW
8000010d AJW -76
8000010f LDC 201
80000111 LDPI
80000113 MINT
80000115 LDC 8
80000116 OUT
80000117 LDLP 73
80000119 MINT
8000011b LDNLP 4
8000011c LDC 12
8000011d IN
8000011e LDL 73
80000120 CJ 21
80000120 CJ 21  [* 80000137]
80000122 LDC 205
80000124 LDPI</code></pre>
<p>For the graph output, I assume that you have already seen graphviz output:</p>
<figure>
<img src="/img/st20/t03.png" alt="T03 with dot driver" />
<figcaption aria-hidden="true">T03 with dot driver</figcaption>
</figure>
<p>The introduction image was done using the same output but an alternative layout
engines.</p>
<p>Hope you enjoyed this article!</p>]]></description>
    <pubDate>Thu, 20 Aug 2015 00:00:00 UT</pubDate>
    <guid>http://blog.emillon.org/posts/2015-08-20-a-lens-based-st20-emulator.html</guid>
    <dc:creator>Etienne Millon</dc:creator>
</item>

    </channel>
</rss>
