<?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>HackerFoo Writes Stuff Here</title>
        <link>https://www.hackerfoo.com</link>
        <description><![CDATA[Things I thought might be interesting to others.]]></description>
        <atom:link href="https://www.hackerfoo.com/rss.xml" rel="self"
                   type="application/rss+xml" />
        <lastBuildDate>Sat, 15 Aug 2020 00:00:00 UT</lastBuildDate>
        <item>
    <title>Startup Memory Allocation in PoprC</title>
    <link>https://www.hackerfoo.com/posts/poprc-startup-memory-allocation.html</link>
    <description><![CDATA[<h3 id="arbitrary-limits-are-bad">Arbitrary limits are bad</h3>
<p>I’ve written PoprC in an embedded style of C, where <code>malloc()</code> is avoided. This has a lot of benefits: no dynamic allocation overhead, repeatable addresses which can be used as identifiers, and the ability to use watchpoints when debugging, as well as being able to easily iterate over arrays.</p>
<p>It does have one large drawback, though: because memory is statically allocated, the sizes cannot change. I generally try to set the limits around 2x a reasonable amount, but while this works okay for development, I know it’s not acceptable for end use.</p>
<h3 id="startup-static-allocation">Startup “static” allocation</h3>
<p>To address this, I implemented an easy way to perform “static” allocation on startup (in <a href="https://github.com/HackerFoo/poprc/blob/master/startle/static_alloc.c"><code>static_alloc.c</code></a>. The idea is to perform all allocations with arbitrary limits on startup, which allows the opportunity to adjust the sizes based on flags or a configuration file.</p>
<p>Doing this manually would be annoying, so I used the code generation system that I’ve used elsewhere to collect macros of the form <code>STATIC_ALLOC(name, type, default_size)</code>. Then, I would translate allocations of the form <code>type name[size]</code> into that macro throughout PoprC’s source. In addition, there are extended forms of the macro to specify alignment (<code>STATIC_ALLOC_ALIGNED</code>) and sizes that are dependent on another (<code>STATIC_ALLOC_DEPENDENT</code>.)</p>
<p>There are a few drawbacks to this system:</p>
<ul>
<li>Sizes can’t depend on things not visible in <code>static_alloc.c</code></li>
<li>Types must also be visible in that file.</li>
<li>Static allocations are in a single namespace, so collisions might be a problem.</li>
<li>Addresses are no longer static, so some things must be set up on initialization (e.g. in <code>*_init()</code> procedures.)</li>
<li>LLDB seems to have more difficulty with <code>malloc</code>’ed pointers for some reason.</li>
</ul>
<p>All of these limitations were fairly easy to work with.</p>
<p>A nice added feature for debugging is the compiler can identify pointers in the allocated region, which is most of the pointers I’m interested in during debugging. I can type <code>pp (some pointer)</code> in LLDB now to display a description of the form <code>variable[offset]</code> (see <a href="https://github.com/HackerFoo/poprc/blob/master/startle/static_alloc.c#L171-L188"><code>print_static_alloc()</code></a>.)</p>
<h3 id="future-work">Future work</h3>
<p>Some allocations aren’t needed all of the time. I would like to implement a way to perform temporary allocations in an area allocated on startup (using <code>static_alloc.c</code>) which is large enough to hold the maximum temporary allocation. This would be like a statically allocated union where the fields can be declared anywhere.</p>
<p>I have yet to implement reading allocation sizes from a configuration file, so PoprC is just using the default sizes. After implementing this, it would be good to have assertion messages that indicate which size needs to be adjusted.</p>]]></description>
    <pubDate>Sat, 15 Aug 2020 00:00:00 UT</pubDate>
    <guid>https://www.hackerfoo.com/posts/poprc-startup-memory-allocation.html</guid>
    <dc:creator>Dustin DeWeese</dc:creator>
</item>
<item>
    <title>Error Highlighting in PoprC</title>
    <link>https://www.hackerfoo.com/posts/poprc-error-highlighting.html</link>
    <description><![CDATA[<h3 id="what-is-an-error-anyway">What is an error anyway…</h3>
<p>I have refrained from implementing error messages for PoprC until now.</p>
<p>There are several reasons for this:</p>
<ol type="1">
<li><p><strong>Failure is okay, and expected.</strong></p>
<p>Other than trivial syntax errors, there is only one possible error in a Popr program - program non-determinism. Determinism is the property of having a unique successful execution path for any input, so a non-deterministic program has either no successful path, or multiple successful paths, for some input. While the program must be deterministic, it’s okay for any part to fail (e.g. division when the divisor is zero) as long as it is handled by the consumer of that computation. Every branch must fail except one, so failure is common and expected.</p>
<pre><code>1 0 /     __ Division by zero
&quot;one&quot; 2 + __ Addition operates on integers
3 False ! __ Asserting False</code></pre>
<p>These all fail, but appending <code>True |</code> to any one of these will result in <code>True</code>.</p>
<p>This means detecting true errors requires the entire program context, which is not always available. Automatically proving determinism is not implemented yet, and is not solvable in general.</p></li>
<li><p><strong>Reduction is lossy, which can make locating errors in the source imprecise.</strong></p>
<p>Location information is discarded during reduction, and yet the result might fail after reduction. The reduction graph is more expressive than the source language, so a failure might not correspond to a precise location in the original source code.</p>
<p>A simple example is that in <code>1 2 swap 3 + odd !</code>, <code>2</code> is not involved in the error, but after reducing the addition, the location of the result must include the constants <code>1</code> and <code>3</code> from which the result (<code>4</code>) is derived.</p></li>
<li><p><strong>Source locations take up space.</strong></p>
<p>Popr uses a very compact internal representation (IR) graph. For a long time, I’ve been able to fit everything I’ve needed for the IR into 64 byte nodes, but there’s no space for another byte, much less another pointer.</p></li>
</ol>
<!--more-->
<p>Despite this, the previous behavior of omitting output for all errors is not an acceptable user experience, especially for new users. Just printing “Error!” isn’t acceptable, either. So we need a useful error message, if not a perfectly accurate one. It should be useful for catching simple errors without looking through the logs.</p>
<p>So I made some concessions:</p>
<ul>
<li>While some failures are expected, the programmer rarely intends an expression that will always fail (such as <code>1 0 /</code>.)</li>
<li>Imprecise locations are better than nothing.</li>
<li>Error reporting is worth increasing the IR node size, even though this space is “wasted” on a successful compilation.<br />
If this ever becomes a concern, I can use a compile time flag to disable it.</li>
</ul>
<h3 id="how-it-works">How it works</h3>
<p>All nodes are annotated with source locations (seg_t) at parse time. This requires an extra 16 bytes <em>(+25%)</em>. Oh well.</p>
<pre>
union cell {
  <span class="code-highlight">uintptr_t c[10]; // <--- UP FROM 8</span>
  struct {
    union {
      cell_t *alt;
      const char *word_name; /* entry */
    };
    union {
      cell_t *tmp;
      val_t tmp_val;
      const char *module_name; /* entry */
      char_class_t char_class; /* tok_list */
    };
    enum op op;
    <span class="code-highlight">seg_t src; // <--- SOURCE LOCATION</span>
    union {
      uint8_t pos; /* see below */
      uint8_t arg_index; /* arg index (for dep vars) */
      uint8_t var_index; /* final index for vars in trace */
      priority_t priority; /* used in func_list() & delay_branch() */
    };
    refcount_t n;
    csize_t size;
    union {
      expr_t expr;
      value_t value;
      tok_list_t tok_list;
      entry_t entry;
      mem_t mem;
    };
  }
};
</pre>
<p>When a node is reduced, the source range in the context is expanded to include that node. If a node fails, the context is limited to just that node. This benefits from logic that prioritizes early failures, so that code is often not highlighted if it doesn’t contribute to the failure.</p>
<p>The final source location from the context is propagated to the result node.</p>
<pre>
// Reduce then split c->arg[n]
response reduce_arg(cell_t *c,
                csize_t n,
                context_t *ctx) {
  cell_t **ap = &c->expr.arg[n];
  response r = reduce(ap, ctx);
  if(r <= DELAY) {
    ctx->up->alt_set |= ctx->alt_set;
    <span class="code-highlight">ctx->up->text = seg_range(ctx->up->text, ctx->text); // <--- PROPAGATE SOURCE LOCATION ON REDUCTION</span>
    split_arg(c, n, dup_alt);
  } else if(r == FAIL) {
    <span class="code-highlight">ctx->up->text = ctx->text; // <--- BLAME ONLY THIS REDUCTION ON FAILURE</span>
  }
  return r;
}
</pre>
<p>On each failure, the location from the context is logged to a buffer.</p>
<pre>
// Reduce *cp with type t
response reduce(cell_t **cp, context_t *ctx) {
  cell_t *c = *cp;
  const char *module_name, *word_name;
  get_name(c, &module_name, &word_name); // debug
  assert_error(ctx->depth < MAX_CALL_DEPTH, "stack too deep %C", c);

  while(c) {
    assert_error(is_closure(c));
    c = *cp = fill_incomplete(c);
    stats.reduce_cnt++;
    ctx->text = c->src;
    op op = c->op;
    response r = op_call(op, cp, ctx);

    // prevent infinite loops when debugging
    assert_counter(LENGTH(cells));

    if(!*cp) {
      LOG(MARK("FAIL") ": %O %C (%s.%s) %L @abort",
          op, c, module_name, word_name, ctx->loc.raw);
      <span class="code-highlight">log_fail(ctx); // <--- LOCATION LOGGED HERE</span>
    }
    c = *cp;
    if(r <= DELAY || (r == RETRY && ctx->retry)) {
      ctx->retry = false;
      return r;
    }
  }

  *cp = &fail_cell;
  return FAIL;
}
</pre>
<p>If reduction fails entirely, meaning that the expression will always fail, all locations from the failure log are flattened into a set of non-overlapping locations.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true"></a><span class="dt">size_t</span> get_flattened_error_ranges(seg_t src, pair_t *res) {</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true"></a>  <span class="cf">if</span>(!src.s || !src.n) <span class="cf">return</span> <span class="dv">0</span>;</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true"></a></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true"></a>  <span class="dt">uintptr_t</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true"></a>    l[fail_location_n],</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true"></a>    r[fail_location_n];</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true"></a></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true"></a>  <span class="co">// load offsets into l and r</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true"></a>  COUNTUP(i, fail_location_n) {</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true"></a>    l[i] = clamp(<span class="dv">0</span>, (<span class="dt">intptr_t</span>)src.n, fail_location[i].s - src.s);</span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true"></a>    r[i] = clamp(<span class="dv">0</span>, src.n, l[i] + fail_location[i].n);</span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true"></a>  }</span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true"></a></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true"></a>  <span class="cf">return</span> flatten_ranges(l, r, res, fail_location_n);</span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true"></a>}</span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true"></a></span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true"></a><span class="dt">void</span> highlight_errors(seg_t src) {</span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true"></a>  pair_t res[fail_location_n];</span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true"></a>  <span class="dt">size_t</span> n = get_flattened_error_ranges(src, res);</span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true"></a>  <span class="dt">uintptr_t</span> last = <span class="dv">0</span>;</span>
<span id="cb2-21"><a href="#cb2-21" aria-hidden="true"></a>  COUNTUP(i, n) {</span>
<span id="cb2-22"><a href="#cb2-22" aria-hidden="true"></a>    printf(<span class="st">&quot;%.*s&quot;</span>, (<span class="dt">int</span>)(res[i].first - last), src.s + last);</span>
<span id="cb2-23"><a href="#cb2-23" aria-hidden="true"></a>    printf(UNDERLINE_START);</span>
<span id="cb2-24"><a href="#cb2-24" aria-hidden="true"></a>    print_seg_escape((seg_t) { .s = src.s + res[i].first, .n = res[i].second - res[i].first });</span>
<span id="cb2-25"><a href="#cb2-25" aria-hidden="true"></a>    printf(UNDERLINE_END);</span>
<span id="cb2-26"><a href="#cb2-26" aria-hidden="true"></a>    last = res[i].second;</span>
<span id="cb2-27"><a href="#cb2-27" aria-hidden="true"></a>  }</span>
<span id="cb2-28"><a href="#cb2-28" aria-hidden="true"></a>  printf(<span class="st">&quot;%.*s</span><span class="sc">\n</span><span class="st">&quot;</span>, (<span class="dt">int</span>)(src.n - last), src.s + last);</span>
<span id="cb2-29"><a href="#cb2-29" aria-hidden="true"></a>}</span></code></pre></div>
<p>Ranges are flattened by sorting the start and end points (<code>l</code> &amp; <code>r</code>), incrementing/decrementing <code>depth</code>, and recording the transitions from and to <code>depth == 0</code>. Each transition to a non-zero depth is the start of a flattened range, and each transition back to zero is the end. These will always alternate, so they can be stored as <code>pair_t</code>s.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true"></a><span class="dt">size_t</span> flatten_ranges(<span class="dt">uintptr_t</span> *l, <span class="dt">uintptr_t</span> *r, pair_t *res, <span class="dt">size_t</span> n) {</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true"></a>  quicksort(l, WIDTH(l), n);</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true"></a>  quicksort(r, WIDTH(r), n);</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true"></a>  <span class="dt">int</span> depth = <span class="dv">0</span>;</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true"></a>  <span class="dt">size_t</span> out_n = <span class="dv">0</span>;</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true"></a>  <span class="dt">uintptr_t</span> *l_end = l + n;</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true"></a>  LOOP(n * <span class="dv">2</span>) {</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true"></a>    <span class="cf">if</span>(l &gt;= l_end || *l &gt; *r) {</span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true"></a>      depth--;</span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true"></a>      <span class="cf">if</span>(!depth) {</span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true"></a>        res-&gt;second = *r;</span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true"></a>        res++;</span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true"></a>        out_n++;</span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true"></a>      }</span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true"></a>      r++;</span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true"></a>    } <span class="cf">else</span> <span class="cf">if</span> (*l &lt; *r) {</span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true"></a>      <span class="cf">if</span>(!depth) {</span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true"></a>        res-&gt;first = *l;</span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true"></a>      }</span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true"></a>      depth++;</span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true"></a>      l++;</span>
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true"></a>    } <span class="cf">else</span> { <span class="co">// *l == *r</span></span>
<span id="cb3-23"><a href="#cb3-23" aria-hidden="true"></a>      l++;</span>
<span id="cb3-24"><a href="#cb3-24" aria-hidden="true"></a>      r++;</span>
<span id="cb3-25"><a href="#cb3-25" aria-hidden="true"></a>    }</span>
<span id="cb3-26"><a href="#cb3-26" aria-hidden="true"></a>  }</span>
<span id="cb3-27"><a href="#cb3-27" aria-hidden="true"></a>  <span class="cf">return</span> out_n;</span>
<span id="cb3-28"><a href="#cb3-28" aria-hidden="true"></a>}</span></code></pre></div>
<p>The original source is printed to the screen, with the failure locations underlined.</p>
<p>For example:</p>
<pre>
1 <u>2 odd !</u> 3 +
</pre>
<p>Because <code>2 odd</code> is <code>True</code>, causing <code>!</code> to fail.</p>
<p>Or:</p>
<pre>
1 2 + <u>A</u> *
</pre>
<p>Because <code>A</code> is a symbol, and <code>*</code> operates on integers.</p>
<h3 id="theres-still-more-work-to-do">There’s still more work to do</h3>
<p>This is just the first small step in error reporting. There is much left to do:</p>
<ul>
<li>While I find source location is usually all I need to spot an error (<em>what</em> is wrong), it would also be useful to add an explanation <em>why</em> it is wrong.</li>
<li>Locations are only reported in the expression be compiled, but it might be helpful to see failures in source expanded from a function call.</li>
<li>The programmer probably doesn’t expect a branch to fail for all inputs, so an option would be useful to report this as an error.</li>
</ul>
<h3 id="try-it">Try it!</h3>
<p><a href="https://hackerfoo.com/eval.html">Try it out</a> and let me know what you think. For example, try this:</p>
<pre>
1 3 4 - <u>2 2 - * /</u>
</pre>
<p>Note that only the responsible code is underlined in this case.</p>]]></description>
    <pubDate>Tue, 21 Jul 2020 00:00:00 UT</pubDate>
    <guid>https://www.hackerfoo.com/posts/poprc-error-highlighting.html</guid>
    <dc:creator>Dustin DeWeese</dc:creator>
