inweb-bootstrap/docs/foundation-module/2-llas.html
2022-04-05 12:15:52 +01:00

310 lines
63 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Linked Lists and Stacks</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-assets/Octagram.png" width=72 height=72">
</a></h1>
<ul><li><a href="../inweb/index.html">inweb</a></li>
</ul><h2>Foundation Module</h2><ul>
<li><a href="index.html"><span class="selectedlink">foundation</span></a></li>
<li><a href="../foundation-test/index.html">foundation-test</a></li>
</ul><h2>Example Webs</h2><ul>
<li><a href="../goldbach/index.html">goldbach</a></li>
<li><a href="../twinprimes/twinprimes.html">twinprimes</a></li>
<li><a href="../eastertide/index.html">eastertide</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=18> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="../../../inform/docs/index.html">inform</a></li>
<li><a href="../../../intest/docs/index.html">intest</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Linked Lists and Stacks' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="index.html">foundation</a></li><li><a href="index.html#2">Chapter 2: Memory, Streams and Collections</a></li><li><b>Linked Lists and Stacks</b></li></ul></div>
<p class="purpose">A simple implementation for single-linked lists of objects allocated by Foundation's memory manager, and for last-in-first-out stacks of same.</p>
<ul class="toc"><li><a href="2-llas.html#SP1">&#167;1. Implementation</a></li><li><a href="2-llas.html#SP7">&#167;7. A function call API</a></li><li><a href="2-llas.html#SP8">&#167;8. A macro-ized API</a></li><li><a href="2-llas.html#SP10">&#167;10. LIFO stacks</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Implementation. </b>Basically, there's a head structure, which points to a chain of body structures,
each linking to the next. But to reduce memory manager overhead, we're going to store
the first few body structures inside the head structure: that way, for a list of just
a few items, only one call to the memory manager is needed.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">NO_LL_EARLY_ITEMS</span><span class="plain-syntax"> </span><span class="constant-syntax">32</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> *</span><span class="identifier-syntax">first_list_item</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> *</span><span class="identifier-syntax">last_list_item</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">linked_list_length</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">early_items_used</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> </span><span class="identifier-syntax">early_items</span><span class="plain-syntax">[</span><span class="constant-syntax">NO_LL_EARLY_ITEMS</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="constant-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">linked_list</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">item_contents</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_list_item</span><span class="plain-syntax">;</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure linked_list is private to this section.</li><li>The structure linked_list_item is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="function-syntax">LinkedLists::new</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">LinkedLists::new</span></span>:<br/><a href="2-llas.html#SP8">&#167;8</a>, <a href="2-llas.html#SP11">&#167;11</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ll</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-llas.html#SP2" class="function-link"><span class="function-syntax">LinkedLists::empty</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ll</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">ll</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LinkedLists::empty</span><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ll</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ll</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">linked_list_length</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ll</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">early_items_used</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ll</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_list_item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ll</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_list_item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>The following runs in constant time, i.e., performs no loops. In general we
want speed rather than memory efficiency.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LinkedLists::add</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">LinkedLists::add</span></span>:<br/><a href="2-llas.html#SP6">&#167;6</a>, <a href="2-llas.html#SP8">&#167;8</a>, <a href="2-llas.html#SP11">&#167;11</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">to_end</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"null list"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> *</span><span class="identifier-syntax">item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">early_items_used</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">NO_LL_EARLY_ITEMS</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">item</span><span class="plain-syntax"> = &amp;(</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">early_items</span><span class="plain-syntax">[</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">early_items_used</span><span class="plain-syntax">++]);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">item</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">item_contents</span><span class="plain-syntax"> = </span><span class="identifier-syntax">P</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">to_end</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">item</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_list_item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_list_item</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_list_item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">item</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_list_item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">item</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_list_item</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_list_item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">item</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_list_item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">item</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">item</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_list_item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_list_item</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">first_list_item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">item</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_list_item</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_list_item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">item</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">linked_list_length</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>Because of the direction of the links, only removing from the front is quick:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="function-syntax">LinkedLists::remove_from_front</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">LinkedLists::remove_from_front</span></span>:<br/><a href="2-llas.html#SP5">&#167;5</a>, <a href="2-llas.html#SP11">&#167;11</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"null list"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> *</span><span class="identifier-syntax">front</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">first_list_item</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">front</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"empty list can't have item 0 removed"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_list_item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">front</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_list_item</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">first_list_item</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_list_item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">linked_list_length</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">front</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">item_contents</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>It's rather slower to delete from a known position in the middle:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="function-syntax">LinkedLists::delete</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">LinkedLists::delete</span></span>:<br/><a href="2-llas.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax">, </span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"null list"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">N</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">N</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">linked_list_length</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"index not valid"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">N</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-llas.html#SP4" class="function-link"><span class="function-syntax">LinkedLists::remove_from_front</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> *</span><span class="identifier-syntax">item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_list_item</span><span class="plain-syntax">; </span><span class="identifier-syntax">item</span><span class="plain-syntax">; </span><span class="identifier-syntax">item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">item</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_list_item</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">N</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_list_item</span><span class="plain-syntax"> == </span><span class="identifier-syntax">item</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_list_item</span><span class="plain-syntax">) </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_list_item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">item</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">contents_deleted</span><span class="plain-syntax"> = </span><span class="identifier-syntax">item</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_list_item</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">item_contents</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">item</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_list_item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">item</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_list_item</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_list_item</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">linked_list_length</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">contents_deleted</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"index not found"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>And indeed to insert at a known position, where <span class="extract"><span class="extract-syntax">N</span></span> being 0 means the front
of the list, <span class="extract"><span class="extract-syntax">N</span></span> being 1 means "after the first item", and so on.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LinkedLists::insert</span><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">N</span><span class="plain-syntax"> &lt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><a href="2-llas.html#SP3" class="function-link"><span class="function-syntax">LinkedLists::add</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_list_item</span><span class="plain-syntax">; </span><span class="identifier-syntax">I</span><span class="plain-syntax">; </span><span class="identifier-syntax">I</span><span class="plain-syntax"> = </span><span class="identifier-syntax">I</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_list_item</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">N</span><span class="plain-syntax">-- == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">prev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">prev</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><a href="2-llas.html#SP3" class="function-link"><span class="function-syntax">LinkedLists::add</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> *</span><span class="identifier-syntax">item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">early_items_used</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">NO_LL_EARLY_ITEMS</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">item</span><span class="plain-syntax"> = &amp;(</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">early_items</span><span class="plain-syntax">[</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">early_items_used</span><span class="plain-syntax">++]);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">item</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">item_contents</span><span class="plain-syntax"> = </span><span class="identifier-syntax">P</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subs</span><span class="plain-syntax"> = </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_list_item</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_list_item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">item</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">item</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_list_item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">subs</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">linked_list_length</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. A function call API. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">LinkedLists::len</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">LinkedLists::len</span></span>:<br/><a href="2-llas.html#SP11">&#167;11</a><br/>Time - <a href="3-tm.html#SP7">&#167;7</a><br/>Epub Ebooks - <a href="5-ee.html#SP7_3">&#167;7.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">?(</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">linked_list_length</span><span class="plain-syntax">):0;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> *</span><span class="function-syntax">LinkedLists::first</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">LinkedLists::first</span></span>:<br/><a href="2-llas.html#SP8">&#167;8</a><br/>Version Numbers - <a href="7-vn.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">?(</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_list_item</span><span class="plain-syntax">):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="function-syntax">LinkedLists::entry</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">LinkedLists::entry</span></span>:<br/><a href="2-llas.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax">, </span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">N</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">L</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">N</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">linked_list_length</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_list_item</span><span class="plain-syntax">; </span><span class="identifier-syntax">I</span><span class="plain-syntax">; </span><span class="identifier-syntax">I</span><span class="plain-syntax"> = </span><span class="identifier-syntax">I</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_list_item</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">N</span><span class="plain-syntax">-- == </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">item_contents</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LinkedLists::set_entry</span><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax">, </span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">N</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">L</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">N</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">linked_list_length</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_list_item</span><span class="plain-syntax">; </span><span class="identifier-syntax">I</span><span class="plain-syntax">; </span><span class="identifier-syntax">I</span><span class="plain-syntax"> = </span><span class="identifier-syntax">I</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_list_item</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">N</span><span class="plain-syntax">-- == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">item_contents</span><span class="plain-syntax"> = </span><span class="identifier-syntax">P</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> *</span><span class="function-syntax">LinkedLists::last</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">LinkedLists::last</span></span>:<br/><a href="2-llas.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">?(</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_list_item</span><span class="plain-syntax">):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> *</span><span class="function-syntax">LinkedLists::next</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">LinkedLists::next</span></span>:<br/><a href="2-llas.html#SP8">&#167;8</a><br/>Version Numbers - <a href="7-vn.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="plain-syntax">?(</span><span class="identifier-syntax">I</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_list_item</span><span class="plain-syntax">):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="function-syntax">LinkedLists::content</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">LinkedLists::content</span></span>:<br/><a href="2-llas.html#SP8">&#167;8</a><br/>Version Numbers - <a href="7-vn.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="plain-syntax">?(</span><span class="identifier-syntax">I</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">item_contents</span><span class="plain-syntax">):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. A macro-ized API. </b>These intentionally hide the implementation. The difference between
<span class="extract"><span class="extract-syntax">FIRST_IN_LINKED_LIST</span></span> and <span class="extract"><span class="extract-syntax">FIRST_ITEM_IN_LINKED_LIST</span></span> is that one returns
the first structure in the list, and the other returns the first
<span class="extract"><span class="extract-syntax">linked_list_item</span></span> chunk in the list. From the latter you can make the
former using <span class="extract"><span class="extract-syntax">CONTENT_IN_ITEM</span></span>, but not vice versa. The same object
may be listed in many different lists, so if all you have is the object,
you don't know its place in the list.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> (</span><a href="2-llas.html#SP2" class="function-link"><span class="function-syntax">LinkedLists::new</span></a><span class="plain-syntax">())</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">FIRST_ITEM_IN_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> (</span><a href="2-llas.html#SP7" class="function-link"><span class="function-syntax">LinkedLists::first</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">))</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">ENTRY_IN_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">N</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">T</span><span class="plain-syntax"> *) (</span><a href="2-llas.html#SP7" class="function-link"><span class="function-syntax">LinkedLists::entry</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">N</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)))</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">DELETE_FROM_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">N</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">T</span><span class="plain-syntax"> *) (</span><a href="2-llas.html#SP5" class="function-link"><span class="function-syntax">LinkedLists::delete</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">N</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)))</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">LAST_ITEM_IN_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> (</span><a href="2-llas.html#SP7" class="function-link"><span class="function-syntax">LinkedLists::last</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">))</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">NEXT_ITEM_IN_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> (</span><a href="2-llas.html#SP7" class="function-link"><span class="function-syntax">LinkedLists::next</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">))</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">CONTENT_IN_ITEM</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">T</span><span class="plain-syntax"> *) (</span><a href="2-llas.html#SP7" class="function-link"><span class="function-syntax">LinkedLists::content</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)))</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="2-llas.html#SP3" class="function-link"><span class="function-syntax">LinkedLists::add</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, (</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *) (</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">)</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">FIRST_IN_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">T</span><span class="plain-syntax"> *) (</span><a href="2-llas.html#SP7" class="function-link"><span class="function-syntax">LinkedLists::content</span></a><span class="plain-syntax">(</span><a href="2-llas.html#SP7" class="function-link"><span class="function-syntax">LinkedLists::first</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">))))</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">LAST_IN_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">T</span><span class="plain-syntax"> *) (</span><a href="2-llas.html#SP7" class="function-link"><span class="function-syntax">LinkedLists::content</span></a><span class="plain-syntax">(</span><a href="2-llas.html#SP7" class="function-link"><span class="function-syntax">LinkedLists::last</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">))))</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. </b>The following macro requires slight care to use: the list <span class="extract"><span class="extract-syntax">L</span></span> needs to be
calculable without side-effects. There's no such worry over <span class="extract"><span class="extract-syntax">P</span></span> or <span class="extract"><span class="extract-syntax">T</span></span>, since
they're just identifier names: the loop variable and the type name respectively.
</p>
<p class="commentary">Note that the loop variable <span class="extract"><span class="extract-syntax">P</span></span> must already be defined. Inside the loop body,
a new variable will also then exist, <span class="extract"><span class="extract-syntax">P_item</span></span>, to refer to the item which
points to <span class="extract"><span class="extract-syntax">P</span></span>. This allows us to iterate despite the comments above.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">##</span><span class="identifier-syntax">_item</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FIRST_IN_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">), </span><span class="identifier-syntax">FIRST_ITEM_IN_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">##</span><span class="identifier-syntax">_item</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">##</span><span class="identifier-syntax">_item</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CONTENT_IN_ITEM</span><span class="plain-syntax">(</span><span class="identifier-syntax">NEXT_ITEM_IN_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">##</span><span class="identifier-syntax">_item</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">), </span><span class="identifier-syntax">T</span><span class="plain-syntax">), </span><span class="identifier-syntax">NEXT_ITEM_IN_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">##</span><span class="identifier-syntax">_item</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">)))</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. LIFO stacks. </b>The above gives us an almost free implementation of LIFO, last-in-first-out,
stacks, where we represent a stack as a linked list whose first entry is at
the front. To push an item, we add it at the front; to pull, we remove the
front iten.
</p>
<p class="commentary">We provide an abstract type name for these stacks, even though they're the
exact same structure. For reasons to do with the way <span class="extract"><span class="extract-syntax">typedef</span></span> works in C,
it is awkward to typedef the two names together, so we'll simply use the
preprocessor:
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">lifo_stack</span><span class="plain-syntax"> </span><span class="reserved-syntax">linked_list</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>Otherwise, it's macros all the way:
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">NEW_LIFO_STACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> (</span><a href="2-llas.html#SP2" class="function-link"><span class="function-syntax">LinkedLists::new</span></a><span class="plain-syntax">())</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">PUSH_TO_LIFO_STACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="2-llas.html#SP3" class="function-link"><span class="function-syntax">LinkedLists::add</span></a><span class="plain-syntax">((</span><span class="identifier-syntax">L</span><span class="plain-syntax">), (</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *) (</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">PULL_FROM_LIFO_STACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">T</span><span class="plain-syntax"> *) </span><a href="2-llas.html#SP4" class="function-link"><span class="function-syntax">LinkedLists::remove_from_front</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">))</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">POP_LIFO_STACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> (</span><a href="2-llas.html#SP4" class="function-link"><span class="function-syntax">LinkedLists::remove_from_front</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">))</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">TOP_OF_LIFO_STACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">FIRST_IN_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">LIFO_STACK_EMPTY</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> ((</span><a href="2-llas.html#SP7" class="function-link"><span class="function-syntax">LinkedLists::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">)?</span><span class="identifier-syntax">TRUE:FALSE</span><span class="plain-syntax">)</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">LOOP_DOWN_LIFO_STACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="2-mth.html">&#10094;</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresssection"><a href="2-dl.html">dl</a></li><li class="progresssection"><a href="2-mmr.html">mmr</a></li><li class="progresssection"><a href="2-fc.html">fc</a></li><li class="progresssection"><a href="2-lcl.html">lcl</a></li><li class="progresssection"><a href="2-str.html">str</a></li><li class="progresssection"><a href="2-wal.html">wal</a></li><li class="progresssection"><a href="2-mth.html">mth</a></li><li class="progresscurrent">llas</li><li class="progresssection"><a href="2-dct.html">dct</a></li><li class="progresssection"><a href="2-trs.html">trs</a></li><li class="progresschapter"><a href="3-em.html">3</a></li><li class="progresschapter"><a href="4-chr.html">4</a></li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresschapter"><a href="6-bf.html">6</a></li><li class="progresschapter"><a href="7-vn.html">7</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="2-dct.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>