</item>
<item>
    <title>Popr Tutorial - Dot Machines</title>
    <link>https://www.hackerfoo.com/posts/popr-tutorial-0-dot-machines.html</link>
    <description><![CDATA[<p>Popr is a new programming language (<a href="https://github.com/hackerfoo/poprc">compiler</a>, <a href="/eval.html">try it</a>) that works unlike any other programming language that I know of, so a concise description of the language is difficult.</p>
<p>Rather than describe the semantics in relation to other languages, or listing the formal evaluation rules, I will present a graphical notation that, while impractical for larger programs, shows how Popr programs work in an intuitive way.</p>
<p>In this notation, we will build machines that consume and produce dots.</p>
<!--more-->
<p>Before we proceed further, here are the rules for these diagrams:</p>
<h2 id="rules">Rules</h2>
<ol type="1">
<li>Arrows point to dots a machine needs to consume, <em>not</em> where to put the dots that the machine produces.</li>
<li>Arrows enter and leave upward and to the left.</li>
<li>Boxes are dots that hold machines.</li>
<li>Arrows cannot freely cross each other or pass over any component, so components must consume from top to bottom.</li>
<li>If a component consumes more dots than available, a new dot is add to the bottom left.</li>
<li>Each component must have an arrow pointing to each dot it produces.</li>
</ol>
<p>A component is activated by pulling any of the dots that the component produces. Before the component can run, it must pull in a dot for each arrow. This may in turn activate other components, propagating from right to left.</p>
<figure>
<img src="/images/tutorial-grabby-arrow.png" alt="" /><figcaption>Arrows pull in dots</figcaption>
</figure>
<p>I will introduce components as needed.</p>
<h2 id="operators-not">Operators: <code>not</code></h2>
<figure>
<img src="/images/tutorial-not.png" alt="" /><figcaption>not</figcaption>
</figure>
<p><code>not</code> is a component that produces a <code>True</code> dot when given a <code>False</code> dot, and vice versa.</p>
<pre><span class="input">True not</span>
  False
<span class="input">False not</span>
  True
</pre>
<p><code>True</code> and <code>False</code> are dot names. Dot names start with an uppercase letter.</p>
<p><code>not</code> is an example of a component that consumes one dot and produces a related dot. There are many similar components, which I will call “operators”, such as arithmetic operators and comparison operators.</p>
<h2 id="pulln-boxes-popr-and-swap">pullN: boxes, <code>popr</code>, and <code>swap</code></h2>
<p>Components and dots can be placed in a box, for example, <code>[A B]</code> is a box containing <code>A</code> and <code>B</code>.</p>
<p>Any machine, or even a partial machine, such as <code>[not]</code>, can be placed in a box, and boxes themselves can be consumed and produced like any other dot.</p>
<p>Boxed machines are drawn as a machine surrounded by a rectangle (box.)</p>
<figure>
<img src="/images/tutorial-popr.png" alt="" /><figcaption>popr</figcaption>
</figure>
<p><code>popr</code> is a component that pulls one dot from within a box.</p>
<pre><span class="input">: [A B] popr</span>
  [ A ] B
</pre>
<p>Because every box contains a machine, the machine within is activated when pulling from the box:</p>
<pre><span class="input">: [False not]</span>
  [ False not ]
<span class="input">: [False not] popr</span>
  [] True
</pre>
<figure>
<img src="/images/tutorial-swap.png" alt="" /><figcaption>swap</figcaption>
</figure>
<p><code>swap</code> is a component that crosses the top two arrows, so that the top dot and the one beneath it are exchanged.</p>
<pre><span class="input">: A B swap</span>
  B A
</pre>
<figure>
<img src="/images/tutorial-pull.png" alt="" /><figcaption>pull: popr swap</figcaption>
</figure>
<p><code>pull</code> is a machine that combines <code>popr</code> and <code>swap</code> so that the box is above the dot that was pulled out.</p>
<pre><span class="input">: [A B] pull</span>
  B [ A ]
</pre>
<figure>
<img src="/images/tutorial-pull2.png" alt="" /><figcaption>pull2: pull pull</figcaption>
</figure>
<figure>
<img src="/images/tutorial-pull3.png" alt="" /><figcaption>pull3: pull2 pull</figcaption>
</figure>
<p><code>pull</code> is useful because they can be chained together, (the dotted area shows the machines defined above), to create <code>pull2</code> and <code>pull3</code>, which pull 2 and 3 dots, respectively, out of a box.</p>
<pre><span class="input">: [A B C] pull2</span>
  C B [ A ]
<span class="input">: [A B swap C] pull2</span>
  C A [ B ]
<span class="input">: [A B C D] pull3</span>
  D C B [ A ]
</pre>
<p>Some machines can be extended in a straightforward way similar to <code>pull</code>, to form <em>families</em> of machines. These families are named by replacing each number in the name with an uppercase letter, such as <code>pullN</code>.</p>
<h2 id="swap2-drop-pushl-and-pushr">swap2: <code>drop</code>, <code>pushl</code>, and <code>pushr</code></h2>
<figure>
<img src="/images/tutorial-drop.png" alt="" /><figcaption>drop</figcaption>
</figure>
<p><code>drop</code> is a component that cuts off the top arrow, allowing the other arrow to pass underneath.</p>
<p>When an arrow is cut off, the dot to which it pointed can no longer be pulled, which may prevent activating a machine, and the machines that <em>that</em> machine might have activated, and so on.</p>
<em>Exercise:</em> Write the machine <code>head</code>, which removes a single dot from a box.
<pre><span class="input">: :def head: ...</span>
<span class="input">: [A] head</span>
  A
</pre>
<p><em>Tip:</em> Use the <a href="/eval.html">online evaluator</a> to test your solution.</p>
<figure>
<img src="/images/tutorial-pushl.png" alt="" /><figcaption>pushl</figcaption>
</figure>
<p><code>pushl</code> is a component that connects a box to an outside dot, which can be seen as “pushing” the dot into the left side of the box.</p>
<pre><span class="input">: A [B] pushl</span>
  [ A B ]
</pre>
<p>This is a little misleading, though, because machines only pull. <code>pushl</code> does not activate the machine inside the box; it just connects an arrow from the machine inside the box to a dot outside.</p>
<pre><span class="input">: False [not] pushl</span>
  [ False not ]
<span class="input">: False not [] pushl</span>
  [ False not ]
</pre>
<p>The result may be surprising, but this diagram explains the result:</p>
<figure>
<img src="/images/tutorial-false-not-box.png" alt="" /><figcaption><em>Box of potential truth</em></figcaption>
</figure>
<p>In the second example, <code>False</code> is pulled into the box with <code>not</code>. In both cases <code>[False not]</code> represents a machine that has not been activated.</p>
<p><code>popr</code> can be used to activate the machine:</p>
<pre><span class="input">: False [not] pushl popr</span>
  [] True
</pre>
<figure>
<img src="/images/tutorial-pushr.png" alt="" /><figcaption>pushr</figcaption>
</figure>
<p><code>pushr</code> is a component that pushes a dot into the right side of a box, which can be retrieved with <code>popr</code>.</p>
<pre><span class="input">: [A] B pushr</span>
  [ A B ]
<span class="input">: [A] B pushr popr</span>
  [ A ] B
<span class="input">: [] False not pushr</span>
  [ False not ]
</pre>
<p>Just like <code>pushl</code>, it does not activate any components or the machine inside the box.</p>
<p><em>Note:</em> The dot is on top of <code>pushr</code> because it is an abbreviation of a more verbose diagram where the dot is in the middle; see <code>compose</code>.</p>
<figure>
<img src="/images/tutorial-swap2.png" alt="" /><figcaption>swap2: [] swap pushr swap pushr pushl pull3 drop</figcaption>
</figure>
<p>Now, we can build something a little more interesting using these new components. <code>swapN</code> is another family of machines, starting with <code>swap</code>, which rotates two dots.</p>
<p><code>swap2</code> rotates three dots, as shown by the labels in the diagram, bringing the bottom dot to the top.</p>
<pre><span class="input">: A B C swap2 </span>
  B C A
</pre>
<em>Exercise:</em> Write a machine to swap two dots within a box.
<pre><span class="input">: :def swab: ...</span>
<span class="input">: [A B] swab </span>
  [ B A ]
</pre>
<h2 id="dip11-apnm">dip11: <code>apNM</code></h2>
<p><code>pushl</code> and <code>popr</code> use a box to consume and produce (respectively) one dot, but it can be tedious to do this one dot at a time, so there is a family of components, <code>apMN</code>, which consume <code>M</code> dots and produce <code>N</code> dots.</p>
<pre><span class="input">: A B [C] ap21</span>
  [ A B ] C
</pre>
<p><code>apMN</code> is equivalent to <code>M</code> <code>pushl</code>s followed by <code>N</code> <code>popr</code>s, e.g. <code>ap21</code> is equivalent to: <code>pushl pushl popr</code> Therefore, <code>pushl</code> is <code>ap10</code>, and <code>popr</code> is <code>ap01</code>.</p>
<figure>
<img src="/images/tutorial-dip11.png" alt="" /><figcaption>dip11: swap pushr ap12 swap2 drop</figcaption>
</figure>
<p><code>dip11</code> runs a dot through a given box, like <code>ap11</code>, but without affecting the dot on top.</p>
<p>The dot labeled <code>f</code> is a box containing a machine that consumes a dot and produces another. <code>dip11</code> uses <code>pushr</code> to stash the dot on top within the given box, and then uses <code>ap12</code> to run the machine and pull the stashed dot back out along with the produced dot. There is no need to produce the remaining box, so it is dropped (<em>not</em> pulled.)</p>
<pre><span class="input">: False A [not] dip11</span>
  True A
<span class="input">: False A [] dip11</span>
  False A
</pre>
<h2 id="ifte-assert-alt-and-.-compose">ifte: <code>!</code> (assert), <code>|</code> (alt), and <code>.</code> (compose)</h2>
<figure>
<img src="/images/tutorial-assert.png" alt="" /><figcaption>assert</figcaption>
</figure>
<p><code>!</code> (assert) either produces the dot from the lower arrow if the upper arrow consumes a dot called <code>True</code>, otherwise, it produces a broken dot, which breaks everything that consumes it. Broken machines don’t produce anything.</p>
<pre><span class="input">: A True !</span>
  A
<span class="input">: A 42 !</span>
</pre>
<p><em>Note:</em> Because a broken machine doesn’t produce anything, nothing is printed in this case.</p>
<figure>
<img src="/images/tutorial-alt.png" alt="" /><figcaption>alt</figcaption>
</figure>
<p><code>|</code> (alt) represents two versions of the machine to try: one version using the top arrow, and another version using the bottom arrow.</p>
<pre><span class="input">: A B |</span>
  A
  B
<span class="input">: A B False ! |</span>
  A
</pre>
<p><em>Note:</em> The results from both versions of the machine are printed on different lines.</p>
<figure>
<img src="/images/tutorial-compose.png" alt="" /><figcaption>compose</figcaption>
</figure>
<p><code>.</code> (compose) puts two boxes together, merging the two machines into one box by connecting them together. This component does not activate the machine within the box.</p>
<p><em>Note:</em> <code>pushr</code> is equivalent to: <code>[] pushl .</code></p>
<pre><span class="input">: [A] [B] .</span>
  [ A B ]
<span class="input">: [False] [not] . popr</span>
  [] True
<span class="input">: [A B] [swap] .</span>
  [ A B swap ]
</pre>
<p>Notice that the last example did not print: <code>[ B A ]</code></p>
<figure>
<img src="/images/tutorial-ifte.png" alt="" /><figcaption>ifte: [] ap20 swap pushr [not !] [swap drop !] | . head</figcaption>
</figure>
<p><code>ifte</code> uses the components discussed to select between two dots, depending on the name of the first dot.</p>
<p>The first part of <code>ifte</code>, <code>[] ap20 swap pushr</code>, arranges the three dots in a box, as shown in the fluffy bubble.</p>
<p>There are two versions of the machine, indicated by the circle (alt) pointing to the boxes <code>F</code> and <code>G</code>. The boxed dots and <code>F</code> (for one version, <code>G</code> for the other) are put together into one box, using compose. The result is pulled out of the box, using the component <code>head</code>, defined in the earlier exercise.</p>
<p>In both <code>F</code> and <code>G</code>, there is an assertion <code>!</code> connected to <code>A</code>. In F, it is negated with <code>not</code>, and <code>C</code> is passed through. In <code>G</code>, <code>A</code> is passed directly to the assertion, and <code>B</code> is passed through, while <code>C</code> is dropped (not needed.)</p>
<p>So, we have two versions of this machine:</p>
<ol type="1">
<li>Works if <code>A</code> is <code>True</code>, using <code>G</code> to extract <code>B</code>.</li>
<li>Works if <code>A</code> is <code>False</code>, using <code>F</code> to extract <code>C</code>.</li>
</ol>
<p>Now that we have two machines, we can just try both, and keep the results from the one that doesn’t break. This works as intended, producing <code>B</code> or <code>C</code> depending on if <code>A</code> is <code>True</code>.</p>
<pre><span class="input">: True A B ifte</span>
  A
<span class="input">: False A B ifte</span>
  B
</pre>
<em>Exercise:</em> Use <code>ifte</code> to write a machine that inverts the first dot if the second is <code>True</code>.
<pre><span class="input">: :def bxor: ...</span>
<span class="input">: False False bxor</span>
  False
<span class="input">: False True bxor</span>
  True
<span class="input">: True False bxor</span>
  False
<span class="input">: True True bxor </span>
  True
</pre>
<h2 id="dup">dup</h2>
<figure>
<img src="/images/tutorial-dup.png" alt="" /><figcaption>dup</figcaption>
</figure>
<p>One of the remaining components is <code>dup</code>, which produces two copies.</p>
<pre><span class="input">: A dup</span>
  A A
</pre>
<em>Exercise:</em> Write the following machine.
<pre><span class="input">: :def abba: ...</span>
<span class="input">: A B abba</span>
  A B B A
<span class="input">: B A abba</span>
  B A A B
</pre>
<h2 id="so-then">So Then</h2>
<p>While this notation isn’t ideal for large programs, both the diagrams and Popr programs can be broken into smaller pieces (as seen in <code>ifte</code>). This notation can be useful to introduce the semantics of Popr programs, and can be used to analyze any behavior that is confusing or surprising.</p>]]></description>
    <pubDate>Sat, 31 Mar 2018 00:00:00 UT</pubDate>
    <guid>https://www.hackerfoo.com/posts/popr-tutorial-0-dot-machines.html</guid>
    <dc:creator>Dustin DeWeese</dc:creator>
</item>
<item>
    <title>PoprC Runtime Operation Part 4: Alternatives</title>
    <link>https://www.hackerfoo.com/posts/poprc-runtime-operation-part4.html</link>
    <description><![CDATA[<p>Every programming language supports some form of branching. A simple form of branching is the C <code>if</code> statement, which evaluates a boolean expression, and then selects a branch based on the value of that expression. This works well if the branching condition can be calculated before choosing a branch, but sometimes a branch can’t be selected until one of the branches has been partially computed. If this is the case, the programmer has to write several nested <code>if</code> statements, one for each decision point, and divide the calculation into incremental fragments, often repeating parts of the same calculation in different branches. Another example of this type of branching is common in error handling, where errors are checked in several places. If an error occurs, the program must jump to an alternate branch which handles the error, often by aborting the calculation and returning an error to the caller, which will continue to propagate upwards until it can be handled reasonably. This is why C++ explicitly supports exceptions, although it is really just a type of branching.</p>
<!--more-->
<p>Many pipelined processors handle branching slightly different from the semantics of the <code>if</code> statement. Instead of stalling while waiting for the condition to be fully evaluated, the processors has a branch prediction unit, which just makes a guess and follows a branch. The processor backtracks if it chose the wrong branch. The programming language Prolog takes this even further; every code path is executed exhaustively until the computation is successful. Whenever a branch <em>fails</em> (is determined to be invalid), the program backtracks to the last branch point with an unfollowed branch, and then continues along that branch. This is repeated until the program finds a successful path to a result.</p>
<p>The Popr language is designed with Prolog style backtracking as the only form of branching, because this subsumes other types of conditional statements. Furthermore, since Popr is partially evaluated at compile time, backtracking implements an advanced type system, because the compiler will just try all versions of each function until it can form a program that is well typed.</p>
<p>Branches in Popr are called alternatives, and are created with the alternative function (<code>|</code>). Two fields are present in <code>cell_t</code> to support alternatives. The <code>alt</code> field points to the next alternative path in the graph. The <code>alt_set</code> field is used to determine if two paths are compatible, by making sure that values can’t take conflicting paths. This prevents results such as <code>2 3 | dup +</code> evaluating to <code>5</code>; <code>4</code> and <code>6</code> are the only valid results.</p>
<p>Alternatives are expanded during reduction by a process called <em>splitting</em>; when a function has <span class="math inline"><em>N</em></span> arguments having alternatives, <span class="math inline">2<sup><em>N</em></sup></span> copies are created from all the combinations generated by replacing an argument with its alternative. If any argument has more than one alternative, they will continue to be expanded further when they are reduced later.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true"></a>cell_t *dup_alt(cell_t *c, <span class="dt">unsigned</span> <span class="dt">int</span> n, cell_t *b) {</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true"></a>  <span class="dt">unsigned</span> <span class="dt">int</span> i = <span class="dv">0</span>, in = closure_in(c), out = <span class="dv">0</span>;</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true"></a>  assert(n &lt; in);</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true"></a>  cell_t *a = copy(c);</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true"></a></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true"></a>  <span class="co">// ref args</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true"></a>  <span class="cf">for</span>(; i &lt; in; ++i) {</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true"></a>    <span class="cf">if</span>(i != n) ref(a-&gt;arg[i]);</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true"></a>  }</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true"></a></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true"></a>  <span class="co">// update deps</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true"></a>  <span class="cf">for</span>(; i &lt; c-&gt;size; ++i) {</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true"></a>    <span class="cf">if</span>(a-&gt;arg[i]) a-&gt;arg[i] = dep(a);</span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true"></a>    c-&gt;arg[i]-&gt;alt =</span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true"></a>	  conc_alt(a-&gt;arg[i], c-&gt;arg[i]-&gt;alt);</span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true"></a>    ++out;</span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true"></a>  }</span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true"></a></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true"></a>  a-&gt;arg[n] = b;</span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true"></a>  a-&gt;n = out;</span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true"></a>  c-&gt;alt = a;</span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true"></a>  <span class="cf">return</span> a;</span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true"></a>}</span></code></pre></div>
<p><code>dup_alt(c, n, b)</code> copies <code>c</code>, with <code>c-&gt;arg[n]</code> replaced with <code>b</code>, and assigns <code>c-&gt;alt</code> to <code>b</code>; this is the basic operation of creating a new alternative.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true"></a><span class="dt">void</span> split_arg(cell_t *c, <span class="dt">unsigned</span> <span class="dt">int</span> n) {</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true"></a>  cell_t</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true"></a>    *a = c-&gt;arg[n],</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true"></a>    *p = c,</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true"></a>    **pa;</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true"></a>  <span class="cf">if</span>(!a || !a-&gt;alt || is_marked(a, <span class="dv">1</span>)) <span class="cf">return</span>;</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true"></a>  <span class="cf">do</span> {</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true"></a>    pa = &amp;p-&gt;arg[n];</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true"></a>    <span class="cf">if</span>(*pa == a) {</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true"></a>      <span class="co">// insert a copy with the alt arg</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true"></a>      p = dup_alt(p, n, ref((*pa)-&gt;alt))-&gt;alt;</span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true"></a>      <span class="co">// mark the arg</span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true"></a>      *pa = mark_ptr(*pa, <span class="dv">1</span>);</span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true"></a>    } <span class="cf">else</span> p = p-&gt;alt;</span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true"></a>  } <span class="cf">while</span>(p);</span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true"></a>}</span></code></pre></div>
<p><code>split_arg(c, n)</code> splits <code>c</code> on the <code>n</code>th argument. Any alternative of <code>c</code> having the same argument in the same position is split. When a closure is split on an argument <code>n</code>, the new closure has the argument <code>c-&gt;arg[n]-&gt;alt</code>, but the old one needs a new argument that no longer has an alternative, so that <code>c-&gt;arg[n]-&gt;alt</code> isn’t split and followed more than once. Rather than make a copy without an alternative, the low bit of the pointer <code>c-&gt;arg[n]</code> is set, marking that the <code>alt</code> field should be ignored, as if <code>c-&gt;arg[n]-&gt;alt</code> was set to <code>0</code>.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true"></a>cell_t *closure_split(cell_t *c, <span class="dt">unsigned</span> <span class="dt">int</span> s) {</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true"></a>  <span class="dt">int</span> i;</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true"></a>  <span class="cf">for</span>(i = <span class="dv">0</span>; i &lt; s; ++i) {</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true"></a>    split_arg(c, i);</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true"></a>  }</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true"></a>  <span class="cf">for</span>(i = <span class="dv">0</span>; i &lt; s; ++i) {</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true"></a>    c-&gt;arg[i] = clear_ptr(c-&gt;arg[i], <span class="dv">1</span>);</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true"></a>  }</span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true"></a>  <span class="cf">return</span> c-&gt;alt;</span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true"></a>}</span></code></pre></div>
<p><code>closure_split(c, s)</code> splits <code>c</code> from <code>c-&gt;arg[0]</code> to <code>c-&gt;arg[s-1]</code>, and then clears the flags set on the arguments of <code>c</code> (so they are ready for reduction), and returns <code>c-&gt;alt</code>. This function must generally be called after <code>c-&gt;arg[0]</code> to <code>c-&gt;arg[s-1]</code> have been reduced for alternatives to work correctly.</p>
<p>An <code>alt_set_t</code> is a bit field indicating which alternatives have been followed to reach a value. Functions for manipulating <code>alt_set</code>s are prefixed with <code>as</code>.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true"></a>alt_set_t as(<span class="dt">unsigned</span> <span class="dt">int</span> k, <span class="dt">unsigned</span> <span class="dt">int</span> v) {</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true"></a>  assert(k &lt; AS_SIZE);</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true"></a>  <span class="cf">return</span> ((alt_set_t)<span class="dv">1</span> &lt;&lt; (k + AS_SIZE)) |</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true"></a>    (((alt_set_t)v &amp; <span class="dv">1</span>) &lt;&lt; k);</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true"></a>}</span></code></pre></div>
<p>Each point where an alternative is chosen (<code>|</code> is reduced) has an associated unique identifier. <code>as(k, v)</code> creates an <code>alt_set_t</code> that indicates which alternative was followed at point <code>k</code>. If <code>v</code> is <code>0</code>, the first alternative was followed; if <code>v</code> is <code>1</code>, the second alternative was followed.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true"></a>alt_set_t as_conflict(alt_set_t a, alt_set_t b) {</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true"></a>  <span class="cf">return</span> ((a &amp; b) &gt;&gt; AS_SIZE) &amp;</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true"></a>    ((a ^ b) &amp; (((alt_set_t)<span class="dv">1</span>&lt;&lt;AS_SIZE)-<span class="dv">1</span>));</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true"></a>}</span></code></pre></div>
<p><code>as_conflict(a, b)</code> determines if there are any conflicts between <code>a</code> and <code>b</code> i.e. both alternatives where followed at some point. If two <code>alt_set</code>s do not conflict, they can be combined with bitwise or.</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true"></a><span class="dt">bool</span> entangle(alt_set_t *as, cell_t *c) {</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true"></a>  <span class="cf">return</span> !as_conflict(*as, c-&gt;alt_set) &amp;&amp;</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true"></a>    (*as |= c-&gt;alt_set, true);</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true"></a>}</span></code></pre></div>
<p><code>entangle(&amp;as, c)</code> returns <code>false</code> if <code>c-&gt;alt_set</code> conflicts with <code>as</code>, otherwise they are combined and stored in <code>as</code>, and the function returns <code>true</code>. This should be called on all reduced arguments of a function to determine the <code>alt_set</code> of the resulting value. If there are conflicts, the function must fail.</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true"></a><span class="dt">bool</span> reduce_arg(cell_t *c,</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true"></a>		<span class="dt">unsigned</span> <span class="dt">int</span> n,</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true"></a>		alt_set_t *as,</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true"></a>		type_t t) {</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true"></a>  <span class="dt">bool</span> r = reduce(&amp;c-&gt;arg[n], t);</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true"></a>  split_arg(c, n);</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true"></a>  <span class="cf">return</span> r &amp;&amp; entangle(as, clear_ptr(c-&gt;arg[n], <span class="dv">1</span>));</span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true"></a>}</span></code></pre></div>
<p><code>reduce_arg(c, n, &amp;as, t)</code> combines the reduction of an argument with splitting and entanglement. It reduces <code>c-&gt;arg[n]</code> with expected type <code>t</code> and entangling <code>as</code>.</p>
<p>Alternatives in Popr are very powerful, allowing logic programming and a powerful type system. The implementation is complex, but partial evaluation can remove alternatives in many cases.</p>]]></description>
    <pubDate>Tue, 19 Nov 2013 00:00:00 UT</pubDate>
    <guid>https://www.hackerfoo.com/posts/poprc-runtime-operation-part4.html</guid>
    <dc:creator>Dustin DeWeese</dc:creator>
</item>
<item>
    <title>PoprC Runtime Operation Part 3: Quotes</title>
    <link>https://www.hackerfoo.com/posts/poprc-runtime-operation-part3.html</link>
    <description><![CDATA[<p>A quote in the PoprC runtime is a fragment of possibly unevaluated code. You can think of a quote as holding a section of code, which can be further assembled and executed. Arguments can be appended to the left (<code>pushl</code>), and results can be removed from the right (<code>popr</code>). Quotes can also be composed using (<code>.</code>). Quote literals are indicated by a section of code surrounded by square brackets (<code>[ ... ]</code>). Quotes can be nested without limit. Quotes can be used as auxiliary stacks.</p>
<p>Quotes <em>cannot</em> be spliced up a level (‘removing the square brackets’.) This would result in all higher order functions having variable arity. Furthermore, the higher order functions’ behavior would be tied to their internal operation, because any function executed within another could consume and modify its internal data, making abstract interpretation and even compile time parsing of library functions difficult. So, the only way to manipulate and access the contents from outside are through <code>pushl</code> and <code>popr</code>.</p>
<p>This is important, because it is what allows PoprC to entirely remove all local (intermediate) quote operations (<code>pushl</code>, <code>popr</code>, and <code>.</code>) from the resulting compiled code. Furthermore, inlining can make more quote operations local, at the expense of code size. This is also interesting because, although most implementations of concatenative languages rely on one or more stacks to store arguments to functions, PoprC aggressively eliminates the only non-primitive datatype (which can be used as a stack), and most function arguments are assigned at compile time.</p>
<!--more-->
<figure>
<img src="/images/incomplete.svg" alt="" /><figcaption><em>Figure 1</em>: <code>[1 + 2 +]</code></figcaption>
</figure>
<p>Quotes are stored as lists, which are vectors of pointers to closures. Pointers to incomplete closures are always on the left of the list (<code>c-&gt;ptr[list_size(c) - 1]</code>). An incomplete closure can contain another incomplete closure (but only one), which forms a chain terminating at the innermost incomplete closure (node 4 in <em>Figure 1</em>, notice it only has one argument). To the right are complete closures, ready to be reduced (except for <code>dep</code>s, which although marked as complete, can point to incomplete closures.)</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true"></a>cell_t *empty_list() {</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true"></a>  cell_t *c = closure_alloc(<span class="dv">1</span>);</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true"></a>  c-&gt;func = func_reduced;</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true"></a>  c-&gt;type = T_LIST;</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true"></a>  <span class="cf">return</span> c;</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true"></a>}</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true"></a></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true"></a>cell_t *quote(cell_t *x) {</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true"></a>  cell_t *c = closure_alloc(<span class="dv">2</span>);</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true"></a>  c-&gt;func = func_reduced;</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true"></a>  c-&gt;type = T_LIST;</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true"></a>  c-&gt;ptr[<span class="dv">0</span>] = x;</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true"></a>  <span class="cf">return</span> c;</span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true"></a>}</span></code></pre></div>
<p>It’s easy to make a list; just allocate the cells, set <code>c-&gt;func</code> and <code>c-&gt;type</code>, and assign the items of the list to <code>c-&gt;ptr</code>. Above is code to create an empty list (<code>empty_list()</code>), and a list with just one item (<code>quote(c)</code>).</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true"></a>cell_t *expand(cell_t *c, <span class="dt">unsigned</span> <span class="dt">int</span> s) {</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true"></a>  <span class="cf">if</span>(!c) <span class="cf">return</span> <span class="dv">0</span>;</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true"></a>  <span class="dt">int</span> n = closure_args(c);</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true"></a>  <span class="dt">int</span> cn_p = calculate_cells(n);</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true"></a>  <span class="dt">int</span> cn = calculate_cells(n + s);</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true"></a>  <span class="cf">if</span>(!c-&gt;n &amp;&amp; cn == cn_p) {</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true"></a>     c-&gt;size += s;</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true"></a>    <span class="cf">return</span> c;</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true"></a>  } <span class="cf">else</span> {</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true"></a>    <span class="co">/* copy */</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true"></a>    cell_t *new = closure_alloc(n + s);</span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true"></a>    memcpy(new, c, cn_p * <span class="kw">sizeof</span>(cell_t));</span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true"></a>    <span class="cf">if</span>(is_placeholder(c)) trace(new, c, tt_copy);</span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true"></a>    new-&gt;n = <span class="dv">0</span>;</span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true"></a>    traverse_ref(new, ARGS_IN | PTRS | ALT);</span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true"></a>    new-&gt;size = n + s;</span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true"></a>    <span class="cf">if</span>(is_reduced(c)) alt_set_ref(c-&gt;alt_set);</span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true"></a>    drop(c);</span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true"></a>    <span class="cf">return</span> new;</span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true"></a>  }</span>
<span id="cb2-21"><a href="#cb2-21" aria-hidden="true"></a>}</span></code></pre></div>
<p>When a larger list is needed to insert more items (such as in <code>compose()</code> and <code>pushl_nd()</code>), <code>expand(c, n)</code> is used to expand <code>c</code> to allow <code>n</code> more items, returning the expanded list.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true"></a>cell_t *pushl_nd(cell_t *a, cell_t *b) {</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true"></a>  assert(is_closure(a) &amp;&amp;</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true"></a>	 is_closure(b) &amp;&amp; is_list(b));</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true"></a></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true"></a>  <span class="dt">int</span> n = list_size(b);</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true"></a>  <span class="cf">if</span>(n) {</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true"></a>    cell_t *l = b-&gt;ptr[n-<span class="dv">1</span>];</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true"></a>    <span class="cf">if</span>(!closure_is_ready(l)) {</span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true"></a>      cell_t *_b = arg_nd(l, a, b);</span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true"></a>      <span class="cf">if</span>(is_placeholder(l)) trace(_b-&gt;ptr[n-<span class="dv">1</span>], l, tt_copy);</span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true"></a>      <span class="cf">return</span> _b;</span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true"></a>    }</span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true"></a>  }</span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true"></a></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true"></a>  cell_t *e = expand(b, <span class="dv">1</span>);</span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true"></a>  e-&gt;ptr[n] = a;</span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true"></a>  <span class="cf">return</span> e;</span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true"></a>}</span></code></pre></div>
<p><code>pushl_nd(a, b)</code> tries to fill in <code>a</code> as an argument for the leftmost item in the list using <code>arg_nd</code>, otherwise the list is expanded and <code>a</code> is inserted in the leftmost position.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true"></a>cell_t *compose_nd(cell_t *a, cell_t *b) {</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true"></a>  <span class="dt">int</span> n = list_size(b);</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true"></a>  <span class="dt">int</span> n_a = list_size(a);</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true"></a>  <span class="dt">int</span> i = <span class="dv">0</span>;</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true"></a>  <span class="cf">if</span>(n &amp;&amp; n_a) {</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true"></a>    cell_t *l;</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true"></a>    <span class="cf">while</span>(!closure_is_ready(l = b-&gt;ptr[n-<span class="dv">1</span>]) &amp;&amp; i &lt; n_a) {</span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true"></a>      cell_t *x = a-&gt;ptr[i];</span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true"></a>      <span class="cf">if</span>(is_placeholder(x)) {</span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true"></a>	<span class="co">/* ... */</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true"></a>      } <span class="cf">else</span> {</span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true"></a>	b = arg_nd(l, ref(x), b);</span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true"></a>	++i;</span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true"></a>      }</span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true"></a>    }</span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true"></a>  }</span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true"></a>  cell_t *e = expand(b, n_a - i);</span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true"></a>  <span class="dt">int</span> j;</span>
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true"></a>  <span class="cf">for</span>(j = n; i &lt; n_a; ++i, ++j) {</span>
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true"></a>    e-&gt;ptr[j] = ref(a-&gt;ptr[i]);</span>
<span id="cb4-21"><a href="#cb4-21" aria-hidden="true"></a>  }</span>
<span id="cb4-22"><a href="#cb4-22" aria-hidden="true"></a>  drop(a);</span>
<span id="cb4-23"><a href="#cb4-23" aria-hidden="true"></a>  <span class="cf">return</span> e;</span>
<span id="cb4-24"><a href="#cb4-24" aria-hidden="true"></a>}</span></code></pre></div>
<p><code>compose_nd(a, b)</code> is similar to <code>pushl_nd</code>, but <code>a</code> is a list, so it conceptually the same as performing <code>pushl_nd(x, b)</code> for each item <code>x</code> in <code>a</code>, but it is much more efficient because <code>b</code> is expanded only once. Ignore <code>if(is_placeholder(x) { ... }</code> for now, just look at the <code>else</code> clause.</p>
<p>The <code>_nd</code> variants of functions are nondestructive to their arguments, so that <code>pushl_nd</code> doesn’t affect other references; only the portion of the graph that has an exclusive reference can be modified and the rest must be copied. This is accomplished with <code>arg_nd(c, a, r)</code> which is similar to <code>arg(c, a)</code>, except the argument <code>r</code> points to the root of the graph of which <code>arg_nd</code> will return a modified version in which <code>c</code> has been supplied argument <code>a</code>.</p>
<p><code>arg_nd</code> uses <code>modify_copy(c, r)</code>, which returns a copy of <code>r</code> where it is safe to modify <code>c</code>.</p>
<pre><code>cell_t *modify_copy(cell_t *c, cell_t *r) {
  cell_t *new = _modify_copy1(c, r, true);
  if(new &amp;&amp; new != r) {
    ref(new);
    drop(r);
  }
  if(new) {
    _modify_copy2(new);
    return new;
  } else return r;
}

void _modify_new(cell_t *r, bool u) {
  cell_t *n;
  if(clear_ptr(r-&gt;tmp, 3)) return;
  if(u) {
    n = ref(r);
  } else {
    n = copy(r);
    n-&gt;tmp = (cell_t *)3;
    n-&gt;n = 0;
  }
  r-&gt;tmp = mark_ptr(n, 3);
}

/* first sweep of modify_copy */
cell_t *_modify_copy1(cell_t *c, cell_t *r, bool up) {
  if(!is_closure(r)) return 0;

  r = clear_ptr(r, 3);
  int nd = nondep_n(r);

  /* is r unique (okay to replace)? */
  bool u = up &amp;&amp; !nd;

  if(r-&gt;tmp) {
    assert(is_marked(r-&gt;tmp, 3));
    /* already been replaced */
    return clear_ptr(r-&gt;tmp, 3);
  } else r-&gt;tmp = (cell_t *)3;
  if(c == r) _modify_new(r, u);
  traverse(r, {
      if(_modify_copy1(c, *p, u))
	_modify_new(r, u);
    }, ARGS | PTRS | ALT);
  return clear_ptr(r-&gt;tmp, 3);
}

cell_t *get_mod(cell_t *r) {
  if(!r) return 0;
  cell_t *a = r-&gt;tmp;
  if(is_marked(a, 2)) return clear_ptr(a, 3);
  else return 0;
}

/* second sweep of modify copy */
void _modify_copy2(cell_t *r) {

  /* r is modified in place */
  bool s = r == clear_ptr(r-&gt;tmp, 3);

  if(!is_closure(r)) return;
  /* alread been here */
  if(!is_marked(r-&gt;tmp, 1)) return;
  r-&gt;tmp = clear_ptr(r-&gt;tmp, 1);
  traverse(r, {
      cell_t *u = clear_ptr(*p, 3);
      cell_t *t = get_mod(u);
      if(t) {
	if(!(s &amp;&amp; t == u)) {
	  *p = ref(t);
	  if(s) drop(u);
	}
	_modify_copy2(t);
      } else if(!s) ref(u);
      if((!s || t != u) &amp;&amp; is_weak(r, *p)) {
	--(*p)-&gt;n;
      }
    }, ARGS | PTRS | ALT);
}</code></pre>
<p><code>modify_copy</code> is complex, but essentially, it makes a <a href="http://en.wikipedia.org/wiki/Object_copy#Lazy_copy">lazy copy</a> using the <code>tmp</code> fields in <code>cell_t</code>. <code>_modify_copy1</code> performs the first sweep, where copied closures are allocated as needed and stored in <code>tmp</code>, and <code>_modify_copy2</code> performs the second sweep, where references are updated in the copied graph to point to the new closures.</p>
<p>As you can see, quotes are very powerful, although the implementation is somewhat complex. The compiler can eliminate any overhead from using quotes in most cases.</p>
<p>In the next article, I will cover how alternatives work in the PoprC runtime.</p>]]></description>
    <pubDate>Sun, 10 Nov 2013 00:00:00 UT</pubDate>
    <guid>https://www.hackerfoo.com/posts/poprc-runtime-operation-part3.html</guid>
    <dc:creator>Dustin DeWeese</dc:creator>
</item>
<item>
    <title>PoprC Runtime Operation Part 2: Memory Management</title>
    <link>https://www.hackerfoo.com/posts/poprc-runtime-operation-part2.html</link>
    <description><![CDATA[<p>Memory management in the PoprC runtime is done using a custom allocator, based on a ring of cells. It’s fairly simple, but it works, and I’m not yet to the point where it needs to be optimized. Memory allocation must be handled carefully, because I want PoprC to be able to produce code suitable for embedded devices, which have very little memory, and need real-time guarantees.</p>
<p>The runtime’s garbage collection is based on reference counting to minimize memory usage, to avoid unpredictable pauses, and also because it’s simple. In addition, the reference count can be used to determine when it is okay to modify a closure, rather than making a modified copy. This is an effective optimization because most closures only have a single reference.</p>
<!--more-->
<p>At startup, all cells are added to a free ring by <code>cells_init()</code>.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true"></a><span class="dt">void</span> cells_init() {</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true"></a>  <span class="dt">int</span> i;</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true"></a>  <span class="dt">const</span> <span class="dt">unsigned</span> <span class="dt">int</span> n = LENGTH(cells)-<span class="dv">1</span>;</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true"></a>  <span class="co">// zero the cells</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true"></a>  memset(&amp;cells, <span class="dv">0</span>, <span class="kw">sizeof</span>(cells));</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true"></a>  memset(&amp;alt_live, <span class="dv">0</span>, <span class="kw">sizeof</span>(alt_live));</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true"></a></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true"></a>  <span class="co">// set up doubly-linked pointer ring</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true"></a>  <span class="cf">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true"></a>    cells[i].prev = &amp;cells[i-<span class="dv">1</span>];</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true"></a>    cells[i].next = &amp;cells[i+<span class="dv">1</span>];</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true"></a>  }</span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true"></a>  cells[<span class="dv">0</span>].prev = &amp;cells[n-<span class="dv">1</span>];</span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true"></a>  cells[n-<span class="dv">1</span>].next = &amp;cells[<span class="dv">0</span>];</span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true"></a></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true"></a>  cells_ptr = &amp;cells[<span class="dv">0</span>];</span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true"></a>  alt_cnt = <span class="dv">0</span>;</span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true"></a>}</span></code></pre></div>
<p><code>cells_init</code> is fairly straightforward; the cells are zeroed, each cell is linked to its neighbor (<code>n-1</code> and <code>n+1</code> modulo the number of cells), and <code>cells_ptr</code>, the point from with cells are added and removed, is set to point to <code>cells[0]</code>. <code>alt_cnt</code> counts the number of alternatives (explained later) allocated.</p>
<p><code>cells_next()</code> is used to obtain a point in the ring from which to allocate. It simply returns <code>cells_ptr</code> and advances <code>cells_ptr</code> to its <code>next</code> pointer.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true"></a>cell_t *cells_next() {</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true"></a>  cell_t *p = cells_ptr;</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true"></a>  assert(is_cell(p) &amp;&amp;</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true"></a>         !is_closure(p) &amp;&amp;</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true"></a>         is_cell(cells_ptr-&gt;next));</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true"></a>  cells_ptr = cells_ptr-&gt;next;</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true"></a>  <span class="cf">return</span> p;</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true"></a>}</span></code></pre></div>
<p><code>cell_alloc(c)</code> removes the <code>cell_t</code> pointer <code>c</code> from the ring. It also keeps track of allocation metrics.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true"></a><span class="dt">void</span> cell_alloc(cell_t *c) {</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true"></a>  assert(is_cell(c) &amp;&amp; !is_closure(c));</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true"></a>  cell_t *prev = c-&gt;prev;</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true"></a>  assert(is_cell(prev) &amp;&amp; !is_closure(prev));</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true"></a>  cell_t *next = c-&gt;next;</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true"></a>  assert(is_cell(next) &amp;&amp; !is_closure(next));</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true"></a>  <span class="cf">if</span>(cells_ptr == c) cells_next();</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true"></a>  prev-&gt;next = next;</span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true"></a>  next-&gt;prev = prev;</span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true"></a>  measure.alloc_cnt++;</span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true"></a>  <span class="cf">if</span>(++measure.current_alloc_cnt &gt; measure.max_alloc_cnt)</span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true"></a>    measure.max_alloc_cnt = measure.current_alloc_cnt;</span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true"></a>}</span></code></pre></div>
<p>Allocation from the free ring is handled by <code>closure_alloc(args)</code>, where args is the number of arguments required by the closure.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true"></a>cell_t *closure_alloc(<span class="dt">int</span> args) {</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true"></a>  cell_t *c = closure_alloc_cells(calculate_cells(args));</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true"></a>  c-&gt;size = args;</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true"></a>  <span class="cf">return</span> c;</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true"></a>}</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true"></a></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true"></a>cell_t *closure_alloc_cells(<span class="dt">int</span> size) {</span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true"></a>  cell_t *ptr = cells_next(), *c = ptr;</span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true"></a>  cell_t *mark = ptr;</span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true"></a>  <span class="dt">int</span> cnt = <span class="dv">0</span>;</span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true"></a>  (<span class="dt">void</span>)mark;</span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true"></a></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true"></a>  <span class="co">// search for contiguous chunk</span></span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true"></a>  <span class="cf">while</span>(cnt &lt; size) {</span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true"></a>    <span class="cf">if</span>(is_cell(ptr) &amp;&amp; !is_closure(ptr)) {</span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true"></a>      cnt++;</span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true"></a>      ptr++;</span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true"></a>    } <span class="cf">else</span> {</span>
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true"></a>      cnt = <span class="dv">0</span>;</span>
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true"></a>      c = ptr = cells_next();</span>
<span id="cb4-21"><a href="#cb4-21" aria-hidden="true"></a>      assert(c != mark);</span>
<span id="cb4-22"><a href="#cb4-22" aria-hidden="true"></a>    }</span>
<span id="cb4-23"><a href="#cb4-23" aria-hidden="true"></a>  }</span>
<span id="cb4-24"><a href="#cb4-24" aria-hidden="true"></a></span>
<span id="cb4-25"><a href="#cb4-25" aria-hidden="true"></a>  <span class="co">// remove the found chunk</span></span>
<span id="cb4-26"><a href="#cb4-26" aria-hidden="true"></a>  <span class="dt">int</span> i;</span>
<span id="cb4-27"><a href="#cb4-27" aria-hidden="true"></a>  <span class="cf">for</span>(i = <span class="dv">0</span>; i &lt; size; i++) {</span>
<span id="cb4-28"><a href="#cb4-28" aria-hidden="true"></a>    cell_alloc(&amp;c[i]);</span>
<span id="cb4-29"><a href="#cb4-29" aria-hidden="true"></a>  }</span>
<span id="cb4-30"><a href="#cb4-30" aria-hidden="true"></a></span>
<span id="cb4-31"><a href="#cb4-31" aria-hidden="true"></a>  memset(c, <span class="dv">0</span>, <span class="kw">sizeof</span>(cell_t)*size);</span>
<span id="cb4-32"><a href="#cb4-32" aria-hidden="true"></a>  <span class="cf">return</span> c;</span>
<span id="cb4-33"><a href="#cb4-33" aria-hidden="true"></a>}</span></code></pre></div>
<p><code>closure_alloc</code> uses <code>calculate_cells</code> to determine the number of cells required, and calls <code>closure_alloc_cells(size)</code>, where size is the number of cells. This function looks for a contiguous chunk of cells that is large enough to fit the new closure. It starts from the pointer returned from <code>cells_next()</code>, and then looks to see if there are enough unallocated cells after it. If it fails, it pulls the next pointer from cells_next(). <code>mark</code> is used to avoid an infinite loop if no chunk that is large enough exists.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true"></a>cell_t *func(reduce_t *f, <span class="dt">unsigned</span> <span class="dt">int</span> in, <span class="dt">unsigned</span> <span class="dt">int</span> out) {</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true"></a>  assert(out &gt; <span class="dv">0</span>);</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true"></a>  <span class="dt">unsigned</span> <span class="dt">int</span> args = in + out - <span class="dv">1</span>;</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true"></a>  cell_t *c = closure_alloc(args);</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true"></a>  c-&gt;out = out - <span class="dv">1</span>;</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true"></a>  c-&gt;func = f;</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true"></a>  <span class="cf">if</span>(args) c-&gt;arg[<span class="dv">0</span>] = (cell_t *)(<span class="dt">intptr_t</span>)(args - <span class="dv">1</span>);</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true"></a>  closure_set_ready(c, !args &amp;&amp; f != func_placeholder);</span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true"></a>  <span class="cf">return</span> c;</span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true"></a>}</span></code></pre></div>
<p>After allocation using <code>closure_alloc(n)</code>, the new cell is filled with zeroes, except <code>c-&gt;size == n</code>. <code>func(f, in, out)</code> wraps <code>closure_alloc</code> to provide a simple way to make incomplete (with missing arguments) closures. <code>f</code> is a reduction function (<code>reduce_t</code>), and <code>in</code> and <code>out</code> are the number of in and out arguments, respectively. <code>c-&gt;arg[0]</code> is set to the offset of the first argument (closures fill right to left.) The closure is marked as incomplete by setting the low bit of c-&gt;func unless the function requires no arguments or the closure is a placeholder.</p>
<p>Then the <code>arg</code> function can be used to load the arguments from right to left.</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true"></a><span class="co">/* arg is destructive to *cp */</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true"></a><span class="dt">void</span> arg(cell_t **cp, cell_t *a) {</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true"></a>  cell_t *c = *cp;</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true"></a>  assert(is_closure(c) &amp;&amp; is_closure(a));</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true"></a>  assert(!closure_is_ready(c));</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true"></a>  <span class="dt">int</span> i = closure_next_child(c);</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true"></a>  <span class="co">// *** shift args if placeholder</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true"></a>  <span class="cf">if</span>(is_placeholder(c) &amp;&amp;</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true"></a>     (closure_in(c) == <span class="dv">0</span> ||</span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true"></a>      closure_is_ready(c-&gt;arg[<span class="dv">0</span>]))) {</span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true"></a>    c = expand_inplace(c, <span class="dv">1</span>);</span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true"></a>    c-&gt;arg[<span class="dv">0</span>] = a;</span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true"></a>  } <span class="cf">else</span> <span class="cf">if</span>(!is_data(c-&gt;arg[i])) {</span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true"></a>    c-&gt;arg[<span class="dv">0</span>] = (cell_t *)(<span class="dt">intptr_t</span>)</span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true"></a>	  (i - (closure_is_ready(a) ? <span class="dv">1</span> : <span class="dv">0</span>));</span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true"></a>    c-&gt;arg[i] = a;</span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true"></a>    <span class="cf">if</span>(i == <span class="dv">0</span> &amp;&amp; !is_placeholder(c))</span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true"></a>	  closure_set_ready(c, closure_is_ready(a));</span>
<span id="cb6-19"><a href="#cb6-19" aria-hidden="true"></a>  } <span class="cf">else</span> {</span>
<span id="cb6-20"><a href="#cb6-20" aria-hidden="true"></a>    arg(&amp;c-&gt;arg[i], a);</span>
<span id="cb6-21"><a href="#cb6-21" aria-hidden="true"></a>    <span class="cf">if</span>(!is_placeholder(c) &amp;&amp;</span>
<span id="cb6-22"><a href="#cb6-22" aria-hidden="true"></a>       closure_is_ready(c-&gt;arg[i])) {</span>
<span id="cb6-23"><a href="#cb6-23" aria-hidden="true"></a>      <span class="cf">if</span>(i == <span class="dv">0</span>) closure_set_ready(c, true);</span>
<span id="cb6-24"><a href="#cb6-24" aria-hidden="true"></a>      <span class="cf">else</span> --*(<span class="dt">intptr_t</span> *)&amp;c-&gt;arg[<span class="dv">0</span>]; <span class="co">// decrement offset</span></span>
<span id="cb6-25"><a href="#cb6-25" aria-hidden="true"></a>    }</span>
<span id="cb6-26"><a href="#cb6-26" aria-hidden="true"></a>  }</span>
<span id="cb6-27"><a href="#cb6-27" aria-hidden="true"></a>  *cp = c;</span>
<span id="cb6-28"><a href="#cb6-28" aria-hidden="true"></a>}</span></code></pre></div>
<p><code>arg(&amp;c, a)</code> is pretty complex because it needs to handle placeholders. It works its way down the left side of the graph, looking for the innermost function lacking an argument, and then inserts <code>a</code> into that closure. Intuitively, it simply concatenates the argument <code>a</code> to <code>c</code>. Note that <code>c</code> is passed as a reference. This is because <code>c</code> could be moved to accommodate an expanding placeholder.</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true"></a>cell_t *ref(cell_t *c) {</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true"></a>  <span class="cf">return</span>(refn(c, <span class="dv">1</span>));</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true"></a>}</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true"></a></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true"></a>cell_t *refn(cell_t *c, <span class="dt">unsigned</span> <span class="dt">int</span> n) {</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true"></a>  c = clear_ptr(c, <span class="dv">3</span>);</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true"></a>  <span class="cf">if</span>(c) {</span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true"></a>    assert(is_closure(c));</span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true"></a>    c-&gt;n += n;</span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true"></a>  }</span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true"></a>  <span class="cf">return</span> c;</span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true"></a>}</span></code></pre></div>
<p>References are made by incrementing <code>c-&gt;n</code>. The number of references are <code>c-&gt;n + 1</code>, because the reference count will never reach zero; it will be immediately freed. This means <code>!c-&gt;n</code> indicates that a closure is only referenced once, and can be modified in place. <code>clear_ptr(ptr, bits)</code> clears marker bits in <code>ptr</code> (used by other functions).</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true"></a><span class="dt">void</span> drop(cell_t *c) {</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true"></a>  <span class="cf">if</span>(!is_cell(c) || !is_closure(c)) <span class="cf">return</span>;</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true"></a>  <span class="cf">if</span>(!c-&gt;n) {</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true"></a>    cell_t *p;</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true"></a>    traverse(c, {</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true"></a>	cell_t *x = clear_ptr(*p, <span class="dv">3</span>);</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true"></a>	<span class="co">/* !is_marked condition needed */</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true"></a>	<span class="co">/* during _modify_copy2 */</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true"></a>	<span class="cf">if</span>(!is_marked(*p, <span class="dv">2</span>)) {</span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true"></a>	  drop(x);</span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true"></a>	}</span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true"></a>      }, ALT | ARGS_IN | PTRS);</span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true"></a>    <span class="cf">if</span>(is_dep(c) &amp;&amp; !is_reduced(p = c-&gt;arg[<span class="dv">0</span>]) &amp;&amp; is_closure(p)) {</span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true"></a>      <span class="co">/* mark dep arg as gone */</span></span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true"></a>      <span class="dt">int</span> n = closure_args(p);</span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true"></a>      <span class="cf">while</span>(n--) {</span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true"></a>	<span class="cf">if</span>(p-&gt;arg[n] == c) {</span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true"></a>	  p-&gt;arg[n] = <span class="dv">0</span>;</span>
<span id="cb8-19"><a href="#cb8-19" aria-hidden="true"></a>	  <span class="cf">break</span>;</span>
<span id="cb8-20"><a href="#cb8-20" aria-hidden="true"></a>	}</span>
<span id="cb8-21"><a href="#cb8-21" aria-hidden="true"></a>      }</span>
<span id="cb8-22"><a href="#cb8-22" aria-hidden="true"></a>    }</span>
<span id="cb8-23"><a href="#cb8-23" aria-hidden="true"></a>    <span class="cf">if</span>(is_reduced(c)) alt_set_drop(c-&gt;alt_set);</span>
<span id="cb8-24"><a href="#cb8-24" aria-hidden="true"></a>    <span class="cf">if</span>(c-&gt;func == func_id) alt_set_drop((alt_set_t)c-&gt;arg[<span class="dv">1</span>]);</span>
<span id="cb8-25"><a href="#cb8-25" aria-hidden="true"></a>    closure_free(c);</span>
<span id="cb8-26"><a href="#cb8-26" aria-hidden="true"></a>  } <span class="cf">else</span> {</span>
<span id="cb8-27"><a href="#cb8-27" aria-hidden="true"></a>    --c-&gt;n;</span>
<span id="cb8-28"><a href="#cb8-28" aria-hidden="true"></a>  }</span>
<span id="cb8-29"><a href="#cb8-29" aria-hidden="true"></a>}</span></code></pre></div>
<p>Dropping (or removing a reference) is accomplished using the <code>drop(c)</code> function, where <code>c</code> is the cell to drop. It drops <code>c</code>. If <code>c-&gt;n == 0</code>, it recursively drops all the arguments of an unevaluated function, or the items in a list, as well as the alternative pointer.</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true"></a><span class="pp">#define traverse(r, action, flags) 			\</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true"></a><span class="pp">  do {							\</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true"></a><span class="pp">    cell_t **p;						\</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true"></a><span class="pp">    if(is_reduced(r)) {					\</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true"></a><span class="pp">      if(((flags) &amp; PTRS) &amp;&amp;				\</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true"></a><span class="pp">		is_list(r)) {				\</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true"></a><span class="pp">	int i, n = list_size(r);			\</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true"></a><span class="pp">	for(i = 0; i &lt; n; ++i) {			\</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true"></a><span class="pp">	  p = (r)-&gt;ptr + i;				\</span></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true"></a><span class="pp">	  action					\</span></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true"></a><span class="pp">	}						\</span></span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true"></a><span class="pp">      }							\</span></span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true"></a><span class="pp">    } else if((flags) &amp; (ARGS | ARGS_IN)) {		\</span></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true"></a><span class="pp">      int i, n = ((flags) &amp; ARGS_IN) ?			\</span></span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true"></a><span class="pp">	closure_in(r) :					\</span></span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true"></a><span class="pp">	closure_args(r);				\</span></span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true"></a><span class="pp">      for(i = closure_next_child(r); i &lt; n; ++i) {	\</span></span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true"></a><span class="pp">	p = (r)-&gt;arg + i;				\</span></span>
<span id="cb9-19"><a href="#cb9-19" aria-hidden="true"></a><span class="pp">	if(*p) {action}					\</span></span>
<span id="cb9-20"><a href="#cb9-20" aria-hidden="true"></a><span class="pp">      }							\</span></span>
<span id="cb9-21"><a href="#cb9-21" aria-hidden="true"></a><span class="pp">    }							\</span></span>
<span id="cb9-22"><a href="#cb9-22" aria-hidden="true"></a><span class="pp">    if((flags) &amp; ALT) {					\</span></span>
<span id="cb9-23"><a href="#cb9-23" aria-hidden="true"></a><span class="pp">      p = &amp;(r)-&gt;alt;					\</span></span>
<span id="cb9-24"><a href="#cb9-24" aria-hidden="true"></a><span class="pp">      action						\</span></span>
<span id="cb9-25"><a href="#cb9-25" aria-hidden="true"></a><span class="pp">    }							\</span></span>
<span id="cb9-26"><a href="#cb9-26" aria-hidden="true"></a><span class="pp">  } while(0)</span></span></code></pre></div>
<p>The <code>traverse(r, action, flags)</code> macro traverses the cell <code>r</code> and applies <code>action</code> to the parts of <code>r</code> indicated by <code>flags</code>. This makes the <code>drop</code> function (and many others) less tedious.</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true"></a><span class="dt">void</span> closure_shrink(cell_t *c, <span class="dt">int</span> s) {</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true"></a>  <span class="cf">if</span>(!is_cell(c)) <span class="cf">return</span>;</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true"></a>  <span class="dt">int</span> i, size = closure_cells(c);</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true"></a>  <span class="cf">if</span>(size &gt; s) {</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true"></a>    assert(is_closure(c));</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true"></a>    <span class="cf">for</span>(i = s; i &lt; size; i++) {</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true"></a>      c[i].func = <span class="dv">0</span>;</span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true"></a>      c[i].prev = &amp;c[i-<span class="dv">1</span>];</span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true"></a>      c[i].next = &amp;c[i+<span class="dv">1</span>];</span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true"></a>    }</span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true"></a>    c[s].prev = cells_ptr-&gt;prev;</span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true"></a>    cells_ptr-&gt;prev-&gt;next = &amp;c[s];</span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true"></a>    c[size-<span class="dv">1</span>].next = cells_ptr;</span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true"></a>    cells_ptr-&gt;prev = &amp;c[size-<span class="dv">1</span>];</span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true"></a>    measure.current_alloc_cnt -= size - s;</span>
<span id="cb10-16"><a href="#cb10-16" aria-hidden="true"></a>  }</span>
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true"></a>}</span>
<span id="cb10-18"><a href="#cb10-18" aria-hidden="true"></a></span>
<span id="cb10-19"><a href="#cb10-19" aria-hidden="true"></a><span class="dt">void</span> closure_free(cell_t *c) {</span>
<span id="cb10-20"><a href="#cb10-20" aria-hidden="true"></a>  closure_shrink(c, <span class="dv">0</span>);</span>
<span id="cb10-21"><a href="#cb10-21" aria-hidden="true"></a>}</span></code></pre></div>
<p><code>closure_shrink(c, s)</code> shrinks the closure <code>c</code> to <code>s</code> cells, adding the extra cells back to the free ring. <code>closure_free(c)</code> then, which deallocates <code>c</code> entirely, is trivially implemented with <code>closure_shrink(c, 0)</code>.</p>
<p>That covers the basics of the memory management functions of the PoprC runtime. The next article in this series will explain quotes (also called lists).</p>]]></description>
    <pubDate>Mon, 04 Nov 2013 00:00:00 UT</pubDate>
    <guid>https://www.hackerfoo.com/posts/poprc-runtime-operation-part2.html</guid>
    <dc:creator>Dustin DeWeese</dc:creator>
</item>
<item>
    <title>PoprC Runtime Operation Part 1: Cells and Closures</title>
    <link>https://www.hackerfoo.com/posts/poprc-runtime-operation-part1.html</link>
    <description><![CDATA[<p>Because Popr is a functional language, execution of a Popr expression can be thought of as a series of reductions to reach the final result. PoprC relies on functions in the runtime (<code>rt.c</code>) to handle the reduction of Popr expressions. It can reduce functions with static (known) arguments. If this were all PoprC could do, it would be an interpreter, and not a compiler. It can also reduce functions with variables as arguments, producing a trace which is converted into LLVM IR. This results in code with all static parts fully reduced, and only the dynamic (not known in advance) portions implemented by using calls to the runtime.</p>
<p>The runtime is also responsible for memory management. Unallocated memory is arrange as a free ring (a doubly-linked list with no head or tail) of cells. Each cell stores data required to implement a closure, which is a function and its arguments, but a cell also has more information required for memory management, alternatives, reduced values, alternatives, and a temporary pointer used during graph copying.</p>
<!--more-->
<p>Here is exactly what is stored in the cell type (<code>cell_t</code>):</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true"></a><span class="kw">typedef</span> <span class="dt">bool</span> (reduce_t)(cell_t **cell, type_rep_t type);</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true"></a><span class="kw">struct</span> __attribute__((packed)) cell {</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true"></a>  reduce_t *func;</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true"></a>  cell_t *alt;</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true"></a>  cell_t *tmp;</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true"></a>  <span class="dt">uint32_t</span> n;</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true"></a>  <span class="dt">uint16_t</span> size;</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true"></a>  <span class="kw">union</span> {</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true"></a>    <span class="dt">uint16_t</span> type;</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true"></a>    <span class="dt">uint16_t</span> out;</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true"></a>  };</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true"></a>  <span class="kw">union</span> {</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true"></a>    <span class="co">/* unevaluated */</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true"></a>    cell_t *arg[<span class="dv">3</span>];</span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true"></a>    <span class="co">/* reduced */</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true"></a>    <span class="kw">struct</span> __attribute__((packed)) {</span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true"></a>      alt_set_t alt_set;</span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true"></a>      <span class="kw">union</span> {</span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true"></a>        <span class="dt">intptr_t</span> val[<span class="dv">2</span>]; <span class="co">/* value */</span></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true"></a>        cell_t *ptr[<span class="dv">2</span>];  <span class="co">/* list */</span></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true"></a>      };</span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true"></a>    };</span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true"></a>    <span class="co">/* unallocated */</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true"></a>    <span class="kw">struct</span> __attribute__((packed)) {</span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true"></a>      cell_t *prev, *next;</span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true"></a>    };</span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true"></a>  };</span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true"></a>} __attribute__((aligned(<span class="dv">4</span>)));</span></code></pre></div>
<p>In the description of PoprC, the term <em>closure</em> is used to refer to a function which may be missing arguments, which can be reduced. Closures are stored in one or more cells.</p>
<p><code>cell_t</code> is complicated, because closures have a life cycle with three stages, and to minimize memory usage, some parts of cells are reused to store different information in some stages.</p>
<p>The first stage is the unallocated cell; it only requires a previous (<code>prev</code>) and next (<code>next</code>) pointer, and a way to indicate that it is unallocated is useful to prevent errors, which is done by setting <code>func</code> to <code>0</code>. When the runtime is initialized, it builds a ring of unallocated cells in a statically allocated array (<code>cells</code>). This could later be extended to allow dynamically growing and shrinking the memory pool, or if the code is embedded, all heap memory could be consumed by the cell ring at startup.</p>
<p>The next two stages share some common fields. The <code>func</code> field stores a pointer to the function that the closure will execute on reduction. <code>alt</code> stores the next alternative. <code>tmp</code> is a temporary pointer used to implement graph copying. <code>n</code> is a reference count. <code>size</code> indicates the size of the <code>arg</code> array, and consequently is one greater than the size of the <code>val</code> and <code>ptr</code> arrays.</p>
<p>The second stage is the unevaluated closure. In this stage, in addition to the common fields, the <code>out</code> field indicates how many of the arguments are outputs instead of inputs, and the <code>arg</code> array stores pointers to other cells, which are the arguments. In this stage, during building (when the graph is being constructed, before reduction), some arguments might be missing. Arguments are filled in from the left (<code>c-&gt;arg[c-&gt;size - 1]</code>), with the position of the next argument stored in <code>c-&gt;arg[0]</code>. Bit 0 of <code>func</code> is set to indicate that the closure is not ready.</p>
<p>The third stage is the reduced closure. In this stage, the <code>type</code> field indicates a type (and also has some other bits that store metadata), <code>alt_set</code> is a bit field that controls the interaction of alternatives (which I will describe in another post.) The reduced cell could be either a vector of unboxed values stored in the <code>val</code> array, or a list, which stores pointers to its members in the <code>ptr</code> array.</p>
<p>With all that out of the way, you might wonder what happens if I want a list of more than two items. Multiple contiguous cells can be used together to extend the <code>arg</code>, <code>val</code>, and <code>ptr</code> arrays.</p>
<p>So now you should understand <code>cell_t</code> and closures, upon which the runtime is built. In the next article in this series, I’ll explain the allocator and memory management functions in the runtime.</p>]]></description>
    <pubDate>Fri, 01 Nov 2013 00:00:00 UT</pubDate>
    <guid>https://www.hackerfoo.com/posts/poprc-runtime-operation-part1.html</guid>
    <dc:creator>Dustin DeWeese</dc:creator>
</item>
<item>
    <title>PoprC Code Explanation: Introduction and Overview</title>
    <link>https://www.hackerfoo.com/posts/poprc-code-intro.html</link>
    <description><![CDATA[<p>I’ve been working on a <a href="https://github.com/HackerFoo/poprc">compiler called PoprC</a> for my programming language, Popr. It has been about a year since I started, so I want to explain how the compiler currently works to help clarify my ideas. It might also be interesting to others, and I hope to get some feedback.</p>
<p>The compiler consists of four main components: runtime (<code>rt.c</code>), evaluation (<code>eval.c</code>), predefined primitives (<code>primitive.c</code>), and LLVM code generation (<code>llvm.cpp</code>). The runtime provides code to be linked into compiled Popr code, to handle memory management and graph reduction. eval.c has code for parsing Popr expressions and displaying results, as well as functions to generate .dot files (graphing working memory) for debugging. It contains any code related to evaluation that is not required in the runtime. The predefined primitives in primitives.c form the basic building blocks for Popr programs. <code>llvm.cpp</code> handles tracing evaluation to generate LLVM IR that is currently JIT compiled.</p>
<!--more-->
<p>The compiler is based on <a href="http://en.wikipedia.org/wiki/Abstract_interpretation">abstract interpretation</a>; it is an interpreter that can also handle <em>variables</em> and <em>placeholders</em>. Variables represent a partially unknown value, such as an argument to a function. Placeholders are partially unknown functions. Functions continue to operate in the presence of variables and placeholders; if the result can’t be known given the arguments, variables and placeholders are used to denote the unknown portions in the resulting value. This allows the interpreter to partially evaluate functions. A tracing function can be hooked into the interpreter to convert operations on variables and placeholders into code implementing the partially applied function. The ability of the interpreter to execute alternatives allows all branches to be explored while generating code for full flow analysis.</p>
<p>Some examples might help illustrate how it works (you can try them <a href="http://www.hackerfoo.com/peg">online</a>):</p>
<pre><span class="input">: +</span>
?_2 <- arg(0)
?_3 <- arg(1)
?i3 <- type
?i2 <- type
?i1 <- ?3 ?2 add
 [ ?i1 ]
</pre>
<p>A <code>+</code> is entered at the prompt (user input is shown after the prompt ‘<code>:</code>’). First the interpreter produces arguments until the expression is complete. It creates <code>?_2</code> and <code>?_3</code> as the first and second arguments, respectively. The character after the <code>?</code> denotes the type, an underscore (<code>_</code>) represents an unknown type, and <code>i</code> represents an integer. The <code>+</code> function restricts its arguments to integer type, producing the next two lines. Finally <code>+</code> is applied to its arguments, producing the <code>add</code> line, and the result is the variable <code>?i1</code>.</p>
<pre><span class="input">: popr swap drop</span>
?_6 <- arg(0)
?f7 <- ?l6 head
?8 <- f[?7]
 [ ?_8 ]
</pre>
<p>A more complex example is the <code>head</code> function in <code>lib.peg</code>. It takes a list argument (<code>?l6</code>), extracts the function within (<code>?f7</code>), and applies it, producing a value of unknown type (<code>?_8</code>).</p>
<p>To understand more in depth how PoprC works, you will need to understand the details of the interpreter, which will be the topic of my next post.</p>]]></description>
    <pubDate>Wed, 30 Oct 2013 00:00:00 UT</pubDate>
    <guid>https://www.hackerfoo.com/posts/poprc-code-intro.html</guid>
    <dc:creator>Dustin DeWeese</dc:creator>
</item>
<item>
    <title>A Quick Introduction to the Popr Programming Language</title>
    <link>https://www.hackerfoo.com/posts/popr-introduction.html</link>
    <description><![CDATA[<p>Popr is a pure functional lazy post-fix concatenative programming language. I will briefly explain some of the features of Popr through some examples. You can try these examples <a href="http://www.hackerfoo.com/peg">online</a>.</p>
<pre><code>1 2 +   --&gt;   [ 3 ]</code></pre>
<p><code>+</code> is a function that takes two integers and returns one. There are several similar functions, with the same meaning as in C: <code>-</code>, <code>*</code>, <code>&lt;</code>, <code>&lt;=</code>, <code>==</code>, <code>&gt;</code>, <code>&gt;=</code>. Booleans are currently represented as integers, non-zero for true, zero for false.</p>
<!--more-->
<pre><code>1 2 | 3 +         --&gt;   [ { 4 | 5 } ]
2 5 | dup 2 - !   --&gt;   [ 5 ]</code></pre>
<p><code>|</code> takes two values and creates two <em>alternatives</em>, where each value is returned. <code>!</code> takes two values; if the second argument is 0, the it <em>fails</em>, otherwise the first value is returned. Alternatives and failure provide a more general branching mechanism than if/else, similar to speculative execution, or Prolog inference.</p>
<pre><code>[ 1 2 + 3 4 + ] popr   --&gt;   [ [ 1 2 + ] 7 ]
1 [ 2 + ] pushl        --&gt;   [ [ 1 2 + ] ]
1 [ 2 + ] pushl popr   --&gt;   [ [] 3 ]</code></pre>
<p><code>[ ... ]</code> denotes a quotation, which can be used for constructing functions or for aggregating values. <code>popr</code> pops the rightmost element from a quotation and forces evaluation. <code>pushl</code> takes its first argument and pushes it onto the left of the quotation. The two primitives can be combined to evaluate a quotation. Notice that Popr is lazy, and only reduces functions in quotations when required.</p>
<pre><code>1 2 | dup   --&gt;   { [ 1 1 ] | [ 2 2 ] }
1 2 swap    --&gt;   [ 2 1 ]
1 2 drop    --&gt;   [ 1 ]
1 2 | cut   --&gt;   [ 1 ]</code></pre>
<p>Some other primitives. <code>dup</code> duplicates a value; notice how it respects the constraints introduced by alternatives. <code>swap</code> swaps two values. <code>drop</code> drops a value. <code>cut</code> prunes alternatives after the first successful one. This should only be used to hint that only one unique alternative would succeed, rather than to prune otherwise successful execution paths. The type checker might eventually check this.</p>]]></description>
    <pubDate>Tue, 29 Oct 2013 00:00:00 UT</pubDate>
    <guid>https://www.hackerfoo.com/posts/popr-introduction.html</guid>
    <dc:creator>Dustin DeWeese</dc:creator>
</item>

    </channel>
</rss>
